fixup! Add display server.
This commit is contained in:
parent
bdd859c748
commit
a78704f7e6
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015, 2016, 2018, 2022 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2014, 2015, 2016, 2018, 2022, 2023 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -17,7 +17,6 @@
|
||||||
* Display server logic.
|
* Display server logic.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
#include <sys/keycodes.h>
|
#include <sys/keycodes.h>
|
||||||
#include <sys/ps2mouse.h>
|
#include <sys/ps2mouse.h>
|
||||||
|
@ -124,7 +123,8 @@ void display_unlink_window(struct display* display, struct window* window)
|
||||||
assert_is_well_formed_display_list(display);
|
assert_is_well_formed_display_list(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_unlink_window_removal(struct display* display, struct window* window)
|
void display_unlink_window_removal(struct display* display,
|
||||||
|
struct window* window)
|
||||||
{
|
{
|
||||||
assert_is_well_formed_display_list(display);
|
assert_is_well_formed_display_list(display);
|
||||||
|
|
||||||
|
@ -145,7 +145,8 @@ void display_unlink_window_removal(struct display* display, struct window* windo
|
||||||
assert_is_well_formed_display_list(display);
|
assert_is_well_formed_display_list(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_unmark_active_window(struct display* display, struct window* window)
|
void display_unmark_active_window(struct display* display,
|
||||||
|
struct window* window)
|
||||||
{
|
{
|
||||||
assert(display->active_window == window);
|
assert(display->active_window == window);
|
||||||
window->focus = false;
|
window->focus = false;
|
||||||
|
@ -173,7 +174,8 @@ void display_move_window_to_top(struct display* display, struct window* window)
|
||||||
display_link_window_at_top(display, window);
|
display_link_window_at_top(display, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_change_active_window(struct display* display, struct window* window)
|
void display_change_active_window(struct display* display,
|
||||||
|
struct window* window)
|
||||||
{
|
{
|
||||||
if ( display->active_window == window )
|
if ( display->active_window == window )
|
||||||
{
|
{
|
||||||
|
@ -284,7 +286,8 @@ void display_composit(struct display* display, struct framebuffer fb)
|
||||||
uint32_t bg_color = make_color(0x89 * 2/3, 0xc7 * 2/3, 0xff * 2/3);
|
uint32_t bg_color = make_color(0x89 * 2/3, 0xc7 * 2/3, 0xff * 2/3);
|
||||||
for ( size_t y = 0; y < damage_rect.height; y++ )
|
for ( size_t y = 0; y < damage_rect.height; y++ )
|
||||||
for ( size_t x = 0; x < damage_rect.width; x++ )
|
for ( size_t x = 0; x < damage_rect.width; x++ )
|
||||||
framebuffer_set_pixel(fb, damage_rect.left + x, damage_rect.top + y, bg_color);
|
framebuffer_set_pixel(fb, damage_rect.left + x, damage_rect.top + y,
|
||||||
|
bg_color);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
framebuffer_copy_to_framebuffer(fb, display->wallpaper);
|
framebuffer_copy_to_framebuffer(fb, display->wallpaper);
|
||||||
|
@ -303,7 +306,8 @@ void display_composit(struct display* display, struct framebuffer fb)
|
||||||
if ( window->left < 0 )
|
if ( window->left < 0 )
|
||||||
{
|
{
|
||||||
winfb_left = 0;
|
winfb_left = 0;
|
||||||
winfb = framebuffer_crop(winfb, -window->left, 0, winfb.xres, winfb.yres);
|
winfb = framebuffer_crop(winfb, -window->left, 0,
|
||||||
|
winfb.xres, winfb.yres);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
winfb_left = window->left;
|
winfb_left = window->left;
|
||||||
|
@ -311,7 +315,8 @@ void display_composit(struct display* display, struct framebuffer fb)
|
||||||
if ( window->top < 0 )
|
if ( window->top < 0 )
|
||||||
{
|
{
|
||||||
winfb_top = 0;
|
winfb_top = 0;
|
||||||
winfb = framebuffer_crop(winfb, 0, -window->top, winfb.xres, winfb.yres);
|
winfb = framebuffer_crop(winfb, 0, -window->top,
|
||||||
|
winfb.xres, winfb.yres);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
winfb_top = window->top;
|
winfb_top = window->top;
|
||||||
|
@ -320,14 +325,19 @@ void display_composit(struct display* display, struct framebuffer fb)
|
||||||
size_t winfb_height = winfb.yres;
|
size_t winfb_height = winfb.yres;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ( winfb_left < damage_rect.left && winfb_width < damage_rect.left - winfb_left )
|
if ( winfb_left < damage_rect.left &&
|
||||||
|
winfb_width < damage_rect.left - winfb_left )
|
||||||
continue;
|
continue;
|
||||||
if ( winfb_left < damage_rect.left )
|
if ( winfb_left < damage_rect.left )
|
||||||
winfb_left = damage_rect.left, winfb_width -= damage_rect.left - winfb_left;
|
{
|
||||||
|
winfb_left = damage_rect.left;
|
||||||
|
winfb_width -= damage_rect.left - winfb_left;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct framebuffer fb_dst =
|
struct framebuffer fb_dst =
|
||||||
framebuffer_crop(fb, winfb_left, winfb_top, winfb_width, winfb_height);
|
framebuffer_crop(fb, winfb_left, winfb_top,
|
||||||
|
winfb_width, winfb_height);
|
||||||
|
|
||||||
framebuffer_copy_to_framebuffer_blend(fb_dst, winfb);
|
framebuffer_copy_to_framebuffer_blend(fb_dst, winfb);
|
||||||
}
|
}
|
||||||
|
@ -356,12 +366,14 @@ void display_composit(struct display* display, struct framebuffer fb)
|
||||||
struct framebuffer arrow_render = arrow_framebuffer;
|
struct framebuffer arrow_render = arrow_framebuffer;
|
||||||
if ( pointer_x < 0 )
|
if ( pointer_x < 0 )
|
||||||
{
|
{
|
||||||
arrow_render = framebuffer_crop(arrow_render, -pointer_x, 0, arrow_render.xres, arrow_render.yres);
|
arrow_render = framebuffer_crop(arrow_render, -pointer_x, 0,
|
||||||
|
arrow_render.xres, arrow_render.yres);
|
||||||
pointer_x = 0;
|
pointer_x = 0;
|
||||||
}
|
}
|
||||||
if ( pointer_y < 0 )
|
if ( pointer_y < 0 )
|
||||||
{
|
{
|
||||||
arrow_render = framebuffer_crop(arrow_render, 0, -pointer_y, arrow_render.xres, arrow_render.yres);
|
arrow_render = framebuffer_crop(arrow_render, 0, -pointer_y,
|
||||||
|
arrow_render.xres, arrow_render.yres);
|
||||||
pointer_y = 0;
|
pointer_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,19 +390,13 @@ void display_composit(struct display* display, struct framebuffer fb)
|
||||||
|
|
||||||
void display_render(struct display* display)
|
void display_render(struct display* display)
|
||||||
{
|
{
|
||||||
struct dispmsg_crtc_mode mode;
|
struct dispmsg_get_crtc_mode get_mode_msg = {0};
|
||||||
{
|
get_mode_msg.msgid = DISPMSG_GET_CRTC_MODE;
|
||||||
struct dispmsg_get_crtc_mode msg;
|
get_mode_msg.device = display->display.device;
|
||||||
memset(&msg, 0, sizeof(msg));
|
get_mode_msg.connector = display->display.connector;
|
||||||
msg.msgid = DISPMSG_GET_CRTC_MODE;
|
if ( dispmsg_issue(&get_mode_msg, sizeof(get_mode_msg)) != 0 )
|
||||||
msg.device = 0; // TODO: Multi-screen support!
|
err(1, "dispmsg_issue: dispmsg_get_crtc_mode");
|
||||||
msg.connector = 0; // TODO: Multi-screen support!
|
struct dispmsg_crtc_mode mode = get_mode_msg.mode;
|
||||||
|
|
||||||
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
|
||||||
err(1, "dispmsg_issue: dispmsg_get_crtc_mode");
|
|
||||||
|
|
||||||
mode = msg.mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !(mode.control & DISPMSG_CONTROL_VALID) )
|
if ( !(mode.control & DISPMSG_CONTROL_VALID) )
|
||||||
errx(1, "No valid video mode was set");
|
errx(1, "No valid video mode was set");
|
||||||
|
@ -425,18 +431,13 @@ void display_render(struct display* display)
|
||||||
|
|
||||||
display_composit(display, display->fb);
|
display_composit(display, display->fb);
|
||||||
|
|
||||||
{
|
struct dispmsg_write_memory write_memory_msg = {0};
|
||||||
struct dispmsg_write_memory msg;
|
write_memory_msg.msgid = DISPMSG_WRITE_MEMORY;
|
||||||
memset(&msg, 0, sizeof(msg));
|
write_memory_msg.device = display->display.device;
|
||||||
msg.msgid = DISPMSG_WRITE_MEMORY;
|
write_memory_msg.size = framebuffer_size;
|
||||||
msg.device = 0; // TODO: Multi-screen support!
|
write_memory_msg.src = (uint8_t*) display->fb.buffer;
|
||||||
msg.offset = 0; // TODO: mode.fb_location!
|
if ( dispmsg_issue(&write_memory_msg, sizeof(write_memory_msg)) != 0 )
|
||||||
msg.size = framebuffer_size;
|
err(1, "dispmsg_issue: dispmsg_write_memory");
|
||||||
msg.src = (uint8_t*) display->fb.buffer;
|
|
||||||
|
|
||||||
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
|
||||||
err(1, "dispmsg_issue: dispmsg_write_memory");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_keyboard_event(struct display* display, uint32_t codepoint)
|
void display_keyboard_event(struct display* display, uint32_t codepoint)
|
||||||
|
@ -537,7 +538,8 @@ void display_keyboard_event(struct display* display, uint32_t codepoint)
|
||||||
{
|
{
|
||||||
// TODO: window->title can be null.
|
// TODO: window->title can be null.
|
||||||
char* new_title;
|
char* new_title;
|
||||||
if ( 0 <= asprintf(&new_title, "%s%s", window->title, grab_inputbed_string) )
|
if ( 0 <= asprintf(&new_title, "%s%s", window->title,
|
||||||
|
grab_inputbed_string) )
|
||||||
{
|
{
|
||||||
window->grab_input = true;
|
window->grab_input = true;
|
||||||
free(window->title);
|
free(window->title);
|
||||||
|
@ -709,18 +711,18 @@ void display_mouse_event(struct display* display, uint8_t byte)
|
||||||
if ( xm || ym )
|
if ( xm || ym )
|
||||||
{
|
{
|
||||||
bool floating = window->window_state == WINDOW_STATE_REGULAR;
|
bool floating = window->window_state == WINDOW_STATE_REGULAR;
|
||||||
bool on_edge = display->pointer_x == 0
|
bool on_edge =
|
||||||
|| display->pointer_y == 0
|
display->pointer_x == 0 ||
|
||||||
|| display->pointer_x
|
display->pointer_y == 0 ||
|
||||||
== (ssize_t) display->screen_width
|
display->pointer_x == (ssize_t) display->screen_width ||
|
||||||
|| display->pointer_y
|
display->pointer_y == (ssize_t) display->screen_height;
|
||||||
== (ssize_t) display->screen_height;
|
|
||||||
switch ( display->mouse_state )
|
switch ( display->mouse_state )
|
||||||
{
|
{
|
||||||
case MOUSE_STATE_NONE: break;
|
case MOUSE_STATE_NONE: break;
|
||||||
case MOUSE_STATE_TITLE_MOVE:
|
case MOUSE_STATE_TITLE_MOVE:
|
||||||
if ( clipped_edge )
|
if ( clipped_edge )
|
||||||
{
|
{
|
||||||
|
// TODO: Clean these up.
|
||||||
// I'd declare those in function scope but I'm afraid of
|
// I'd declare those in function scope but I'm afraid of
|
||||||
// messing with the code too much.
|
// messing with the code too much.
|
||||||
ssize_t x = display->pointer_x;
|
ssize_t x = display->pointer_x;
|
||||||
|
@ -732,22 +734,22 @@ void display_mouse_event(struct display* display, uint8_t byte)
|
||||||
ssize_t corner_size = (sw < sh ? sw : sh) / 4;
|
ssize_t corner_size = (sw < sh ? sw : sh) / 4;
|
||||||
if ( x < corner_size && y < corner_size )
|
if ( x < corner_size && y < corner_size )
|
||||||
window_tile_top_left(window);
|
window_tile_top_left(window);
|
||||||
else if (sw - x < corner_size && y < corner_size )
|
else if ( sw - x < corner_size && y < corner_size )
|
||||||
window_tile_top_right(window);
|
window_tile_top_right(window);
|
||||||
else if ( x < corner_size && sh - y < corner_size )
|
else if ( x < corner_size && sh - y < corner_size )
|
||||||
window_tile_bottom_left(window);
|
window_tile_bottom_left(window);
|
||||||
else if (sw - x < corner_size && sh - y < corner_size )
|
else if ( sw - x < corner_size && sh - y < corner_size )
|
||||||
window_tile_bottom_right(window);
|
window_tile_bottom_right(window);
|
||||||
else if (x == 0)
|
else if ( x == 0 )
|
||||||
window_tile_left(window);
|
window_tile_left(window);
|
||||||
else if (x == sw)
|
else if ( x == sw )
|
||||||
window_tile_right(window);
|
window_tile_right(window);
|
||||||
else if (y == 0)
|
else if ( y == 0 )
|
||||||
window_tile_top(window);
|
window_tile_top(window);
|
||||||
else if (y == sh)
|
else if ( y == sh )
|
||||||
window_tile_bottom(window);
|
window_tile_bottom(window);
|
||||||
}
|
}
|
||||||
else if (floating || !on_edge)
|
else if ( floating || !on_edge )
|
||||||
{
|
{
|
||||||
if ( !floating )
|
if ( !floating )
|
||||||
{
|
{
|
||||||
|
@ -799,7 +801,8 @@ void display_mouse_event(struct display* display, uint8_t byte)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_on_resolution_change(struct display* display, size_t width, size_t height)
|
void display_on_resolution_change(struct display* display, size_t width,
|
||||||
|
size_t height)
|
||||||
{
|
{
|
||||||
if ( display->screen_width == width && display->screen_height == height )
|
if ( display->screen_width == width && display->screen_height == height )
|
||||||
return;
|
return;
|
||||||
|
@ -807,7 +810,9 @@ void display_on_resolution_change(struct display* display, size_t width, size_t
|
||||||
display->screen_height = height;
|
display->screen_height = height;
|
||||||
display->pointer_x = width / 2;
|
display->pointer_x = width / 2;
|
||||||
display->pointer_y = height / 2;
|
display->pointer_y = height / 2;
|
||||||
for ( struct window* window = display->bottom_window; window; window = window->above_window )
|
for ( struct window* window = display->bottom_window;
|
||||||
|
window;
|
||||||
|
window = window->above_window )
|
||||||
window_on_display_resolution_change(window, display);
|
window_on_display_resolution_change(window, display);
|
||||||
wallpaper(display->wallpaper);
|
wallpaper(display->wallpaper);
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,8 +84,8 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
char* home_session = NULL;
|
char* home_session = NULL;
|
||||||
char** session_argv = NULL;
|
char** session_argv = NULL;
|
||||||
if ( 1 < argc )
|
if ( optind < argc )
|
||||||
session_argv = argv + 1;
|
session_argv = argv + optind;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char* home = getenv("HOME");
|
const char* home = getenv("HOME");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015, 2016, 2022 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2014, 2015, 2016, 2022, 2023 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
#ifndef DISPLAY_H
|
#ifndef DISPLAY_H
|
||||||
#define DISPLAY_H
|
#define DISPLAY_H
|
||||||
|
|
||||||
|
#include <sys/display.h>
|
||||||
#include <sys/ps2mouse.h>
|
#include <sys/ps2mouse.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -46,6 +47,7 @@ struct window;
|
||||||
|
|
||||||
struct display
|
struct display
|
||||||
{
|
{
|
||||||
|
struct tiocgdisplay display;
|
||||||
struct framebuffer fb;
|
struct framebuffer fb;
|
||||||
struct framebuffer wallpaper;
|
struct framebuffer wallpaper;
|
||||||
size_t fb_size;
|
size_t fb_size;
|
||||||
|
@ -74,19 +76,23 @@ void assert_is_well_formed_display_list(struct display* display);
|
||||||
void assert_is_well_formed_display(struct display* display);
|
void assert_is_well_formed_display(struct display* display);
|
||||||
void display_link_window_at_top(struct display* display, struct window* window);
|
void display_link_window_at_top(struct display* display, struct window* window);
|
||||||
void display_unlink_window(struct display* display, struct window* window);
|
void display_unlink_window(struct display* display, struct window* window);
|
||||||
void display_unlink_window_removal(struct display* display, struct window* window);
|
void display_unlink_window_removal(struct display* display,
|
||||||
void display_unmark_active_window(struct display* display, struct window* window);
|
struct window* window);
|
||||||
|
void display_unmark_active_window(struct display* display,
|
||||||
|
struct window* window);
|
||||||
void display_mark_active_window(struct display* display, struct window* window);
|
void display_mark_active_window(struct display* display, struct window* window);
|
||||||
void display_update_active_window(struct display* display);
|
void display_update_active_window(struct display* display);
|
||||||
void display_move_window_to_top(struct display* display, struct window* window);
|
void display_move_window_to_top(struct display* display, struct window* window);
|
||||||
void display_change_active_window(struct display* display, struct window* window);
|
void display_change_active_window(struct display* display,
|
||||||
|
struct window* window);
|
||||||
void display_set_active_window(struct display* display, struct window* window);
|
void display_set_active_window(struct display* display, struct window* window);
|
||||||
void display_add_window(struct display* display, struct window* window);
|
void display_add_window(struct display* display, struct window* window);
|
||||||
void display_remove_window(struct display* display, struct window* window);
|
void display_remove_window(struct display* display, struct window* window);
|
||||||
void display_composit(struct display* display, struct framebuffer fb);
|
void display_composit(struct display* display, struct framebuffer fb);
|
||||||
void display_render(struct display* display);
|
void display_render(struct display* display);
|
||||||
void display_keyboard_event(struct display* display, uint32_t codepoint);
|
void display_keyboard_event(struct display* display, uint32_t codepoint);
|
||||||
void display_on_resolution_change(struct display* display, size_t width, size_t height);
|
void display_on_resolution_change(struct display* display, size_t width,
|
||||||
|
size_t height);
|
||||||
void display_mouse_event(struct display* display, uint8_t byte);
|
void display_mouse_event(struct display* display, uint8_t byte);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
* Display server main loop.
|
* Display server main loop.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/termmode.h>
|
#include <sys/termmode.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
@ -77,6 +78,14 @@ void server_initialize(struct server* server, struct display* display,
|
||||||
err(1, tty);
|
err(1, tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Support for multiple displays.
|
||||||
|
struct tiocgdisplays gdisplays = {0};
|
||||||
|
gdisplays.count = 1;
|
||||||
|
gdisplays.displays = &display->display;
|
||||||
|
if ( ioctl(server->tty_fd, TIOCGDISPLAYS, &gdisplays) < 0 ||
|
||||||
|
gdisplays.count == 0 )
|
||||||
|
errx(1, "%s: No video devices are associated with this terminal", tty);
|
||||||
|
|
||||||
server->mouse_fd = open(mouse, O_RDONLY | O_CLOEXEC);
|
server->mouse_fd = open(mouse, O_RDONLY | O_CLOEXEC);
|
||||||
if ( server->mouse_fd < 0 )
|
if ( server->mouse_fd < 0 )
|
||||||
err(1, "%s", mouse);
|
err(1, "%s", mouse);
|
||||||
|
|
Loading…
Reference in New Issue