From e8a192ca616107dcb672b34d0c80f2de679bcd0a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 18 Aug 2011 17:53:50 -0400 Subject: [PATCH] server: Make everything in the object hash a wl_resource --- src/scanner.c | 8 +- src/wayland-server.c | 222 ++++++++++++++++++++++++++++++--------------------- src/wayland-server.h | 37 +++++---- src/wayland-shm.c | 35 ++++---- 4 files changed, 170 insertions(+), 132 deletions(-) diff --git a/src/scanner.c b/src/scanner.c index 9584046..7e4bac6 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -527,9 +527,8 @@ emit_structs(struct wl_list *message_list, struct interface *interface) n = strlen(m->name) + 17; if (is_interface) { printf("struct wl_client *client,\n" - "%sstruct %s *%s", - indent(n), - interface->name, interface->name); + "%sstruct wl_resource *resource", + indent(n)); } else { printf("void *data,\n"), printf("%sstruct %s *%s", @@ -606,7 +605,8 @@ emit_header(struct protocol *protocol, int server) "#include \n" "#include \n" "#include \"wayland-util.h\"\n\n" - "struct wl_client;\n\n", + "struct wl_client;\n" + "struct wl_resource;\n\n", protocol->uppercase_name, s, protocol->uppercase_name, s); diff --git a/src/wayland-server.c b/src/wayland-server.c index c6ec2f1..c3f30d6 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -57,6 +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_list resource_list; uint32_t id_count; uint32_t mask; @@ -64,7 +65,7 @@ struct wl_client { }; struct wl_display { - struct wl_object object; + struct wl_resource resource; struct wl_event_loop *loop; struct wl_hash_table *objects; int run; @@ -87,22 +88,22 @@ struct wl_global { static int wl_debug = 0; WL_EXPORT void -wl_client_post_event(struct wl_client *client, struct wl_object *sender, - uint32_t opcode, ...) +wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...) { struct wl_closure *closure; + struct wl_object *object = &resource->object; va_list ap; va_start(ap, opcode); - closure = wl_connection_vmarshal(client->connection, - sender, opcode, ap, - &sender->interface->events[opcode]); + closure = wl_connection_vmarshal(resource->client->connection, + object, opcode, ap, + &object->interface->events[opcode]); va_end(ap); - wl_closure_send(closure, client->connection); + wl_closure_send(closure, resource->client->connection); if (wl_debug) - wl_closure_print(closure, sender, true); + wl_closure_print(closure, object, true); wl_closure_destroy(closure); } @@ -118,8 +119,8 @@ wl_client_post_error(struct wl_client *client, struct wl_object *object, vsnprintf(buffer, sizeof buffer, msg, ap); va_end(ap); - wl_client_post_event(client, &client->display->object, - WL_DISPLAY_ERROR, object, code, buffer); + wl_resource_post_event(&client->display_resource, + WL_DISPLAY_ERROR, object, code, buffer); } static int @@ -127,6 +128,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) { struct wl_client *client = data; struct wl_connection *connection = client->connection; + struct wl_resource *resource; struct wl_object *object; struct wl_closure *closure; const struct wl_message *message; @@ -152,9 +154,10 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) if (len < size) break; - object = wl_hash_table_lookup(client->display->objects, p[0]); - if (object == NULL) { - wl_client_post_error(client, &client->display->object, + resource = wl_hash_table_lookup(client->display->objects, p[0]); + if (resource == NULL) { + wl_client_post_error(client, + &client->display->resource.object, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid object %d", p[0]); wl_connection_consume(connection, size); @@ -162,8 +165,10 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) continue; } + object = &resource->object; if (opcode >= object->interface->method_count) { - wl_client_post_error(client, &client->display->object, + wl_client_post_error(client, + &client->display->resource.object, WL_DISPLAY_ERROR_INVALID_METHOD, "invalid method %d, object %s@%d", object->interface->name, @@ -180,11 +185,13 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) len -= size; if (closure == NULL && errno == EINVAL) { - wl_client_post_error(client, &client->display->object, + wl_client_post_error(client, + &client->display->resource.object, WL_DISPLAY_ERROR_INVALID_METHOD, "invalid arguments for %s@%d.%s", object->interface->name, - object->id, message->name); + object->id, + message->name); continue; } else if (closure == NULL && errno == ENOMEM) { wl_client_post_no_memory(client); @@ -193,7 +200,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) if (wl_debug) - wl_closure_print(closure, object, false); + wl_closure_print(closure, object, false); wl_closure_invoke(closure, object, object->implementation[opcode], client); @@ -236,8 +243,8 @@ wl_client_get_display(struct wl_client *client) static void wl_display_post_range(struct wl_display *display, struct wl_client *client) { - wl_client_post_event(client, &client->display->object, - WL_DISPLAY_RANGE, display->client_id_range); + wl_resource_post_event(&client->display_resource, + WL_DISPLAY_RANGE, display->client_id_range); display->client_id_range += 256; client->id_count += 256; } @@ -264,6 +271,9 @@ wl_client_create(struct wl_display *display, int fd) return NULL; } + client->display_resource.object = display->resource.object; + client->display_resource.client = client; + wl_list_insert(display->client_list.prev, &client->link); wl_list_init(&client->resource_list); @@ -285,6 +295,7 @@ wl_client_add_resource(struct wl_client *client, if (client->id_count-- < 64) wl_display_post_range(display, client); + resource->client = client; wl_list_init(&resource->destroy_listener_list); wl_hash_table_insert(client->display->objects, @@ -295,36 +306,33 @@ wl_client_add_resource(struct wl_client *client, WL_EXPORT void wl_client_post_no_memory(struct wl_client *client) { - wl_client_post_error(client, &client->display->object, + wl_client_post_error(client, &client->display->resource.object, WL_DISPLAY_ERROR_NO_MEMORY, "no memory"); } WL_EXPORT void wl_client_post_global(struct wl_client *client, struct wl_object *object) { - wl_client_post_event(client, - &client->display->object, - WL_DISPLAY_GLOBAL, - object->id, - object->interface->name, - object->interface->version); + 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, - struct wl_client *client, uint32_t time) +wl_resource_destroy(struct wl_resource *resource, uint32_t time) { - struct wl_display *display = client->display; + struct wl_display *display = resource->client->display; struct wl_listener *l, *next; - wl_list_for_each_safe(l, next, - &resource->destroy_listener_list, link) + wl_list_for_each_safe(l, next, &resource->destroy_listener_list, link) l->func(l, resource, time); wl_list_remove(&resource->link); if (resource->object.id > 0) wl_hash_table_remove(display->objects, resource->object.id); - resource->destroy(resource, client); + resource->destroy(resource); } WL_EXPORT void @@ -335,7 +343,7 @@ wl_client_destroy(struct wl_client *client) printf("disconnect from client %p\n", client); wl_list_for_each_safe(resource, tmp, &client->resource_list, link) - wl_resource_destroy(resource, client, 0); + wl_resource_destroy(resource, 0); wl_event_source_remove(client->source); wl_connection_destroy(client->connection); @@ -369,9 +377,9 @@ WL_EXPORT void wl_input_device_init(struct wl_input_device *device, struct wl_compositor *compositor) { - wl_list_init(&device->pointer_focus_listener.link); + memset(device, 0, sizeof *device); + wl_list_init(&device->resource_list); device->pointer_focus_listener.func = lose_pointer_focus; - wl_list_init(&device->keyboard_focus_listener.link); device->keyboard_focus_listener.func = lose_keyboard_focus; device->x = 100; @@ -379,6 +387,22 @@ wl_input_device_init(struct wl_input_device *device, device->compositor = compositor; } +static struct wl_resource * +find_resource_for_surface(struct wl_list *list, struct wl_surface *surface) +{ + struct wl_resource *r; + + if (!surface) + return NULL; + + wl_list_for_each(r, list, link) { + if (r->client == surface->resource.client) + return r; + } + + return NULL; +} + WL_EXPORT void wl_input_device_set_pointer_focus(struct wl_input_device *device, struct wl_surface *surface, @@ -386,30 +410,32 @@ wl_input_device_set_pointer_focus(struct wl_input_device *device, int32_t x, int32_t y, int32_t sx, int32_t sy) { + struct wl_resource *resource; + if (device->pointer_focus == surface) return; - if (device->pointer_focus && - (!surface || device->pointer_focus->client != surface->client)) - wl_client_post_event(device->pointer_focus->client, - &device->object, - WL_INPUT_DEVICE_POINTER_FOCUS, - time, NULL, 0, 0, 0, 0); - if (device->pointer_focus) + if (device->pointer_focus_resource && + (!surface || + device->pointer_focus->resource.client != surface->resource.client)) + wl_resource_post_event(device->pointer_focus_resource, + WL_INPUT_DEVICE_POINTER_FOCUS, + time, NULL, 0, 0, 0, 0); + if (device->pointer_focus_resource) wl_list_remove(&device->pointer_focus_listener.link); - if (surface) { - wl_client_post_event(surface->client, - &device->object, - WL_INPUT_DEVICE_POINTER_FOCUS, - time, surface, x, y, sx, sy); + resource = find_resource_for_surface(&device->resource_list, surface); + if (resource) { + wl_resource_post_event(resource, + WL_INPUT_DEVICE_POINTER_FOCUS, + time, surface, x, y, sx, sy); wl_list_insert(surface->resource.destroy_listener_list.prev, &device->pointer_focus_listener.link); } + device->pointer_focus_resource = resource; device->pointer_focus = surface; device->pointer_focus_time = time; - } WL_EXPORT void @@ -417,27 +443,30 @@ wl_input_device_set_keyboard_focus(struct wl_input_device *device, struct wl_surface *surface, uint32_t time) { + struct wl_resource *resource; + if (device->keyboard_focus == surface) return; - if (device->keyboard_focus && - (!surface || device->keyboard_focus->client != surface->client)) - wl_client_post_event(device->keyboard_focus->client, - &device->object, - WL_INPUT_DEVICE_KEYBOARD_FOCUS, - time, NULL, &device->keys); - if (device->keyboard_focus) + if (device->keyboard_focus_resource && + (!surface || + device->keyboard_focus->resource.client != surface->resource.client)) + wl_resource_post_event(device->keyboard_focus_resource, + WL_INPUT_DEVICE_KEYBOARD_FOCUS, + time, NULL, &device->keys); + if (device->keyboard_focus_resource) wl_list_remove(&device->keyboard_focus_listener.link); - if (surface) { - wl_client_post_event(surface->client, - &device->object, - WL_INPUT_DEVICE_KEYBOARD_FOCUS, - time, surface, &device->keys); + resource = find_resource_for_surface(&device->resource_list, surface); + if (resource) { + wl_resource_post_event(resource, + WL_INPUT_DEVICE_KEYBOARD_FOCUS, + time, surface, &device->keys); wl_list_insert(surface->resource.destroy_listener_list.prev, &device->keyboard_focus_listener.link); } + device->keyboard_focus_resource = resource; device->keyboard_focus = surface; device->keyboard_focus_time = time; } @@ -504,17 +533,18 @@ wl_input_device_update_grab(struct wl_input_device *device, static void display_bind(struct wl_client *client, - struct wl_display *display, uint32_t id, + struct wl_resource *resource, uint32_t id, const char *interface, uint32_t version) { struct wl_global *global; + struct wl_display *display = resource->data; wl_list_for_each(global, &display->global_list, link) if (global->object->id == id) break; if (&global->link == &display->global_list) - wl_client_post_error(client, &client->display->object, + wl_client_post_error(client, &client->display->resource.object, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid object %d", id); else if (global->func) @@ -523,14 +553,15 @@ display_bind(struct wl_client *client, static void display_sync(struct wl_client *client, - struct wl_display *display, uint32_t id) + struct wl_resource *resource, uint32_t id) { - struct wl_object object; + struct wl_resource callback; - object.interface = &wl_callback_interface; - object.id = id; + callback.object.interface = &wl_callback_interface; + callback.object.id = id; + callback.client = client; - wl_client_post_event(client, &object, WL_CALLBACK_DONE, 0); + wl_resource_post_event(&callback, WL_CALLBACK_DONE, 0); } struct wl_display_interface display_interface = { @@ -574,10 +605,13 @@ wl_display_create(void) display->client_id_range = 256; /* Gah, arbitrary... */ display->id = 1; - display->object.interface = &wl_display_interface; - display->object.implementation = (void (**)(void)) &display_interface; - wl_display_add_object(display, &display->object); - if (wl_display_add_global(display, &display->object, NULL)) { + display->resource.object.interface = &wl_display_interface; + display->resource.object.implementation = + (void (**)(void)) &display_interface; + display->resource.data = display; + + wl_display_add_object(display, &display->resource.object); + if (wl_display_add_global(display, &display->resource.object, NULL)) { wl_hash_table_destroy(display->objects); wl_event_loop_destroy(display->loop); free(display); @@ -648,10 +682,9 @@ wl_display_remove_global(struct wl_display *display, return -1; wl_list_for_each(client, &display->client_list, link) - wl_client_post_event(client, - &client->display->object, - WL_DISPLAY_GLOBAL_REMOVE, - global->object->id); + wl_resource_post_event(&client->display_resource, + WL_DISPLAY_GLOBAL_REMOVE, + global->object->id); wl_list_remove(&global->link); free(global); @@ -820,22 +853,23 @@ compositor_bind(struct wl_client *client, struct wl_object *global, uint32_t version) { struct wl_compositor *compositor = - container_of(global, struct wl_compositor, object); + container_of(global, struct wl_compositor, resource.object); - wl_client_post_event(client, global, - WL_COMPOSITOR_TOKEN_VISUAL, - &compositor->argb_visual.object, - WL_COMPOSITOR_VISUAL_ARGB32); + compositor->resource.client = client; + wl_resource_post_event(&compositor->resource, + WL_COMPOSITOR_TOKEN_VISUAL, + &compositor->argb_visual.object, + WL_COMPOSITOR_VISUAL_ARGB32); - wl_client_post_event(client, global, - WL_COMPOSITOR_TOKEN_VISUAL, - &compositor->premultiplied_argb_visual.object, - WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32); + wl_resource_post_event(&compositor->resource, + WL_COMPOSITOR_TOKEN_VISUAL, + &compositor->premultiplied_argb_visual.object, + WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32); - wl_client_post_event(client, global, - WL_COMPOSITOR_TOKEN_VISUAL, - &compositor->rgb_visual.object, - WL_COMPOSITOR_VISUAL_XRGB32); + wl_resource_post_event(&compositor->resource, + WL_COMPOSITOR_TOKEN_VISUAL, + &compositor->rgb_visual.object, + WL_COMPOSITOR_VISUAL_XRGB32); } WL_EXPORT int @@ -843,11 +877,13 @@ wl_compositor_init(struct wl_compositor *compositor, const struct wl_compositor_interface *interface, struct wl_display *display) { - compositor->object.interface = &wl_compositor_interface; - compositor->object.implementation = (void (**)(void)) interface; - wl_display_add_object(display, &compositor->object); - if (wl_display_add_global(display, - &compositor->object, compositor_bind)) + compositor->resource.object.interface = &wl_compositor_interface; + compositor->resource.object.implementation = + (void (**)(void)) interface; + compositor->resource.data = compositor; + wl_display_add_object(display, &compositor->resource.object); + if (wl_display_add_global(display, &compositor->resource.object, + compositor_bind)) return -1; compositor->argb_visual.object.interface = &wl_visual_interface; diff --git a/src/wayland-server.h b/src/wayland-server.h index 69d0d51..e1a9b7a 100644 --- a/src/wayland-server.h +++ b/src/wayland-server.h @@ -104,6 +104,15 @@ 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 { + struct wl_object object; + void (*destroy)(struct wl_resource *resource); + struct wl_list link; + struct wl_list destroy_listener_list; + struct wl_client *client; + void *data; +}; + struct wl_visual { struct wl_object object; }; @@ -119,23 +128,14 @@ struct wl_shm_callbacks { }; struct wl_compositor { - struct wl_object object; + struct wl_resource resource; struct wl_visual argb_visual; struct wl_visual premultiplied_argb_visual; struct wl_visual rgb_visual; }; -struct wl_resource { - struct wl_object object; - void (*destroy)(struct wl_resource *resource, - struct wl_client *client); - struct wl_list link; - struct wl_list destroy_listener_list; -}; - struct wl_buffer { struct wl_resource resource; - struct wl_client *client; struct wl_visual *visual; int32_t width, height; uint32_t busy_count; @@ -150,7 +150,6 @@ struct wl_listener { struct wl_surface { struct wl_resource resource; - struct wl_client *client; }; struct wl_grab; @@ -168,9 +167,12 @@ struct wl_grab { }; struct wl_input_device { - struct wl_object object; + struct wl_resource resource; + struct wl_list resource_list; struct wl_compositor *compositor; + struct wl_resource *pointer_focus_resource; struct wl_surface *pointer_focus; + struct wl_resource *keyboard_focus_resource; struct wl_surface *keyboard_focus; struct wl_array keys; uint32_t pointer_focus_time; @@ -188,7 +190,7 @@ struct wl_input_device { }; struct wl_drag_offer { - struct wl_object object; + struct wl_resource resource; }; struct wl_drag { @@ -206,7 +208,7 @@ struct wl_drag { }; struct wl_selection_offer { - struct wl_object object; + struct wl_resource resource; }; struct wl_selection { @@ -221,9 +223,7 @@ struct wl_selection { }; void -wl_client_post_event(struct wl_client *client, - struct wl_object *sender, - uint32_t event, ...); +wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...); int wl_display_set_compositor(struct wl_display *display, @@ -242,8 +242,7 @@ struct wl_display * wl_client_get_display(struct wl_client *client); void -wl_resource_destroy(struct wl_resource *resource, - struct wl_client *client, uint32_t time); +wl_resource_destroy(struct wl_resource *resource, uint32_t time); void wl_input_device_init(struct wl_input_device *device, diff --git a/src/wayland-shm.c b/src/wayland-shm.c index 90d2fcf..8f1d0df 100644 --- a/src/wayland-shm.c +++ b/src/wayland-shm.c @@ -34,7 +34,7 @@ #include "wayland-server.h" struct wl_shm { - struct wl_object object; + struct wl_resource resource; const struct wl_shm_callbacks *callbacks; }; @@ -46,7 +46,7 @@ struct wl_shm_buffer { }; static void -destroy_buffer(struct wl_resource *resource, struct wl_client *client) +destroy_buffer(struct wl_resource *resource) { struct wl_shm_buffer *buffer = container_of(resource, struct wl_shm_buffer, buffer.resource); @@ -59,19 +59,19 @@ destroy_buffer(struct wl_resource *resource, struct wl_client *client) } static void -shm_buffer_damage(struct wl_client *client, struct wl_buffer *buffer_base, +shm_buffer_damage(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) { - struct wl_shm_buffer *buffer = (struct wl_shm_buffer *) buffer_base; + struct wl_shm_buffer *buffer = resource->data; - buffer->shm->callbacks->buffer_damaged(buffer_base, x, y, + buffer->shm->callbacks->buffer_damaged(&buffer->buffer, x, y, width, height); } static void -shm_buffer_destroy(struct wl_client *client, struct wl_buffer *buffer) +shm_buffer_destroy(struct wl_client *client, struct wl_resource *resource) { - wl_resource_destroy(&buffer->resource, client, 0); + wl_resource_destroy(resource, 0); } const static struct wl_buffer_interface shm_buffer_interface = { @@ -94,7 +94,6 @@ wl_shm_buffer_init(struct wl_shm *shm, struct wl_client *client, uint32_t id, buffer->buffer.width = width; buffer->buffer.height = height; buffer->buffer.visual = visual; - buffer->buffer.client = client; buffer->stride = stride; buffer->data = data; @@ -103,6 +102,8 @@ wl_shm_buffer_init(struct wl_shm *shm, struct wl_client *client, uint32_t id, buffer->buffer.resource.object.implementation = (void (**)(void)) &shm_buffer_interface; + buffer->buffer.resource.data = buffer; + buffer->buffer.resource.client = client; buffer->buffer.resource.destroy = destroy_buffer; buffer->shm = shm; @@ -113,15 +114,16 @@ wl_shm_buffer_init(struct wl_shm *shm, struct wl_client *client, uint32_t id, } static void -shm_create_buffer(struct wl_client *client, struct wl_shm *shm, +shm_create_buffer(struct wl_client *client, struct wl_resource *resource, uint32_t id, int fd, int32_t width, int32_t height, uint32_t stride, struct wl_visual *visual) { + struct wl_shm *shm = resource->data; struct wl_shm_buffer *buffer; void *data; if (!visual || visual->object.interface != &wl_visual_interface) { - wl_client_post_error(client, &shm->object, + wl_client_post_error(client, &shm->resource.object, WL_SHM_ERROR_INVALID_VISUAL, "invalid visual"); close(fd); @@ -129,7 +131,7 @@ shm_create_buffer(struct wl_client *client, struct wl_shm *shm, } if (width < 0 || height < 0 || stride < width) { - wl_client_post_error(client, &shm->object, + wl_client_post_error(client, &shm->resource.object, WL_SHM_ERROR_INVALID_STRIDE, "invalid width, height or stride (%dx%d, %u)", width, height, stride); @@ -142,7 +144,7 @@ shm_create_buffer(struct wl_client *client, struct wl_shm *shm, close(fd); if (data == MAP_FAILED) { - wl_client_post_error(client, &shm->object, + wl_client_post_error(client, &shm->resource.object, WL_SHM_ERROR_INVALID_FD, "failed mmap fd %d", fd); return; @@ -175,10 +177,11 @@ wl_shm_init(struct wl_display *display, if (!shm) return NULL; - shm->object.interface = &wl_shm_interface; - shm->object.implementation = (void (**)(void)) &shm_interface; - wl_display_add_object(display, &shm->object); - wl_display_add_global(display, &shm->object, NULL); + shm->resource.object.interface = &wl_shm_interface; + shm->resource.object.implementation = (void (**)(void)) &shm_interface; + shm->resource.data = shm; + wl_display_add_object(display, &shm->resource.object); + wl_display_add_global(display, &shm->resource.object, NULL); shm->callbacks = callbacks; -- 2.7.4