fixup! Add display server.
This commit is contained in:
parent
147b33c26b
commit
9afe0e6946
|
@ -227,8 +227,8 @@ CONNECTION_MESSAGE_HANDLER_SERVER(chkblayout)
|
|||
event.error = errno;
|
||||
|
||||
struct display_packet_header header;
|
||||
header.message_id = EVENT_ACK;
|
||||
header.message_length = sizeof(event);
|
||||
header.id = EVENT_ACK;
|
||||
header.size = sizeof(event);
|
||||
|
||||
connection_schedule_transmit(connection, &header, sizeof(header));
|
||||
connection_schedule_transmit(connection, &event, sizeof(event));
|
||||
|
@ -289,17 +289,17 @@ void connection_can_read(struct connection* connection,
|
|||
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.
|
||||
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,
|
||||
connection->packet + connection->packet_received,
|
||||
packet_length - connection->packet_received);
|
||||
packet_size - connection->packet_received);
|
||||
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
|
||||
return;
|
||||
if ( amount < 0 || amount == 0 )
|
||||
|
@ -307,14 +307,14 @@ void connection_can_read(struct connection* connection,
|
|||
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 )
|
||||
{
|
||||
struct connection_message_handler_registration* handler =
|
||||
&connection_message_handlers[packet_id];
|
||||
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,
|
||||
auxiliary, auxiliary_size, server);
|
||||
}
|
||||
|
|
|
@ -567,8 +567,8 @@ void display_keyboard_event(struct display* display, uint32_t codepoint)
|
|||
event.codepoint = codepoint;
|
||||
|
||||
struct display_packet_header header;
|
||||
header.message_id = EVENT_KEYBOARD;
|
||||
header.message_length = sizeof(event);
|
||||
header.id = EVENT_KEYBOARD;
|
||||
header.size = sizeof(event);
|
||||
|
||||
assert(window->connection);
|
||||
|
||||
|
|
|
@ -308,8 +308,8 @@ void window_quit(struct window* window)
|
|||
event.window_id = window->window_id;
|
||||
|
||||
struct display_packet_header header;
|
||||
header.message_id = EVENT_QUIT;
|
||||
header.message_length = sizeof(event);
|
||||
header.id = EVENT_QUIT;
|
||||
header.size = sizeof(event);
|
||||
|
||||
assert(window->connection);
|
||||
|
||||
|
@ -550,8 +550,8 @@ void window_notify_client_resize(struct window* window)
|
|||
event.height = window_client_buffer(window).yres;
|
||||
|
||||
struct display_packet_header header;
|
||||
header.message_id = EVENT_RESIZE;
|
||||
header.message_length = sizeof(event);
|
||||
header.id = EVENT_RESIZE;
|
||||
header.size = sizeof(event);
|
||||
|
||||
assert(window->connection);
|
||||
|
||||
|
|
|
@ -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ä.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -25,8 +25,8 @@
|
|||
|
||||
struct display_packet_header
|
||||
{
|
||||
uint32_t message_id;
|
||||
uint32_t message_length;
|
||||
uint32_t id;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
#define DISPLAY_CREATE_WINDOW 0
|
||||
|
@ -64,7 +64,7 @@ struct display_render_window
|
|||
struct display_title_window
|
||||
{
|
||||
uint32_t window_id;
|
||||
/* An UTF-8 string follows */
|
||||
/* A non-terminated UTF-8 string follows */
|
||||
};
|
||||
|
||||
#define DISPLAY_SHOW_WINDOW 5
|
||||
|
@ -122,7 +122,7 @@ struct event_keyboard
|
|||
struct event_ack
|
||||
{
|
||||
uint32_t id;
|
||||
int error;
|
||||
int32_t error;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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_default(void);
|
||||
void display_disconnect(struct display_connection* connection);
|
||||
|
||||
int display_connection_fd(struct display_connection* connection);
|
||||
|
||||
void display_shutdown(struct display_connection* connection, uint32_t code);
|
||||
|
||||
void display_create_window(struct display_connection* connection,
|
||||
uint32_t window_id);
|
||||
void display_destroy_window(struct display_connection* connection,
|
||||
|
@ -63,7 +60,6 @@ void display_show_window(struct display_connection* connection,
|
|||
uint32_t window_id);
|
||||
void display_hide_window(struct display_connection* connection,
|
||||
uint32_t window_id);
|
||||
|
||||
void display_chkblayout(struct display_connection* connection,
|
||||
uint32_t id,
|
||||
void* data,
|
||||
|
|
|
@ -38,8 +38,10 @@
|
|||
|
||||
int display_spawn(int argc, char** argv)
|
||||
{
|
||||
// TODO: Overflow.
|
||||
char** new_argv = malloc((2 + argc + 1) * sizeof(char*));
|
||||
int length = 2 + 1;
|
||||
if ( __builtin_add_overflow(length, argc, &length) )
|
||||
return errno = EOVERFLOW, -1;
|
||||
char** new_argv = reallocarray(NULL, length, sizeof(char*));
|
||||
if ( !new_argv )
|
||||
return -1;
|
||||
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 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 )
|
||||
return -1;
|
||||
sockaddr->sun_family = AF_LOCAL;
|
||||
|
@ -76,18 +78,17 @@ struct display_connection
|
|||
{
|
||||
int fd;
|
||||
struct display_packet_header header;
|
||||
size_t header_bytes;
|
||||
size_t header_got;
|
||||
uint8_t* payload;
|
||||
size_t payload_bytes;
|
||||
size_t payload_got;
|
||||
};
|
||||
|
||||
struct display_connection* display_connect(const char* socket_path)
|
||||
{
|
||||
struct display_connection* connection =
|
||||
(struct display_connection*) malloc(sizeof(struct display_connection));
|
||||
calloc(1, sizeof(struct display_connection));
|
||||
if ( !connection )
|
||||
return NULL;
|
||||
memset(connection, 0, sizeof(*connection));
|
||||
if ( (connection->fd = open_local_client_socket(socket_path, 0)) < 0 )
|
||||
return free(connection), (struct display_connection*) NULL;
|
||||
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,
|
||||
uint32_t message_id,
|
||||
uint32_t id,
|
||||
const void* message,
|
||||
size_t message_size,
|
||||
const void* auxiliary,
|
||||
size_t auxiliary_size)
|
||||
{
|
||||
struct display_packet_header header;
|
||||
header.message_id = message_id;
|
||||
header.message_length = message_size + auxiliary_size;
|
||||
header.id = id;
|
||||
header.size = message_size + auxiliary_size;
|
||||
writeall(connection->fd, &header, sizeof(header));
|
||||
writeall(connection->fd, message, message_size);
|
||||
writeall(connection->fd, auxiliary, auxiliary_size);
|
||||
}
|
||||
|
||||
static void send_message_no_aux(struct display_connection* connection,
|
||||
uint32_t message_id,
|
||||
uint32_t id,
|
||||
const void* message,
|
||||
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)
|
||||
|
@ -197,7 +198,8 @@ void display_title_window(struct display_connection* connection,
|
|||
{
|
||||
struct display_title_window msg;
|
||||
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,
|
||||
|
@ -229,41 +231,39 @@ void display_chkblayout(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;
|
||||
ssize_t amount = read(connection->fd,
|
||||
(uint8_t*) &connection->header + connection->header_bytes,
|
||||
sizeof(connection->header) - connection->header_bytes);
|
||||
uint8_t* data = (uint8_t*) &connection->header + connection->header_got;
|
||||
size_t left = sizeof(connection->header) - connection->header_got;
|
||||
ssize_t amount = read(connection->fd, data, left);
|
||||
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
|
||||
break;
|
||||
if ( amount < 0 )
|
||||
break;
|
||||
if ( amount == 0 )
|
||||
if ( amount <= 0 )
|
||||
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 = (uint8_t*) malloc(connection->header.message_length);
|
||||
connection->payload_bytes = 0;
|
||||
connection->payload = malloc(connection->header.size);
|
||||
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_bytes < connection->header.message_length )
|
||||
connection->payload_got < connection->header.size )
|
||||
{
|
||||
errno = 0;
|
||||
ssize_t amount = read(connection->fd,
|
||||
connection->payload + connection->payload_bytes,
|
||||
connection->header.message_length - connection->payload_bytes);
|
||||
uint8_t* data = connection->payload + connection->payload_got;
|
||||
size_t left = connection->header.size - connection->payload_got;
|
||||
ssize_t amount = read(connection->fd, data, left);
|
||||
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
|
||||
break;
|
||||
if ( amount < 0 )
|
||||
break;
|
||||
if ( amount == 0 )
|
||||
if ( amount <= 0 )
|
||||
return false;
|
||||
connection->payload_bytes += amount;
|
||||
connection->payload_got += amount;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -272,16 +272,16 @@ static bool display_read_event(struct display_connection* connection)
|
|||
static int display_dispatch_event(struct display_connection* connection,
|
||||
struct display_event_handlers* handlers)
|
||||
{
|
||||
if ( connection->header_bytes == sizeof(connection->header) &&
|
||||
if ( connection->header_got == sizeof(connection->header) &&
|
||||
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
|
||||
// use == instead.
|
||||
if ( connection->header.message_id == EVENT_DISCONNECT &&
|
||||
connection->header.message_length ==/*>=*/ sizeof(struct event_disconnect) )
|
||||
void* payload = connection->payload;
|
||||
|
||||
if ( connection->header.id == 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;
|
||||
if ( handlers->disconnect_handler )
|
||||
handlers->disconnect_handler(handlers->context);
|
||||
|
@ -289,43 +289,47 @@ static int display_dispatch_event(struct display_connection* connection,
|
|||
exit(0);
|
||||
}
|
||||
|
||||
if ( connection->header.message_id == EVENT_QUIT &&
|
||||
connection->header.message_length >= sizeof(struct event_quit) )
|
||||
if ( connection->header.id == 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 )
|
||||
handlers->quit_handler(handlers->context, event->window_id);
|
||||
else
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ( connection->header.message_id == EVENT_RESIZE &&
|
||||
connection->header.message_length >= sizeof(struct event_resize) )
|
||||
if ( connection->header.id == 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 )
|
||||
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 &&
|
||||
connection->header.message_length >= sizeof(struct event_keyboard) )
|
||||
if ( connection->header.id == 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 )
|
||||
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 &&
|
||||
connection->header.message_length >= sizeof(struct event_ack) )
|
||||
if ( connection->header.id == 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 )
|
||||
handlers->ack_handler(handlers->context, event->id, event->error);
|
||||
handlers->ack_handler(handlers->context, event->id,
|
||||
event->error);
|
||||
}
|
||||
|
||||
connection->header_bytes = 0;
|
||||
free(connection->payload), connection->payload = NULL;
|
||||
connection->payload_bytes = 0;
|
||||
connection->header_got = 0;
|
||||
free(connection->payload);
|
||||
connection->payload = NULL;
|
||||
connection->payload_got = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue