From 97079ad52c313d4b622110cae978ee7c2392b714 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Sun, 21 Dec 2008 22:45:33 -0500 Subject: [PATCH] Send client id range as an event. This also makes the server send the event again when the client is about to exhaust its current client range. --- wayland-client.c | 74 ++++++++++++++++++++++++++++++++++++------------------ wayland-protocol.c | 1 + wayland-protocol.h | 1 + wayland.c | 24 ++++++++++++------ 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/wayland-client.c b/wayland-client.c index a898fd2..8a597f5 100644 --- a/wayland-client.c +++ b/wayland-client.c @@ -57,7 +57,7 @@ struct wl_display { struct wl_proxy proxy; struct wl_connection *connection; int fd; - uint32_t id; + uint32_t id, id_count, next_range; uint32_t mask; struct wl_list global_list; struct wl_list visual_list; @@ -162,10 +162,6 @@ wl_display_create(const char *name, size_t name_size) return NULL; } - /* FIXME: We'll need a protocol for getting a new range, I - * guess... */ - read(display->fd, &display->id, sizeof display->id); - wl_list_init(&display->global_list); wl_list_init(&display->visual_list); @@ -222,29 +218,50 @@ wl_display_get_fd(struct wl_display *display, } static void -handle_global(struct wl_display *display, uint32_t *p, uint32_t size) +handle_display_event(struct wl_display *display, + uint32_t opcode, uint32_t *p, uint32_t size) { struct wl_global *global; uint32_t length; - global = malloc(sizeof *global); - if (global == NULL) - return; - - global->id = p[0]; - length = p[1]; - global->interface = malloc(length + 1); - if (global->interface == NULL) { - free(global); - return; + switch (opcode) { + case WL_DISPLAY_INVALID_OBJECT: + fprintf(stderr, "sent request to invalid object\n"); + break; + + case WL_DISPLAY_INVALID_METHOD: + fprintf(stderr, "sent invalid request opcode\n"); + break; + + case WL_DISPLAY_NO_MEMORY: + fprintf(stderr, "server out of memory\n"); + break; + + case WL_DISPLAY_GLOBAL: + global = malloc(sizeof *global); + if (global == NULL) + return; + + global->id = p[0]; + length = p[1]; + global->interface = malloc(length + 1); + if (global->interface == NULL) { + free(global); + return; + } + memcpy(global->interface, &p[2], length); + global->interface[length] = '\0'; + global->version = p[2 + DIV_ROUNDUP(length, sizeof *p)]; + wl_list_insert(display->global_list.prev, &global->link); + + if (strcmp(global->interface, "visual") == 0) + add_visual(display, global); + break; + + case WL_DISPLAY_RANGE: + display->next_range = p[0]; + break; } - memcpy(global->interface, &p[2], length); - global->interface[length] = '\0'; - global->version = p[2 + DIV_ROUNDUP(length, sizeof *p)]; - wl_list_insert(display->global_list.prev, &global->link); - - if (strcmp(global->interface, "visual") == 0) - add_visual(display, global); } static void @@ -254,8 +271,8 @@ handle_event(struct wl_display *display, uint32_t p[32]; wl_connection_copy(display->connection, p, size); - if (object == 1 && opcode == WL_DISPLAY_GLOBAL) { - handle_global(display, p + 2, size); + if (object == 1) { + handle_display_event(display, opcode, p + 2, size); } else if (display->event_handler != NULL) display->event_handler(display, object, opcode, size, p + 2, display->event_handler_data); @@ -303,6 +320,13 @@ wl_display_set_event_handler(struct wl_display *display, WL_EXPORT uint32_t wl_display_allocate_id(struct wl_display *display) { + if (display->id_count == 0) { + display->id_count = 256; + display->id = display->next_range; + } + + display->id_count--; + return display->id++; } diff --git a/wayland-protocol.c b/wayland-protocol.c index 5b20154..4c61810 100644 --- a/wayland-protocol.c +++ b/wayland-protocol.c @@ -30,6 +30,7 @@ static const struct wl_message display_events[] = { { "invalid_method", "uu" }, { "no_memory", "" }, { "global", "osu" }, + { "range", "u" }, }; WL_EXPORT const struct wl_interface wl_display_interface = { diff --git a/wayland-protocol.h b/wayland-protocol.h index f5deea3..c71cfdc 100644 --- a/wayland-protocol.h +++ b/wayland-protocol.h @@ -49,6 +49,7 @@ struct wl_interface { #define WL_DISPLAY_INVALID_METHOD 1 #define WL_DISPLAY_NO_MEMORY 2 #define WL_DISPLAY_GLOBAL 3 +#define WL_DISPLAY_RANGE 4 extern const struct wl_interface wl_display_interface; diff --git a/wayland.c b/wayland.c index 48e1513..6ad1887 100644 --- a/wayland.c +++ b/wayland.c @@ -44,6 +44,7 @@ struct wl_client { struct wl_display *display; struct wl_list object_list; struct wl_list link; + uint32_t id_count; }; struct wl_display { @@ -270,6 +271,15 @@ wl_client_connection_update(struct wl_connection *connection, return wl_event_source_fd_update(client->source, mask); } +static void +wl_display_post_range(struct wl_display *display, struct wl_client *client) +{ + wl_client_marshal(client, &client->display->base, + WL_DISPLAY_RANGE, display->client_id_range); + display->client_id_range += 256; + client->id_count += 256; +} + static struct wl_client * wl_client_create(struct wl_display *display, int fd) { @@ -285,16 +295,13 @@ wl_client_create(struct wl_display *display, int fd) client->source = wl_event_loop_add_fd(display->loop, fd, WL_EVENT_READABLE, wl_client_connection_data, client); - client->connection = wl_connection_create(fd, - wl_client_connection_update, - client); + client->connection = + wl_connection_create(fd, wl_client_connection_update, client); + wl_list_init(&client->object_list); wl_list_init(&client->link); - wl_connection_write(client->connection, - &display->client_id_range, - sizeof display->client_id_range); - display->client_id_range += 256; + wl_display_post_range(display, client); ref = container_of(display->global_list.next, struct wl_object_ref, link); @@ -353,6 +360,9 @@ wl_client_add_surface(struct wl_client *client, struct wl_display *display = client->display; struct wl_object_ref *ref; + if (client->id_count-- < 64) + wl_display_post_range(display, client); + surface->base.id = id; surface->base.interface = &wl_surface_interface; surface->base.implementation = (void (**)(void)) implementation; -- 2.7.4