fixup! Add display server.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-06-19 23:55:28 +02:00
parent 147b33c26b
commit 9afe0e6946
6 changed files with 81 additions and 81 deletions

View File

@ -227,8 +227,8 @@ CONNECTION_MESSAGE_HANDLER_SERVER(chkblayout)
event.error = errno; event.error = errno;
struct display_packet_header header; struct display_packet_header header;
header.message_id = EVENT_ACK; header.id = EVENT_ACK;
header.message_length = sizeof(event); header.size = sizeof(event);
connection_schedule_transmit(connection, &header, sizeof(header)); connection_schedule_transmit(connection, &header, sizeof(header));
connection_schedule_transmit(connection, &event, sizeof(event)); connection_schedule_transmit(connection, &event, sizeof(event));
@ -289,17 +289,17 @@ void connection_can_read(struct connection* connection,
connection->packet_header_received += amount; connection->packet_header_received += amount;
} }
size_t packet_length = connection->packet_header.message_length; size_t packet_size = connection->packet_header.size;
// TODO: Check allocation and protect against too big buffers. // TODO: Check allocation and protect against too big buffers.
if ( !connection->packet ) if ( !connection->packet )
connection->packet = (unsigned char*) malloc(packet_length); connection->packet = malloc(packet_size);
while ( connection->packet_received < packet_length ) while ( connection->packet_received < packet_size )
{ {
ssize_t amount = read(connection->fd, ssize_t amount = read(connection->fd,
connection->packet + connection->packet_received, connection->packet + connection->packet_received,
packet_length - connection->packet_received); packet_size - connection->packet_received);
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
return; return;
if ( amount < 0 || amount == 0 ) if ( amount < 0 || amount == 0 )
@ -307,14 +307,14 @@ void connection_can_read(struct connection* connection,
connection->packet_received += amount; connection->packet_received += amount;
} }
size_t packet_id = connection->packet_header.message_id; size_t packet_id = connection->packet_header.id;
if ( packet_id < num_connection_message_handlers ) if ( packet_id < num_connection_message_handlers )
{ {
struct connection_message_handler_registration* handler = struct connection_message_handler_registration* handler =
&connection_message_handlers[packet_id]; &connection_message_handlers[packet_id];
unsigned char* auxiliary = connection->packet + handler->message_size; unsigned char* auxiliary = connection->packet + handler->message_size;
size_t auxiliary_size = packet_length - handler->message_size; size_t auxiliary_size = packet_size - handler->message_size;
handler->handler(connection, connection->packet, handler->handler(connection, connection->packet,
auxiliary, auxiliary_size, server); auxiliary, auxiliary_size, server);
} }

View File

@ -567,8 +567,8 @@ void display_keyboard_event(struct display* display, uint32_t codepoint)
event.codepoint = codepoint; event.codepoint = codepoint;
struct display_packet_header header; struct display_packet_header header;
header.message_id = EVENT_KEYBOARD; header.id = EVENT_KEYBOARD;
header.message_length = sizeof(event); header.size = sizeof(event);
assert(window->connection); assert(window->connection);

View File

@ -308,8 +308,8 @@ void window_quit(struct window* window)
event.window_id = window->window_id; event.window_id = window->window_id;
struct display_packet_header header; struct display_packet_header header;
header.message_id = EVENT_QUIT; header.id = EVENT_QUIT;
header.message_length = sizeof(event); header.size = sizeof(event);
assert(window->connection); assert(window->connection);
@ -550,8 +550,8 @@ void window_notify_client_resize(struct window* window)
event.height = window_client_buffer(window).yres; event.height = window_client_buffer(window).yres;
struct display_packet_header header; struct display_packet_header header;
header.message_id = EVENT_RESIZE; header.id = EVENT_RESIZE;
header.message_length = sizeof(event); header.size = sizeof(event);
assert(window->connection); assert(window->connection);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen. * Copyright (c) 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2023 Juhani 'nortti' Krekelä. * Copyright (c) 2023 Juhani 'nortti' Krekelä.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -25,8 +25,8 @@
struct display_packet_header struct display_packet_header
{ {
uint32_t message_id; uint32_t id;
uint32_t message_length; uint32_t size;
}; };
#define DISPLAY_CREATE_WINDOW 0 #define DISPLAY_CREATE_WINDOW 0
@ -64,7 +64,7 @@ struct display_render_window
struct display_title_window struct display_title_window
{ {
uint32_t window_id; uint32_t window_id;
/* An UTF-8 string follows */ /* A non-terminated UTF-8 string follows */
}; };
#define DISPLAY_SHOW_WINDOW 5 #define DISPLAY_SHOW_WINDOW 5
@ -122,7 +122,7 @@ struct event_keyboard
struct event_ack struct event_ack
{ {
uint32_t id; uint32_t id;
int error; int32_t error;
}; };
#endif #endif

View File

@ -36,11 +36,8 @@ int display_spawn(int argc, char** argv);
struct display_connection* display_connect(const char* socket_path); struct display_connection* display_connect(const char* socket_path);
struct display_connection* display_connect_default(void); struct display_connection* display_connect_default(void);
void display_disconnect(struct display_connection* connection); void display_disconnect(struct display_connection* connection);
int display_connection_fd(struct display_connection* connection); int display_connection_fd(struct display_connection* connection);
void display_shutdown(struct display_connection* connection, uint32_t code); void display_shutdown(struct display_connection* connection, uint32_t code);
void display_create_window(struct display_connection* connection, void display_create_window(struct display_connection* connection,
uint32_t window_id); uint32_t window_id);
void display_destroy_window(struct display_connection* connection, void display_destroy_window(struct display_connection* connection,
@ -63,7 +60,6 @@ void display_show_window(struct display_connection* connection,
uint32_t window_id); uint32_t window_id);
void display_hide_window(struct display_connection* connection, void display_hide_window(struct display_connection* connection,
uint32_t window_id); uint32_t window_id);
void display_chkblayout(struct display_connection* connection, void display_chkblayout(struct display_connection* connection,
uint32_t id, uint32_t id,
void* data, void* data,

View File

@ -38,8 +38,10 @@
int display_spawn(int argc, char** argv) int display_spawn(int argc, char** argv)
{ {
// TODO: Overflow. int length = 2 + 1;
char** new_argv = malloc((2 + argc + 1) * sizeof(char*)); if ( __builtin_add_overflow(length, argc, &length) )
return errno = EOVERFLOW, -1;
char** new_argv = reallocarray(NULL, length, sizeof(char*));
if ( !new_argv ) if ( !new_argv )
return -1; return -1;
new_argv[0] = (char*) "display"; new_argv[0] = (char*) "display";
@ -58,7 +60,7 @@ static int open_local_client_socket(const char* path, int flags)
{ {
size_t path_length = strlen(path); size_t path_length = strlen(path);
size_t addr_size = offsetof(struct sockaddr_un, sun_path) + path_length + 1; size_t addr_size = offsetof(struct sockaddr_un, sun_path) + path_length + 1;
struct sockaddr_un* sockaddr = (struct sockaddr_un*) malloc(addr_size); struct sockaddr_un* sockaddr = malloc(addr_size);
if ( !sockaddr ) if ( !sockaddr )
return -1; return -1;
sockaddr->sun_family = AF_LOCAL; sockaddr->sun_family = AF_LOCAL;
@ -76,18 +78,17 @@ struct display_connection
{ {
int fd; int fd;
struct display_packet_header header; struct display_packet_header header;
size_t header_bytes; size_t header_got;
uint8_t* payload; uint8_t* payload;
size_t payload_bytes; size_t payload_got;
}; };
struct display_connection* display_connect(const char* socket_path) struct display_connection* display_connect(const char* socket_path)
{ {
struct display_connection* connection = struct display_connection* connection =
(struct display_connection*) malloc(sizeof(struct display_connection)); calloc(1, sizeof(struct display_connection));
if ( !connection ) if ( !connection )
return NULL; return NULL;
memset(connection, 0, sizeof(*connection));
if ( (connection->fd = open_local_client_socket(socket_path, 0)) < 0 ) if ( (connection->fd = open_local_client_socket(socket_path, 0)) < 0 )
return free(connection), (struct display_connection*) NULL; return free(connection), (struct display_connection*) NULL;
size_t send_buffer_size = 2 * 1024 * 1024; size_t send_buffer_size = 2 * 1024 * 1024;
@ -116,26 +117,26 @@ int display_connection_fd(struct display_connection* connection)
} }
static void send_message(struct display_connection* connection, static void send_message(struct display_connection* connection,
uint32_t message_id, uint32_t id,
const void* message, const void* message,
size_t message_size, size_t message_size,
const void* auxiliary, const void* auxiliary,
size_t auxiliary_size) size_t auxiliary_size)
{ {
struct display_packet_header header; struct display_packet_header header;
header.message_id = message_id; header.id = id;
header.message_length = message_size + auxiliary_size; header.size = message_size + auxiliary_size;
writeall(connection->fd, &header, sizeof(header)); writeall(connection->fd, &header, sizeof(header));
writeall(connection->fd, message, message_size); writeall(connection->fd, message, message_size);
writeall(connection->fd, auxiliary, auxiliary_size); writeall(connection->fd, auxiliary, auxiliary_size);
} }
static void send_message_no_aux(struct display_connection* connection, static void send_message_no_aux(struct display_connection* connection,
uint32_t message_id, uint32_t id,
const void* message, const void* message,
size_t message_size) size_t message_size)
{ {
send_message(connection, message_id, message, message_size, 0, 0); send_message(connection, id, message, message_size, 0, 0);
} }
void display_shutdown(struct display_connection* connection, uint32_t code) void display_shutdown(struct display_connection* connection, uint32_t code)
@ -197,7 +198,8 @@ void display_title_window(struct display_connection* connection,
{ {
struct display_title_window msg; struct display_title_window msg;
msg.window_id = window_id; msg.window_id = window_id;
send_message(connection, DISPLAY_TITLE_WINDOW, &msg, sizeof(msg), title, strlen(title)); send_message(connection, DISPLAY_TITLE_WINDOW, &msg, sizeof(msg), title,
strlen(title));
} }
void display_show_window(struct display_connection* connection, void display_show_window(struct display_connection* connection,
@ -229,41 +231,39 @@ void display_chkblayout(struct display_connection* connection,
static bool display_read_event(struct display_connection* connection) static bool display_read_event(struct display_connection* connection)
{ {
while ( connection->header_bytes < sizeof(connection->header) ) while ( connection->header_got < sizeof(connection->header) )
{ {
errno = 0; errno = 0;
ssize_t amount = read(connection->fd, uint8_t* data = (uint8_t*) &connection->header + connection->header_got;
(uint8_t*) &connection->header + connection->header_bytes, size_t left = sizeof(connection->header) - connection->header_got;
sizeof(connection->header) - connection->header_bytes); ssize_t amount = read(connection->fd, data, left);
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
break; break;
if ( amount < 0 ) if ( amount <= 0 )
break;
if ( amount == 0 )
return false; return false;
connection->header_bytes += amount; connection->header_got += amount;
} }
if ( connection->header_bytes == sizeof(connection->header) && if ( connection->header_got == sizeof(connection->header) &&
!connection->payload ) !connection->payload )
{ {
connection->payload = (uint8_t*) malloc(connection->header.message_length); connection->payload = malloc(connection->header.size);
connection->payload_bytes = 0; if ( !connection->payload )
return false;
connection->payload_got = 0;
} }
while ( connection->header_bytes == sizeof(connection->header) && while ( connection->header_got == sizeof(connection->header) &&
connection->payload && connection->payload &&
connection->payload_bytes < connection->header.message_length ) connection->payload_got < connection->header.size )
{ {
errno = 0; errno = 0;
ssize_t amount = read(connection->fd, uint8_t* data = connection->payload + connection->payload_got;
connection->payload + connection->payload_bytes, size_t left = connection->header.size - connection->payload_got;
connection->header.message_length - connection->payload_bytes); ssize_t amount = read(connection->fd, data, left);
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
break; break;
if ( amount < 0 ) if ( amount <= 0 )
break;
if ( amount == 0 )
return false; return false;
connection->payload_bytes += amount; connection->payload_got += amount;
} }
return true; return true;
@ -272,16 +272,16 @@ static bool display_read_event(struct display_connection* connection)
static int display_dispatch_event(struct display_connection* connection, static int display_dispatch_event(struct display_connection* connection,
struct display_event_handlers* handlers) struct display_event_handlers* handlers)
{ {
if ( connection->header_bytes == sizeof(connection->header) && if ( connection->header_got == sizeof(connection->header) &&
connection->payload && connection->payload &&
connection->payload_bytes == connection->header.message_length ) connection->payload_got == connection->header.size )
{ {
// TODO: == instead of <= due to warning. Maybe all should be changed to void* payload = connection->payload;
// use == instead.
if ( connection->header.message_id == EVENT_DISCONNECT && if ( connection->header.id == EVENT_DISCONNECT &&
connection->header.message_length ==/*>=*/ sizeof(struct event_disconnect) ) connection->header.size == sizeof(struct event_disconnect) )
{ {
struct event_disconnect* event = (struct event_disconnect*) connection->payload; struct event_disconnect* event = payload;
(void) event; (void) event;
if ( handlers->disconnect_handler ) if ( handlers->disconnect_handler )
handlers->disconnect_handler(handlers->context); handlers->disconnect_handler(handlers->context);
@ -289,43 +289,47 @@ static int display_dispatch_event(struct display_connection* connection,
exit(0); exit(0);
} }
if ( connection->header.message_id == EVENT_QUIT && if ( connection->header.id == EVENT_QUIT &&
connection->header.message_length >= sizeof(struct event_quit) ) connection->header.size == sizeof(struct event_quit) )
{ {
struct event_quit* event = (struct event_quit*) connection->payload; struct event_quit* event = payload;
if ( handlers->quit_handler ) if ( handlers->quit_handler )
handlers->quit_handler(handlers->context, event->window_id); handlers->quit_handler(handlers->context, event->window_id);
else else
exit(0); exit(0);
} }
if ( connection->header.message_id == EVENT_RESIZE && if ( connection->header.id == EVENT_RESIZE &&
connection->header.message_length >= sizeof(struct event_resize) ) connection->header.size == sizeof(struct event_resize) )
{ {
struct event_resize* event = (struct event_resize*) connection->payload; struct event_resize* event = payload;
if ( handlers->resize_handler ) if ( handlers->resize_handler )
handlers->resize_handler(handlers->context, event->window_id, event->width, event->height); handlers->resize_handler(handlers->context, event->window_id,
event->width, event->height);
} }
if ( connection->header.message_id == EVENT_KEYBOARD && if ( connection->header.id == EVENT_KEYBOARD &&
connection->header.message_length >= sizeof(struct event_keyboard) ) connection->header.size == sizeof(struct event_keyboard) )
{ {
struct event_keyboard* event = (struct event_keyboard*) connection->payload; struct event_keyboard* event = payload;
if ( handlers->keyboard_handler ) if ( handlers->keyboard_handler )
handlers->keyboard_handler(handlers->context, event->window_id, event->codepoint); handlers->keyboard_handler(handlers->context, event->window_id,
event->codepoint);
} }
if ( connection->header.message_id == EVENT_ACK && if ( connection->header.id == EVENT_ACK &&
connection->header.message_length >= sizeof(struct event_ack) ) connection->header.size == sizeof(struct event_ack) )
{ {
struct event_ack* event = (struct event_ack*) connection->payload; struct event_ack* event = payload;
if ( handlers->ack_handler ) if ( handlers->ack_handler )
handlers->ack_handler(handlers->context, event->id, event->error); handlers->ack_handler(handlers->context, event->id,
event->error);
} }
connection->header_bytes = 0; connection->header_got = 0;
free(connection->payload), connection->payload = NULL; free(connection->payload);
connection->payload_bytes = 0; connection->payload = NULL;
connection->payload_got = 0;
return 0; return 0;
} }