fixup! Add display server.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-06-17 23:10:33 +02:00
parent bdd859c748
commit a78704f7e6
4 changed files with 81 additions and 61 deletions

View File

@ -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
* purpose with or without fee is hereby granted, provided that the above
@ -17,7 +17,6 @@
* Display server logic.
*/
#include <sys/display.h>
#include <sys/keycodes.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);
}
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);
@ -145,7 +145,8 @@ void display_unlink_window_removal(struct display* display, struct window* windo
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);
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);
}
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 )
{
@ -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);
for ( size_t y = 0; y < damage_rect.height; y++ )
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
framebuffer_copy_to_framebuffer(fb, display->wallpaper);
@ -303,7 +306,8 @@ void display_composit(struct display* display, struct framebuffer fb)
if ( window->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
winfb_left = window->left;
@ -311,7 +315,8 @@ void display_composit(struct display* display, struct framebuffer fb)
if ( window->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
winfb_top = window->top;
@ -320,14 +325,19 @@ void display_composit(struct display* display, struct framebuffer fb)
size_t winfb_height = winfb.yres;
#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;
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
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);
}
@ -356,12 +366,14 @@ void display_composit(struct display* display, struct framebuffer fb)
struct framebuffer arrow_render = arrow_framebuffer;
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;
}
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;
}
@ -378,19 +390,13 @@ void display_composit(struct display* display, struct framebuffer fb)
void display_render(struct display* display)
{
struct dispmsg_crtc_mode mode;
{
struct dispmsg_get_crtc_mode msg;
memset(&msg, 0, sizeof(msg));
msg.msgid = DISPMSG_GET_CRTC_MODE;
msg.device = 0; // TODO: Multi-screen support!
msg.connector = 0; // TODO: Multi-screen support!
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
err(1, "dispmsg_issue: dispmsg_get_crtc_mode");
mode = msg.mode;
}
struct dispmsg_get_crtc_mode get_mode_msg = {0};
get_mode_msg.msgid = DISPMSG_GET_CRTC_MODE;
get_mode_msg.device = display->display.device;
get_mode_msg.connector = display->display.connector;
if ( dispmsg_issue(&get_mode_msg, sizeof(get_mode_msg)) != 0 )
err(1, "dispmsg_issue: dispmsg_get_crtc_mode");
struct dispmsg_crtc_mode mode = get_mode_msg.mode;
if ( !(mode.control & DISPMSG_CONTROL_VALID) )
errx(1, "No valid video mode was set");
@ -425,18 +431,13 @@ void display_render(struct display* display)
display_composit(display, display->fb);
{
struct dispmsg_write_memory msg;
memset(&msg, 0, sizeof(msg));
msg.msgid = DISPMSG_WRITE_MEMORY;
msg.device = 0; // TODO: Multi-screen support!
msg.offset = 0; // TODO: mode.fb_location!
msg.size = framebuffer_size;
msg.src = (uint8_t*) display->fb.buffer;
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
err(1, "dispmsg_issue: dispmsg_write_memory");
}
struct dispmsg_write_memory write_memory_msg = {0};
write_memory_msg.msgid = DISPMSG_WRITE_MEMORY;
write_memory_msg.device = display->display.device;
write_memory_msg.size = framebuffer_size;
write_memory_msg.src = (uint8_t*) display->fb.buffer;
if ( dispmsg_issue(&write_memory_msg, sizeof(write_memory_msg)) != 0 )
err(1, "dispmsg_issue: dispmsg_write_memory");
}
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.
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;
free(window->title);
@ -709,18 +711,18 @@ 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;
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 ( clipped_edge )
{
// TODO: Clean these up.
// I'd declare those in function scope but I'm afraid of
// messing with the code too much.
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;
if ( x < corner_size && y < corner_size )
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);
else if ( x < corner_size && sh - y < corner_size )
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);
else if (x == 0)
else if ( x == 0 )
window_tile_left(window);
else if (x == sw)
else if ( x == sw )
window_tile_right(window);
else if (y == 0)
else if ( y == 0 )
window_tile_top(window);
else if (y == sh)
else if ( y == sh )
window_tile_bottom(window);
}
else if (floating || !on_edge)
else if ( floating || !on_edge )
{
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 )
return;
@ -807,7 +810,9 @@ void display_on_resolution_change(struct display* display, size_t width, size_t
display->screen_height = height;
display->pointer_x = width / 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);
wallpaper(display->wallpaper);
}

View File

@ -84,8 +84,8 @@ int main(int argc, char* argv[])
char* home_session = NULL;
char** session_argv = NULL;
if ( 1 < argc )
session_argv = argv + 1;
if ( optind < argc )
session_argv = argv + optind;
else
{
const char* home = getenv("HOME");

View File

@ -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
* purpose with or without fee is hereby granted, provided that the above
@ -20,6 +20,7 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include <sys/display.h>
#include <sys/ps2mouse.h>
#include <stdbool.h>
@ -46,6 +47,7 @@ struct window;
struct display
{
struct tiocgdisplay display;
struct framebuffer fb;
struct framebuffer wallpaper;
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 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_removal(struct display* display, struct window* window);
void display_unmark_active_window(struct display* display, struct window* window);
void display_unlink_window_removal(struct display* display,
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_update_active_window(struct display* display);
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_add_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_render(struct display* display);
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);
#endif

View File

@ -17,6 +17,7 @@
* Display server main loop.
*/
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/termmode.h>
#include <sys/un.h>
@ -77,6 +78,14 @@ void server_initialize(struct server* server, struct display* display,
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);
if ( server->mouse_fd < 0 )
err(1, "%s", mouse);