fixup! Add display server.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-05-15 23:25:36 +02:00
parent 42faa43cee
commit a0ccd6149c
3 changed files with 189 additions and 60 deletions

View File

@ -409,17 +409,7 @@ void display_keyboard_event(struct display* display, uint32_t codepoint)
if ( (display->key_lalt && kbkey == KBKEY_F4) /* ||
(display->key_lctrl && kbkey == KBKEY_Q)*/ )
{
struct event_keyboard event;
event.window_id = display->active_window->window_id;
struct display_packet_header header;
header.message_id = EVENT_QUIT;
header.message_length = sizeof(event);
assert(window->connection);
connection_schedule_transmit(window->connection, &header, sizeof(header));
connection_schedule_transmit(window->connection, &event, sizeof(event));
window_quit(window);
return;
}
@ -546,14 +536,27 @@ void display_mouse_event(struct display* display, uint8_t byte)
display->pointer_x += xm;
display->pointer_y += ym;
bool clipped_edge = false;
if ( display->pointer_x < 0 )
{
display->pointer_x = 0;
clipped_edge = true;
}
if ( display->pointer_y < 0 )
{
display->pointer_y = 0;
if ( display->screen_width <= (size_t) display->pointer_x )
clipped_edge = true;
}
if ( display->screen_width < (size_t) display->pointer_x )
{
display->pointer_x = display->screen_width;
if ( display->screen_height <= (size_t) display->pointer_y )
clipped_edge = true;
}
if ( display->screen_height < (size_t) display->pointer_y )
{
display->pointer_y = display->screen_height;
clipped_edge = true;
}
xm = display->pointer_x - old_pointer_x;
ym = display->pointer_y - old_pointer_y;
@ -592,8 +595,23 @@ void display_mouse_event(struct display* display, uint8_t byte)
window_pointer_x < (ssize_t) window->width &&
0 <= window_pointer_y &&
window_pointer_y <= (ssize_t) TITLE_HEIGHT) )
display->mouse_state = MOUSE_STATE_TITLE_MOVE;
else if ( window_pointer_x < 0 && window_pointer_y < 0 )
{
size_t border_width = window_border_width(window);
size_t button_width = FONT_WIDTH * 2;
ssize_t buttons_x = window->width - border_width
- button_width * 3 + 1;
ssize_t rel_x = window_pointer_x - buttons_x;
if ( 0 <= rel_x && rel_x < (ssize_t) button_width )
{
// TODO Minimize window.
}
else if ( 0 <= rel_x && rel_x < (ssize_t) button_width * 2 )
window_toggle_maximized(window);
else if ( 0 <= rel_x && rel_x < (ssize_t) button_width * 3 )
window_quit(window);
else
display->mouse_state = MOUSE_STATE_TITLE_MOVE;
} else if ( window_pointer_x < 0 && window_pointer_y < 0 )
display->mouse_state = MOUSE_STATE_RESIZE_TOP_LEFT;
else if ( window_pointer_x < 0 &&
0 <= window_pointer_y &&
@ -623,13 +641,60 @@ void display_mouse_event(struct display* display, uint8_t byte)
}
if ( xm || ym )
{
bool floating = window->window_state == WINDOW_STATE_REGULAR;
bool on_edge = display->pointer_x == 0
|| display->pointer_y == 0
|| display->pointer_x
== (ssize_t) display->screen_width
|| display->pointer_y
== (ssize_t) display->screen_height;
switch ( display->mouse_state )
{
case MOUSE_STATE_NONE: break;
case MOUSE_STATE_TITLE_MOVE:
if ( window->window_state != WINDOW_STATE_REGULAR )
window_restore(window);
window_move(window, window->left + xm, window->top + ym);
if ( clipped_edge )
{
// I'd declare those in function scope but I'm afraid of
// messing with the code too much.
ssize_t x = display->pointer_x;
ssize_t y = display->pointer_y;
ssize_t sw = display->screen_width;
ssize_t sh = display->screen_height;
ssize_t corner_size = (sw < sh ? sw : sh) / 4;
if ( x < corner_size && y < corner_size )
window_tile_top_left(window);
else if (sw - x < corner_size && y < corner_size )
window_tile_top_right(window);
else if ( x < corner_size && sh - y < corner_size )
window_tile_bottom_left(window);
else if (sw - x < corner_size && sh - y < corner_size )
window_tile_bottom_right(window);
else if (x == 0)
window_tile_left(window);
else if (x == sw)
window_tile_right(window);
else if (y == 0)
window_tile_top(window);
else if (y == sh)
window_tile_bottom(window);
}
else if (floating || !on_edge)
{
if ( !floating )
{
// The current behaviour of window_restore becomes
// awkward with tiling gestures. I could change the
// function itself, especially since this is currently
// its only callsite, but the old behaviour could be
// nice for a future untile hotkey. Thus, this hack.
window_restore(window);
window->top = display->pointer_y - TITLE_HEIGHT / 2;
window->left = display->pointer_x - window->width / 2;
}
window_move(window, window->left + xm, window->top + ym);
}
break;
case MOUSE_STATE_RESIZE_TOP_LEFT:
window_drag_resize(window, xm, ym, -xm, -ym);

View File

@ -101,62 +101,97 @@ void window_render_frame(struct window* window)
}
const char* tt = window->title ? window->title : "";
size_t tt_max_width = window->width - 2 * BORDER_WIDTH;
size_t tt_desired_width = render_text_width(tt);
size_t tt_width = tt_desired_width < tt_max_width ? tt_desired_width : tt_max_width;
ssize_t tt_width = render_text_width(tt); // Potentially adjusted later.
size_t tt_height = FONT_HEIGHT;
size_t tt_pos_x = BORDER_WIDTH + (tt_max_width - tt_width) / 2;
size_t tt_pos_y = (TITLE_HEIGHT - FONT_HEIGHT) / 2 + 2;
uint32_t tt_color = title_color;
render_text(framebuffer_crop(window->buffer, tt_pos_x, tt_pos_y, tt_width, tt_height), tt, tt_color);
size_t border_width = maximized ? BORDER_WIDTH / 2 : BORDER_WIDTH;
size_t button_size = FONT_WIDTH - 1;
size_t button_spacing = FONT_WIDTH;
size_t border_width = window_border_width(window);
size_t button_width = FONT_WIDTH * 2;
size_t button_height = FONT_HEIGHT;
ssize_t buttons_x = window->width - border_width - button_width * 3 + 1;
struct framebuffer buttons_fb =
framebuffer_crop(window->buffer,
window->width - border_width - (FONT_HEIGHT - button_size) / 2 - 5 * button_spacing,
tt_pos_y, tt_width, tt_height);
size_t buttons_top = (FONT_HEIGHT - button_size) / 2;
framebuffer_crop(window->buffer, buttons_x,
tt_pos_y, button_width * 3, tt_height);
size_t button_size = FONT_WIDTH - 1;
#if 0
for (size_t x = 0; x < button_width; x++)
for (size_t y = 0; y < button_height; y++)
framebuffer_set_pixel(buttons_fb, button_width * 0 + x, y, 0xFF8080FF);
for (size_t x = 0; x < button_width; x++)
for (size_t y = 0; y < button_height; y++)
framebuffer_set_pixel(buttons_fb, button_width * 1 + x, y, 0xFFFF8080);
for (size_t x = 0; x < button_width; x++)
for (size_t y = 0; y < button_height; y++)
framebuffer_set_pixel(buttons_fb, button_width * 2 + x, y, 0xFF8080FF);
#endif
for ( size_t i = 0; i < button_size; i++ )
{
framebuffer_set_pixel(buttons_fb, 0 * button_spacing + i,
buttons_top + button_size - 1, tt_color);
framebuffer_set_pixel(buttons_fb, 0 * button_spacing + i,
buttons_top + button_size - 2, tt_color);
size_t bx = button_width * 0 + (button_width - button_size) / 2;
size_t by = (button_height - button_size) / 2;
framebuffer_set_pixel(buttons_fb, bx + i,
by + button_size - 1, tt_color);
framebuffer_set_pixel(buttons_fb, bx + i,
by + button_size - 2, tt_color);
}
for ( size_t i = 0; i < button_size; i++ )
{
framebuffer_set_pixel(buttons_fb, 2 * button_spacing + i,
buttons_top, tt_color);
framebuffer_set_pixel(buttons_fb, 2 * button_spacing + i,
buttons_top + button_size - 1 , tt_color);
framebuffer_set_pixel(buttons_fb, 2 * button_spacing,
buttons_top + i, tt_color);
framebuffer_set_pixel(buttons_fb, 2 * button_spacing + button_size - 1,
buttons_top + i, tt_color);
size_t bx = button_width * 1 + (button_width - button_size) / 2;
size_t by = (button_height - button_size) / 2;
framebuffer_set_pixel(buttons_fb, bx + i,
by, tt_color);
framebuffer_set_pixel(buttons_fb, bx + i,
by + button_size - 1 , tt_color);
framebuffer_set_pixel(buttons_fb, bx,
by + i, tt_color);
framebuffer_set_pixel(buttons_fb, bx + button_size - 1,
by + i, tt_color);
framebuffer_set_pixel(buttons_fb, 2 * button_spacing + i,
buttons_top + 1, tt_color);
framebuffer_set_pixel(buttons_fb, 2 * button_spacing + i,
buttons_top + button_size - 2 , tt_color);
framebuffer_set_pixel(buttons_fb, 2 * button_spacing + 1,
buttons_top + i, tt_color);
framebuffer_set_pixel(buttons_fb, 2 * button_spacing + button_size - 2,
buttons_top + i, tt_color);
framebuffer_set_pixel(buttons_fb, bx + i,
by + 1, tt_color);
framebuffer_set_pixel(buttons_fb, bx + i,
by + button_size - 2 , tt_color);
framebuffer_set_pixel(buttons_fb, bx + 1,
by + i, tt_color);
framebuffer_set_pixel(buttons_fb, bx + button_size - 2,
by + i, tt_color);
}
for ( size_t i = 0; i < button_size; i++ )
{
framebuffer_set_pixel(buttons_fb, 4 * button_spacing + i,
buttons_top + i, tt_color);
framebuffer_set_pixel(buttons_fb, 4 * button_spacing + i,
buttons_top + button_size - 1 - i, tt_color);
size_t bx = button_width * 2 + (button_width - button_size) / 2;
size_t by = (button_height - button_size) / 2;
framebuffer_set_pixel(buttons_fb, bx + i,
by + i, tt_color);
framebuffer_set_pixel(buttons_fb, bx + i,
by + button_size - 1 - i, tt_color);
framebuffer_set_pixel(buttons_fb, 4 * button_spacing + i + 1,
buttons_top + i, tt_color);
framebuffer_set_pixel(buttons_fb, 4 * button_spacing + i + 1,
buttons_top + button_size - 1 - i, tt_color);
framebuffer_set_pixel(buttons_fb, bx + i - 1,
by + i, tt_color);
framebuffer_set_pixel(buttons_fb, bx + i - 1,
by + button_size - 1 - i, tt_color);
}
ssize_t q = 500 - window->width;
ssize_t q_width = 200;
q = q < q_width ? q : q_width;
q = 0 < q ? q : 0;
ssize_t center_over = window->width - (button_width * 3 * q / q_width);
ssize_t tt_pos_x = (center_over - tt_width) / 2;
#if 0
for (int y = 0; y < 10; y++)
{
framebuffer_set_pixel(window->buffer, window->width / 2, y, 0xFFFF0000);
framebuffer_set_pixel(window->buffer, (window->width - button_width * 3) / 2, y, 0xFFFF0000);
framebuffer_set_pixel(window->buffer, center_over/2, y, 0xFFFF00FF);
}
#endif
if ( tt_pos_x < (ssize_t)border_width )
{
tt_pos_x = border_width;
tt_width = buttons_x - border_width;
tt_width = 0 < tt_width ? tt_width : 0;
}
render_text(framebuffer_crop(window->buffer, tt_pos_x, tt_pos_y, tt_width, tt_height), tt, tt_color);
}
void window_move(struct window* window, size_t left, size_t top)
@ -172,7 +207,7 @@ void window_client_resize(struct window* window,
if ( window->window_state != WINDOW_STATE_MINIMIZED )
window->window_state = WINDOW_STATE_REGULAR;
free(window->buffer.buffer);
struct framebuffer old_fb = window->buffer;
window->width = client_width + BORDER_WIDTH + BORDER_WIDTH;
window->height = client_height + TITLE_HEIGHT + BORDER_WIDTH;
@ -182,7 +217,12 @@ void window_client_resize(struct window* window,
window->buffer.pitch = window->width;
window->buffer.buffer = (uint32_t*)
malloc(sizeof(uint32_t) * window->width * window->height);
memset(window->buffer.buffer, 0, sizeof(uint32_t) * window->width * window->height);
for ( size_t y = 0; y < window->height; y++ )
for ( size_t x = 0; x < window->width; x++ )
framebuffer_set_pixel(window->buffer, x, y,
framebuffer_get_pixel(old_fb, x, y));
free(old_fb.buffer);
window_render_frame(window);
window_notify_client_resize(window);
@ -243,6 +283,21 @@ void window_initialize(struct window* window,
window_client_resize(window, 0, 0);
}
void window_quit(struct window* window)
{
struct event_keyboard event;
event.window_id = window->window_id;
struct display_packet_header header;
header.message_id = EVENT_QUIT;
header.message_length = sizeof(event);
assert(window->connection);
connection_schedule_transmit(window->connection, &header, sizeof(header));
connection_schedule_transmit(window->connection, &event, sizeof(event));
}
void window_destroy(struct window* window)
{
display_remove_window(window->display, window);
@ -480,3 +535,9 @@ void window_notify_client_resize(struct window* window)
connection_schedule_transmit(window->connection, &header, sizeof(header));
connection_schedule_transmit(window->connection, &event, sizeof(event));
}
size_t window_border_width(const struct window* window)
{
bool maximized = window->window_state != WINDOW_STATE_REGULAR;
return maximized ? BORDER_WIDTH / 2 : BORDER_WIDTH;
}

View File

@ -80,6 +80,7 @@ void window_move(struct window* window, size_t left, size_t top);
void window_resize(struct window* window, size_t width, size_t height);
void window_client_resize(struct window* window, size_t client_width, size_t client_height);
void window_initialize(struct window* window, struct connection* connection, struct display* display, uint32_t window_id);
void window_quit(struct window* window);
void window_destroy(struct window* window);
void window_drag_resize(struct window* window, int ld, int td, int wd, int hd);
void window_on_display_resolution_change(struct window* window, struct display* display);
@ -101,4 +102,6 @@ void window_tile_bottom_left(struct window* window);
void window_tile_bottom_right(struct window* window);
void window_notify_client_resize(struct window* window);
size_t window_border_width(const struct window* window);
#endif