diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2011-08-19 16:57:48 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2011-08-27 12:06:11 -0400 |
commit | cc6fd94d6a5743eb94b52f1887557305784525c9 (patch) | |
tree | 31455a407711ddbaa2994182a32892b76857c523 | |
parent | c4774d55e91a722e29326c30ab49dcc3850e0a00 (diff) |
Always allocate a new wl_resource when binding an object
Previously we would bind some resources into multiple client hash tables.
-rw-r--r-- | protocol/wayland.xml | 6 | ||||
-rw-r--r-- | src/wayland-server.c | 209 | ||||
-rw-r--r-- | src/wayland-server.h | 23 | ||||
-rw-r--r-- | src/wayland-shm.c | 24 | ||||
-rw-r--r-- | src/wayland-util.h | 2 |
5 files changed, 151 insertions, 113 deletions
diff --git a/protocol/wayland.xml b/protocol/wayland.xml index ac1e2e5..70b505d 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -66,8 +66,8 @@ server will always announce an object before the object sends out events. --> <event name="global"> - <arg name="id" type="uint" interface="wl_object"/> - <arg name="name" type="string"/> + <arg name="name" type="uint" interface="wl_object"/> + <arg name="interface" type="string"/> <arg name="version" type="uint"/> </event> @@ -109,7 +109,7 @@ </enum> <event name="token_visual"> - <arg name="visual" type="new_id" interface="wl_visual"/> + <arg name="name" type="uint"/> <arg name="token" type="uint"/> </event> </interface> diff --git a/src/wayland-server.c b/src/wayland-server.c index 337ac0b..0f15afd 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -57,7 +57,7 @@ struct wl_client { struct wl_connection *connection; struct wl_event_source *source; struct wl_display *display; - struct wl_resource display_resource; + struct wl_resource *display_resource; struct wl_list resource_list; uint32_t id_count; uint32_t mask; @@ -80,7 +80,9 @@ struct wl_display { }; struct wl_global { - struct wl_object *object; + const struct wl_interface *interface; + uint32_t name; + void *data; wl_global_bind_func_t bind; struct wl_list link; }; @@ -119,7 +121,7 @@ wl_client_post_error(struct wl_client *client, struct wl_object *object, vsnprintf(buffer, sizeof buffer, msg, ap); va_end(ap); - wl_resource_post_event(&client->display_resource, + wl_resource_post_event(client->display_resource, WL_DISPLAY_ERROR, object, code, buffer); } @@ -242,17 +244,20 @@ wl_client_get_display(struct wl_client *client) static void wl_display_post_range(struct wl_display *display, struct wl_client *client) { - wl_resource_post_event(&client->display_resource, + wl_resource_post_event(client->display_resource, WL_DISPLAY_RANGE, display->client_id_range); display->client_id_range += 256; client->id_count += 256; } +static void +bind_display(struct wl_client *client, + void *data, uint32_t version, uint32_t id); + WL_EXPORT struct wl_client * wl_client_create(struct wl_display *display, int fd) { struct wl_client *client; - struct wl_global *global; client = malloc(sizeof *client); if (client == NULL) @@ -277,22 +282,12 @@ wl_client_create(struct wl_display *display, int fd) return NULL; } - client->display_resource.object = display->resource.object; - client->display_resource.client = client; - client->display_resource.data = &display->resource; - - wl_hash_table_insert(client->objects, - client->display_resource.object.id, - &client->display_resource); + bind_display(client, display, 1, 1); wl_list_insert(display->client_list.prev, &client->link); wl_list_init(&client->resource_list); - wl_display_post_range(display, client); - - wl_list_for_each(global, &display->global_list, link) - wl_client_post_global(client, global->object); return client; } @@ -321,16 +316,6 @@ wl_client_post_no_memory(struct wl_client *client) } WL_EXPORT void -wl_client_post_global(struct wl_client *client, struct wl_object *object) -{ - wl_resource_post_event(&client->display_resource, - WL_DISPLAY_GLOBAL, - object->id, - object->interface->name, - object->interface->version); -} - -WL_EXPORT void wl_resource_destroy(struct wl_resource *resource, uint32_t time) { struct wl_client *client = resource->client; @@ -551,17 +536,15 @@ display_bind(struct wl_client *client, struct wl_display *display = resource->data; wl_list_for_each(global, &display->global_list, link) - if (global->object->id == name) + if (global->name == name) break; if (&global->link == &display->global_list) wl_client_post_error(client, &client->display->resource.object, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid global %d", name); - else if (global->bind) - global->bind(client, global->object, version, id); - - wl_hash_table_insert(client->objects, id, global->object); + else + global->bind(client, global->data, version, id); } static void @@ -582,6 +565,26 @@ struct wl_display_interface display_interface = { display_sync, }; +static void +bind_display(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + struct wl_display *display = data; + struct wl_global *global; + + client->display_resource = + wl_client_add_object(client, &wl_display_interface, + &display_interface, id, display); + + wl_display_post_range(display, client); + + wl_list_for_each(global, &display->global_list, link) + wl_resource_post_event(client->display_resource, + WL_DISPLAY_GLOBAL, + global->name, + global->interface->name, + global->interface->version); +} WL_EXPORT struct wl_display * wl_display_create(void) @@ -611,12 +614,9 @@ wl_display_create(void) display->client_id_range = 256; /* Gah, arbitrary... */ display->id = 1; - display->resource.object.interface = &wl_display_interface; - display->resource.object.implementation = - (void (**)(void)) &display_interface; - display->resource.data = display; - if (wl_display_add_global(display, &display->resource.object, NULL)) { + if (!wl_display_add_global(display, &wl_display_interface, + display, bind_display)) { wl_event_loop_destroy(display->loop); free(display); return NULL; @@ -646,46 +646,36 @@ wl_display_destroy(struct wl_display *display) free(display); } -WL_EXPORT int +WL_EXPORT struct wl_global * wl_display_add_global(struct wl_display *display, - struct wl_object *object, wl_global_bind_func_t bind) + const struct wl_interface *interface, + void *data, wl_global_bind_func_t bind) { struct wl_global *global; global = malloc(sizeof *global); if (global == NULL) - return -1; + return NULL; - object->id = display->id++; - global->object = object; + global->name = display->id++; + global->interface = interface; + global->data = data; global->bind = bind; wl_list_insert(display->global_list.prev, &global->link); - return 0; + return global; } -WL_EXPORT int -wl_display_remove_global(struct wl_display *display, - struct wl_object *object) +WL_EXPORT void +wl_display_remove_global(struct wl_display *display, struct wl_global *global) { - struct wl_global *global; struct wl_client *client; - wl_list_for_each(global, &display->global_list, link) - if (global->object == object) - break; - - if (&global->link == &display->global_list) - return -1; - wl_list_for_each(client, &display->client_list, link) - wl_resource_post_event(&client->display_resource, - WL_DISPLAY_GLOBAL_REMOVE, - global->object->id); + wl_resource_post_event(client->display_resource, + WL_DISPLAY_GLOBAL_REMOVE, global->name); wl_list_remove(&global->link); free(global); - - return 0; } WL_EXPORT struct wl_event_loop * @@ -845,30 +835,66 @@ wl_display_add_socket(struct wl_display *display, const char *name) return 0; } +WL_EXPORT struct wl_resource * +wl_client_add_object(struct wl_client *client, + const struct wl_interface *interface, + const void *implementation, + uint32_t id, void *data) +{ + struct wl_resource *resource; + + resource = malloc(sizeof *resource); + if (resource == NULL) { + wl_client_post_no_memory(client); + return NULL; + } + + resource->object.interface = interface; + resource->object.implementation = implementation; + resource->object.id = id; + resource->client = client; + resource->data = data; + resource->destroy = (void *) free; + wl_list_init(&resource->destroy_listener_list); + + wl_hash_table_insert(client->objects, resource->object.id, resource); + + return resource; +} + static void compositor_bind(struct wl_client *client, - struct wl_object *global, uint32_t version, uint32_t id) + void *data, uint32_t version, uint32_t id) { - struct wl_compositor *compositor = - container_of(global, struct wl_compositor, resource.object); + struct wl_compositor *compositor = data; + struct wl_resource *resource; - compositor->resource.client = client; - compositor->resource.object.id = id; + resource = wl_client_add_object(client, &wl_compositor_interface, + compositor->interface, id, compositor); - wl_resource_post_event(&compositor->resource, + wl_resource_post_event(resource, WL_COMPOSITOR_TOKEN_VISUAL, - &compositor->argb_visual.object, + compositor->argb_visual.name, WL_COMPOSITOR_VISUAL_ARGB32); - wl_resource_post_event(&compositor->resource, + wl_resource_post_event(resource, WL_COMPOSITOR_TOKEN_VISUAL, - &compositor->premultiplied_argb_visual.object, + compositor->premultiplied_argb_visual.name, WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32); - wl_resource_post_event(&compositor->resource, + wl_resource_post_event(resource, WL_COMPOSITOR_TOKEN_VISUAL, - &compositor->rgb_visual.object, + compositor->rgb_visual.name, WL_COMPOSITOR_VISUAL_XRGB32); + + wl_list_insert(client->resource_list.prev, &resource->link); +} + +static void +bind_visual(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + wl_client_add_object(client, &wl_visual_interface, NULL, id, data); } WL_EXPORT int @@ -876,33 +902,32 @@ wl_compositor_init(struct wl_compositor *compositor, const struct wl_compositor_interface *interface, struct wl_display *display) { - compositor->resource.object.interface = &wl_compositor_interface; - compositor->resource.object.implementation = - (void (**)(void)) interface; - compositor->resource.data = compositor; - if (wl_display_add_global(display, &compositor->resource.object, - compositor_bind)) + struct wl_global *global; + + compositor->interface = interface; + global = wl_display_add_global(display, &wl_compositor_interface, + compositor, compositor_bind); + if (!global) return -1; - compositor->argb_visual.object.interface = &wl_visual_interface; - compositor->argb_visual.object.implementation = NULL; - if (wl_display_add_global(display, - &compositor->argb_visual.object, NULL)) + global = wl_display_add_global(display, &wl_visual_interface, + &compositor->argb_visual, bind_visual); + if (!global) + return -1; + compositor->argb_visual.name = global->name; + + global = wl_display_add_global(display, &wl_visual_interface, + &compositor->premultiplied_argb_visual, + bind_visual); + if (!global) return -1; + compositor->premultiplied_argb_visual.name = global->name; - compositor->premultiplied_argb_visual.object.interface = - &wl_visual_interface; - compositor->premultiplied_argb_visual.object.implementation = NULL; - if (wl_display_add_global(display, - &compositor->premultiplied_argb_visual.object, - NULL)) - return -1; - - compositor->rgb_visual.object.interface = &wl_visual_interface; - compositor->rgb_visual.object.implementation = NULL; - if (wl_display_add_global(display, - &compositor->rgb_visual.object, NULL)) - return -1; + global = wl_display_add_global(display, &wl_visual_interface, + &compositor->rgb_visual, bind_visual); + if (!global) + return -1; + compositor->rgb_visual.name = global->name; return 0; } diff --git a/src/wayland-server.h b/src/wayland-server.h index 2ef4899..c2b2a17 100644 --- a/src/wayland-server.h +++ b/src/wayland-server.h @@ -85,25 +85,29 @@ void wl_display_run(struct wl_display *display); void wl_display_add_object(struct wl_display *display, struct wl_object *object); -typedef void (*wl_global_bind_func_t)(struct wl_client *client, - struct wl_object *global, +typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data, uint32_t version, uint32_t id); -int wl_display_add_global(struct wl_display *display, - struct wl_object *object, - wl_global_bind_func_t bind); +struct wl_global *wl_display_add_global(struct wl_display *display, + const struct wl_interface *interface, + void *data, + wl_global_bind_func_t bind); -int wl_display_remove_global(struct wl_display *display, - struct wl_object *object); +void wl_display_remove_global(struct wl_display *display, + struct wl_global *global); struct wl_client *wl_client_create(struct wl_display *display, int fd); void wl_client_destroy(struct wl_client *client); void wl_client_post_error(struct wl_client *client, struct wl_object *object, uint32_t code, const char *msg, ...); void wl_client_post_no_memory(struct wl_client *client); -void wl_client_post_global(struct wl_client *client, struct wl_object *object); void wl_client_flush(struct wl_client *client); +struct wl_resource * +wl_client_add_object(struct wl_client *client, + const struct wl_interface *interface, + const void *implementation, uint32_t id, void *data); + struct wl_resource { struct wl_object object; void (*destroy)(struct wl_resource *resource); @@ -115,6 +119,7 @@ struct wl_resource { struct wl_visual { struct wl_object object; + uint32_t name; }; struct wl_shm_callbacks { @@ -128,7 +133,7 @@ struct wl_shm_callbacks { }; struct wl_compositor { - struct wl_resource resource; + const struct wl_compositor_interface *interface; struct wl_visual argb_visual; struct wl_visual premultiplied_argb_visual; struct wl_visual rgb_visual; diff --git a/src/wayland-shm.c b/src/wayland-shm.c index f9ca327..0324168 100644 --- a/src/wayland-shm.c +++ b/src/wayland-shm.c @@ -34,7 +34,6 @@ #include "wayland-server.h" struct wl_shm { - struct wl_resource resource; const struct wl_shm_callbacks *callbacks; }; @@ -123,7 +122,7 @@ shm_create_buffer(struct wl_client *client, struct wl_resource *resource, void *data; if (!visual || visual->object.interface != &wl_visual_interface) { - wl_client_post_error(client, &shm->resource.object, + wl_client_post_error(client, &resource->object, WL_SHM_ERROR_INVALID_VISUAL, "invalid visual"); close(fd); @@ -131,7 +130,7 @@ shm_create_buffer(struct wl_client *client, struct wl_resource *resource, } if (width < 0 || height < 0 || stride < width) { - wl_client_post_error(client, &shm->resource.object, + wl_client_post_error(client, &resource->object, WL_SHM_ERROR_INVALID_STRIDE, "invalid width, height or stride (%dx%d, %u)", width, height, stride); @@ -144,7 +143,7 @@ shm_create_buffer(struct wl_client *client, struct wl_resource *resource, close(fd); if (data == MAP_FAILED) { - wl_client_post_error(client, &shm->resource.object, + wl_client_post_error(client, &resource->object, WL_SHM_ERROR_INVALID_FD, "failed mmap fd %d", fd); return; @@ -166,6 +165,13 @@ const static struct wl_shm_interface shm_interface = { shm_create_buffer }; +static void +bind_shm(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + wl_client_add_object(client, + &wl_shm_interface, &shm_interface, id, data); +} WL_EXPORT struct wl_shm * wl_shm_init(struct wl_display *display, @@ -177,10 +183,12 @@ wl_shm_init(struct wl_display *display, if (!shm) return NULL; - shm->resource.object.interface = &wl_shm_interface; - shm->resource.object.implementation = (void (**)(void)) &shm_interface; - shm->resource.data = shm; - wl_display_add_global(display, &shm->resource.object, NULL); + if (!wl_display_add_global(display, + &wl_shm_interface, shm, bind_shm)) { + + free(shm); + return NULL; + } shm->callbacks = callbacks; diff --git a/src/wayland-util.h b/src/wayland-util.h index f46da10..96dc74d 100644 --- a/src/wayland-util.h +++ b/src/wayland-util.h @@ -61,7 +61,7 @@ struct wl_interface { struct wl_object { const struct wl_interface *interface; - void (**implementation)(void); + void (* const * implementation)(void); uint32_t id; }; |