diff --git a/wayland/connection.c b/wayland/connection.c index b53c0a1..782dd9e 100644 --- a/wayland/connection.c +++ b/wayland/connection.c @@ -686,7 +686,7 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target) int i; fprintf(stderr, "%s@%d.%s(", - target->interface->name, target->id, + target->interface->signature->name, target->id, closure->message->name); for (i = 2; i < closure->count; i++) { @@ -707,7 +707,7 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target) case 'o': if (value->object) fprintf(stderr, "%s@%u", - value->object->interface->name, + value->object->interface->signature->name, value->object->id); else fprintf(stderr, "nil"); diff --git a/wayland/scanner.c b/wayland/scanner.c index b6aebdb..9dd0669 100644 --- a/wayland/scanner.c +++ b/wayland/scanner.c @@ -325,34 +325,16 @@ emit_stubs(struct wl_list *message_list, struct interface *interface) /* We provide a hand written constructor for the display object */ if (strcmp(interface->name, "wl_display") != 0) printf("static inline struct %s *\n" - "%s_create(struct wl_display *display, uint32_t id, uint32_t version)\n" + "%s_create(struct wl_display *display, struct %s_listener *listener, uint32_t id, void *data)\n" "{\n" - "\twl_display_bind(display, id, \"%s\", version);\n\n" "\treturn (struct %s *)\n" - "\t\twl_proxy_create_for_id(display, &%s_interface, id);\n" + "\t\twl_proxy_create_for_id(display, &listener->interface, id, data);\n" "}\n\n", interface->name, interface->name, interface->name, - interface->name, interface->name); - printf("static inline void\n" - "%s_set_user_data(struct %s *%s, void *user_data)\n" - "{\n" - "\twl_proxy_set_user_data((struct wl_proxy *) %s, user_data);\n" - "}\n\n", - interface->name, interface->name, interface->name, - interface->name); - - printf("static inline void *\n" - "%s_get_user_data(struct %s *%s)\n" - "{\n" - "\treturn wl_proxy_get_user_data((struct wl_proxy *) %s);\n" - "}\n\n", - interface->name, interface->name, interface->name, - interface->name); - has_destructor = 0; has_destroy = 0; wl_list_for_each(m, message_list, link) { @@ -493,12 +475,10 @@ emit_structs(struct wl_list *message_list, struct interface *interface) struct arg *a; int is_interface, n; - if (wl_list_empty(message_list)) - return; - is_interface = message_list == &interface->request_list; - printf("struct %s_%s {\n", interface->name, - is_interface ? "interface" : "listener"); + printf("struct %s_%s {\n" + "\tstruct wl_interface interface;\n", + interface->name, is_interface ? "interface" : "listener"); wl_list_for_each(m, message_list, link) { printf("\tvoid (*%s)(", m->name); @@ -526,21 +506,6 @@ emit_structs(struct wl_list *message_list, struct interface *interface) } printf("};\n\n"); - - if (!is_interface) { - printf("static inline int\n" - "%s_add_listener(struct %s *%s,\n" - "%sconst struct %s_listener *listener, void *data)\n" - "{\n" - "\treturn wl_proxy_add_listener((struct wl_proxy *) %s,\n" - "%s(void (**)(void)) listener, data);\n" - "}\n\n", - interface->name, interface->name, interface->name, - indent(17 + strlen(interface->name)), - interface->name, - interface->name, - indent(37)); - } } @@ -571,8 +536,8 @@ emit_header(struct protocol *protocol, int server) printf("\n"); wl_list_for_each(i, &protocol->interface_list, link) { - printf("extern const struct wl_interface " - "%s_interface;\n", + printf("extern const struct wl_signature " + "%s_signature;\n", i->name); } printf("\n"); @@ -662,8 +627,8 @@ emit_code(struct protocol *protocol) emit_messages(&i->request_list, i, "requests"); emit_messages(&i->event_list, i, "events"); - printf("WL_EXPORT const struct wl_interface " - "%s_interface = {\n" + printf("WL_EXPORT const struct wl_signature " + "%s_signature = {\n" "\t\"%s\", %d,\n", i->name, i->name, i->version); diff --git a/wayland/wayland-client.c b/wayland/wayland-client.c index 531807d..8b703b3 100644 --- a/wayland/wayland-client.c +++ b/wayland/wayland-client.c @@ -139,7 +139,7 @@ wl_display_remove_global_listener(struct wl_display *display, WL_EXPORT struct wl_proxy * wl_proxy_create_for_id(struct wl_display *display, - const struct wl_interface *interface, uint32_t id) + const struct wl_interface *interface, uint32_t id, void *data) { struct wl_proxy *proxy; @@ -148,9 +148,9 @@ wl_proxy_create_for_id(struct wl_display *display, return NULL; proxy->object.interface = interface; - proxy->object.implementation = NULL; proxy->object.id = id; proxy->display = display; + proxy->user_data = data; wl_hash_table_insert(display->objects, proxy->object.id, proxy); return proxy; @@ -158,10 +158,11 @@ wl_proxy_create_for_id(struct wl_display *display, WL_EXPORT struct wl_proxy * wl_proxy_create(struct wl_proxy *factory, - const struct wl_interface *interface) + const struct wl_interface *interface, void *data) { return wl_proxy_create_for_id(factory->display, interface, - wl_display_allocate_id(factory->display)); + wl_display_allocate_id(factory->display), + data); } WL_EXPORT void @@ -171,31 +172,18 @@ wl_proxy_destroy(struct wl_proxy *proxy) free(proxy); } -WL_EXPORT int -wl_proxy_add_listener(struct wl_proxy *proxy, - void (**implementation)(void), void *data) -{ - if (proxy->object.implementation) { - fprintf(stderr, "proxy already has listener\n"); - return -1; - } - - proxy->object.implementation = implementation; - proxy->user_data = data; - - return 0; -} - WL_EXPORT void wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...) { struct wl_closure *closure; + const struct wl_signature *signature; va_list ap; va_start(ap, opcode); + signature = proxy->object.interface->signature; closure = wl_connection_vmarshal(proxy->display->connection, &proxy->object, opcode, ap, - &proxy->object.interface->methods[opcode]); + &signature->methods[opcode]); va_end(ap); wl_closure_send(closure, proxy->display->connection); @@ -214,7 +202,8 @@ add_visual(struct wl_display *display, uint32_t id) struct wl_visual *visual; visual = (struct wl_visual *) - wl_proxy_create_for_id(display, &wl_visual_interface, id); + wl_proxy_create_for_id(display, + &wl_visual_interface, id, NULL); if (display->argb_visual == NULL) display->argb_visual = visual; else if (display->premultiplied_argb_visual == NULL) @@ -345,6 +334,7 @@ display_handle_key(void *data, } static const struct wl_display_listener display_listener = { + { &wl_display_signature }, display_handle_invalid_object, display_handle_invalid_method, display_handle_no_memory, @@ -435,17 +425,14 @@ wl_display_connect(const char *name) wl_list_init(&display->global_listener_list); wl_list_init(&display->global_list); - display->proxy.object.interface = &wl_display_interface; + display->proxy.object.interface = &display_listener.interface; display->proxy.object.id = 1; display->proxy.display = display; + display->proxy.user_data = display; wl_list_init(&display->sync_list); wl_list_init(&display->frame_list); - display->proxy.object.implementation = - (void(**)(void)) &display_listener; - display->proxy.user_data = display; - display->connection = wl_connection_create(display->fd, connection_update, display); @@ -532,6 +519,7 @@ handle_event(struct wl_display *display, struct wl_proxy *proxy; struct wl_closure *closure; const struct wl_message *message; + const struct wl_signature *signature; wl_connection_copy(display->connection, p, size); if (id == 1) @@ -539,12 +527,13 @@ handle_event(struct wl_display *display, else proxy = wl_hash_table_lookup(display->objects, id); - if (proxy == NULL || proxy->object.implementation == NULL) { + if (proxy == NULL) { wl_connection_consume(display->connection, size); return; } - message = &proxy->object.interface->events[opcode]; + signature = proxy->object.interface->signature; + message = &signature->events[opcode]; closure = wl_connection_demarshal(display->connection, size, display->objects, message); @@ -552,7 +541,7 @@ handle_event(struct wl_display *display, wl_closure_print(closure, &proxy->object); wl_closure_invoke(closure, &proxy->object, - proxy->object.implementation[opcode], + proxy->object.interface->funcs[opcode], proxy->user_data); wl_closure_destroy(closure); @@ -605,15 +594,3 @@ wl_display_allocate_id(struct wl_display *display) return display->id++; } - -WL_EXPORT void -wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data) -{ - proxy->user_data = user_data; -} - -WL_EXPORT void * -wl_proxy_get_user_data(struct wl_proxy *proxy) -{ - return proxy->user_data; -} diff --git a/wayland/wayland-client.h b/wayland/wayland-client.h index f1ac797..cd6e440 100644 --- a/wayland/wayland-client.h +++ b/wayland/wayland-client.h @@ -34,15 +34,13 @@ struct wl_display; void wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...); struct wl_proxy *wl_proxy_create(struct wl_proxy *factory, - const struct wl_interface *interface); + const struct wl_interface *interface, + void *data); struct wl_proxy *wl_proxy_create_for_id(struct wl_display *display, const struct wl_interface *interface, - uint32_t id); + uint32_t id, + void *data); void wl_proxy_destroy(struct wl_proxy *proxy); -int wl_proxy_add_listener(struct wl_proxy *proxy, - void (**implementation)(void), void *data); -void wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data); -void *wl_proxy_get_user_data(struct wl_proxy *proxy); #include "wayland-client-protocol.h" diff --git a/wayland/wayland-server.c b/wayland/wayland-server.c index daa6989..d5ac92d 100644 --- a/wayland/wayland-server.c +++ b/wayland/wayland-server.c @@ -95,12 +95,14 @@ wl_client_post_event(struct wl_client *client, struct wl_object *sender, uint32_t opcode, ...) { struct wl_closure *closure; + const struct wl_signature *signature; va_list ap; va_start(ap, opcode); + signature = sender->interface->signature; closure = wl_connection_vmarshal(client->connection, sender, opcode, ap, - &sender->interface->events[opcode]); + &signature->events[opcode]); va_end(ap); wl_closure_send(closure, client->connection); @@ -120,6 +122,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) struct wl_connection *connection = client->connection; struct wl_object *object; struct wl_closure *closure; + const struct wl_signature *signature; const struct wl_message *message; uint32_t p[2], opcode, size; uint32_t cmask = 0; @@ -152,7 +155,8 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) continue; } - if (opcode >= object->interface->method_count) { + signature = object->interface->signature; + if (opcode >= signature->method_count) { wl_client_post_event(client, &client->display->object, WL_DISPLAY_INVALID_METHOD, p[0], opcode); wl_connection_consume(connection, size); @@ -160,7 +164,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) continue; } - message = &object->interface->methods[opcode]; + message = &signature->methods[opcode]; closure = wl_connection_demarshal(client->connection, size, client->display->objects, message); @@ -181,7 +185,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) wl_closure_print(closure, object); wl_closure_invoke(closure, object, - object->implementation[opcode], client); + object->interface->funcs[opcode], client); wl_closure_destroy(closure); } @@ -276,12 +280,15 @@ wl_client_post_no_memory(struct wl_client *client) WL_EXPORT void wl_client_post_global(struct wl_client *client, struct wl_object *object) { + const struct wl_signature *signature; + + signature = object->interface->signature; wl_client_post_event(client, &client->display->object, WL_DISPLAY_GLOBAL, object, - object->interface->name, - object->interface->version); + signature->name, + signature->version); } WL_EXPORT void @@ -524,6 +531,7 @@ display_frame(struct wl_client *client, } struct wl_display_interface display_interface = { + { &wl_display_signature }, display_bind, display_sync, display_frame @@ -562,12 +570,10 @@ wl_display_create(void) wl_list_init(&display->socket_list); 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)) { + + if (wl_display_add_global(display, &display->object, + &display_interface.interface, NULL)) { wl_hash_table_destroy(display->objects); wl_event_loop_destroy(display->loop); free(display); @@ -597,15 +603,18 @@ wl_display_destroy(struct wl_display *display) } WL_EXPORT void -wl_display_add_object(struct wl_display *display, struct wl_object *object) +wl_display_add_object(struct wl_display *display, struct wl_object *object, + const struct wl_interface *interface) { + object->interface = interface; object->id = display->id++; wl_hash_table_insert(display->objects, object->id, object); } WL_EXPORT int -wl_display_add_global(struct wl_display *display, - struct wl_object *object, wl_global_bind_func_t func) +wl_display_add_global(struct wl_display *display, struct wl_object *object, + const struct wl_interface *interface, + wl_global_bind_func_t func) { struct wl_global *global; @@ -613,6 +622,7 @@ wl_display_add_global(struct wl_display *display, if (global == NULL) return -1; + wl_display_add_object(display, object, interface); global->object = object; global->func = func; wl_list_insert(display->global_list.prev, &global->link); @@ -786,39 +796,30 @@ wl_display_add_socket(struct wl_display *display, const char *name) return 0; } +static const struct wl_interface visual_interface = { + &wl_visual_signature +}; + WL_EXPORT int 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, NULL)) + if (wl_display_add_global(display, &compositor->object, + &interface->interface, NULL)) return -1; - compositor->argb_visual.object.interface = &wl_visual_interface; - compositor->argb_visual.object.implementation = NULL; - wl_display_add_object(display, &compositor->argb_visual.object); - if (wl_display_add_global(display, &compositor->argb_visual.object, NULL)) + if (wl_display_add_global(display, &compositor->argb_visual.object, + &visual_interface, NULL)) return -1; - compositor->premultiplied_argb_visual.object.interface = - &wl_visual_interface; - compositor->premultiplied_argb_visual.object.implementation = NULL; - wl_display_add_object(display, - &compositor->premultiplied_argb_visual.object); if (wl_display_add_global(display, &compositor->premultiplied_argb_visual.object, - NULL)) + &visual_interface, NULL)) return -1; - compositor->rgb_visual.object.interface = &wl_visual_interface; - compositor->rgb_visual.object.implementation = NULL; - wl_display_add_object(display, - &compositor->rgb_visual.object); - if (wl_display_add_global(display, - &compositor->rgb_visual.object, NULL)) + if (wl_display_add_global(display, &compositor->rgb_visual.object, + &visual_interface, NULL)) return -1; return 0; diff --git a/wayland/wayland-server.h b/wayland/wayland-server.h index 649bb6b..414ceff 100644 --- a/wayland/wayland-server.h +++ b/wayland/wayland-server.h @@ -83,14 +83,16 @@ void wl_display_terminate(struct wl_display *display); void wl_display_run(struct wl_display *display); void wl_display_add_object(struct wl_display *display, - struct wl_object *object); + struct wl_object *object, + const struct wl_interface *interface); typedef void (*wl_global_bind_func_t)(struct wl_client *client, struct wl_object *global, uint32_t version); int wl_display_add_global(struct wl_display *display, - struct wl_object *object, + struct wl_object *object, + const struct wl_interface *interface, wl_global_bind_func_t func); struct wl_client *wl_client_create(struct wl_display *display, int fd); diff --git a/wayland/wayland-shm.c b/wayland/wayland-shm.c index 5f46293..36df029 100644 --- a/wayland/wayland-shm.c +++ b/wayland/wayland-shm.c @@ -75,6 +75,7 @@ shm_buffer_destroy(struct wl_client *client, struct wl_buffer *buffer) } const static struct wl_buffer_interface shm_buffer_interface = { + { &wl_buffer_signature }, shm_buffer_damage, shm_buffer_destroy }; @@ -98,10 +99,7 @@ wl_shm_buffer_init(struct wl_shm *shm, uint32_t id, buffer->data = data; buffer->buffer.resource.object.id = id; - buffer->buffer.resource.object.interface = &wl_buffer_interface; - buffer->buffer.resource.object.implementation = (void (**)(void)) - &shm_buffer_interface; - + buffer->buffer.resource.object.interface = &shm_buffer_interface.interface; buffer->buffer.resource.destroy = destroy_buffer; buffer->shm = shm; @@ -123,7 +121,7 @@ shm_create_buffer(struct wl_client *client, struct wl_shm *shm, /* FIXME: Define a real exception event instead of abusing the * display.invalid_object error */ - if (visual->object.interface != &wl_visual_interface) { + if (visual->object.interface->signature != &wl_visual_signature) { wl_client_post_event(client, (struct wl_object *) display, WL_DISPLAY_INVALID_OBJECT, 0); fprintf(stderr, "invalid visual in create_buffer\n"); @@ -166,6 +164,7 @@ shm_create_buffer(struct wl_client *client, struct wl_shm *shm, } const static struct wl_shm_interface shm_interface = { + { &wl_shm_signature }, shm_create_buffer }; @@ -180,10 +179,8 @@ 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); + wl_display_add_global(display, &shm->object, + &shm_interface.interface, NULL); shm->callbacks = callbacks; @@ -201,8 +198,8 @@ wl_shm_finish(struct wl_shm *shm) WL_EXPORT int wl_buffer_is_shm(struct wl_buffer *buffer) { - return buffer->resource.object.implementation == - (void (**)(void)) &shm_buffer_interface; + return buffer->resource.object.interface == + &shm_buffer_interface.interface; } WL_EXPORT int32_t diff --git a/wayland/wayland-util.h b/wayland/wayland-util.h index 6c1231a..6114c5a 100644 --- a/wayland/wayland-util.h +++ b/wayland/wayland-util.h @@ -55,7 +55,7 @@ struct wl_message { const void **types; }; -struct wl_interface { +struct wl_signature { const char *name; int version; int method_count; @@ -64,9 +64,13 @@ struct wl_interface { const struct wl_message *events; }; +struct wl_interface { + const struct wl_signature *signature; + void *funcs[0]; +}; + struct wl_object { const struct wl_interface *interface; - void (**implementation)(void); uint32_t id; };