diff --git a/TODO b/TODO index 56bb8e60..77a7bddf 100644 --- a/TODO +++ b/TODO @@ -3,9 +3,6 @@ Core wayland protocol - generate pointer_focus on raise/lower, move windows, all kinds of changes in surface stacking. - - don't store globals on client side, require global_handler like - everything else. - - glyph cache - dnd, figure out large object transfer: through wayland protocol or diff --git a/clients/screenshot.c b/clients/screenshot.c index 2ae38a7a..4891fd79 100644 --- a/clients/screenshot.c +++ b/clients/screenshot.c @@ -36,45 +36,36 @@ static const char socket_name[] = "\0wayland"; -struct screenshooter { - uint32_t id; - struct wl_display *display; -}; - -static struct screenshooter * -screenshooter_create(struct wl_display *display) -{ - struct screenshooter *screenshooter; - uint32_t id; +#define SCREENSHOOTER_SHOOT 0 - id = wl_display_get_object_id(display, "screenshooter", 1); - if (id == 0) { - fprintf(stderr, "server doesn't support screenshooter interface\n"); - return NULL; - } +struct screenshooter; - screenshooter = malloc(sizeof screenshooter); - if (screenshooter == NULL) - return NULL; +static const struct wl_message screenshooter_requests[] = { + { "shoot", "" }, +}; - screenshooter->id = id; - screenshooter->display = display; +static const struct wl_interface screenshooter_interface = { + "screenshooter", 1, + ARRAY_LENGTH(screenshooter_requests), screenshooter_requests, + 0, NULL +}; - return screenshooter; +static inline void +screenshooter_shoot(struct screenshooter *shooter) +{ + wl_proxy_marshal((struct wl_proxy *) shooter, SCREENSHOOTER_SHOOT); } -#define SCREENSHOOTER_SHOOT 0 - static void -screenshooter_shoot(struct screenshooter *screenshooter) +handle_global(struct wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data) { - uint32_t request[2]; - - request[0] = screenshooter->id; - request[1] = SCREENSHOOTER_SHOOT | ((sizeof request) << 16); + struct screenshooter **screenshooter = data; - wl_display_write(screenshooter->display, - request, sizeof request); + if (strcmp(interface, "screenshooter") == 0) + *screenshooter = (struct screenshooter *) + wl_proxy_create_for_id(display, + &screenshooter_interface, id); } int main(int argc, char *argv[]) @@ -82,7 +73,7 @@ int main(int argc, char *argv[]) struct wl_display *display; GMainLoop *loop; GSource *source; - struct screenshooter *s; + struct screenshooter *screenshooter; display = wl_display_create(socket_name, sizeof socket_name); if (display == NULL) { @@ -90,16 +81,20 @@ int main(int argc, char *argv[]) return -1; } + screenshooter = NULL; + wl_display_add_global_listener(display, handle_global, &screenshooter); wl_display_iterate(display, WL_DISPLAY_READABLE); + if (screenshooter == NULL) { + fprintf(stderr, "display doesn't support screenshooter\n"); + return -1; + } + loop = g_main_loop_new(NULL, FALSE); source = wl_glib_source_new(display); g_source_attach(source, NULL); - s = screenshooter_create(display); - if (s == NULL) - exit(-1); + screenshooter_shoot(screenshooter); - screenshooter_shoot(s); g_idle_add((GSourceFunc) g_main_loop_quit, loop); g_main_loop_run(loop); diff --git a/clients/window.c b/clients/window.c index c41d2f59..00f49e20 100644 --- a/clients/window.c +++ b/clients/window.c @@ -766,7 +766,7 @@ static const struct wl_output_listener output_listener = { }; static void -display_add_input(struct display *d, struct wl_object *object) +display_add_input(struct display *d, uint32_t id) { struct input *input; @@ -776,7 +776,7 @@ display_add_input(struct display *d, struct wl_object *object) memset(input, 0, sizeof *input); input->display = d; - input->input_device = (struct wl_input_device *) object; + input->input_device = wl_input_device_create(d->display, id); input->pointer_focus = NULL; input->keyboard_focus = NULL; wl_list_insert(d->input_list.prev, &input->link); @@ -786,24 +786,25 @@ display_add_input(struct display *d, struct wl_object *object) } static void -display_handle_global(struct wl_display *display, - struct wl_object *object, void *data) +display_handle_global(struct wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data) { struct display *d = data; - if (wl_object_implements(object, "compositor", 1)) { - d->compositor = (struct wl_compositor *) object; - wl_compositor_add_listener(d->compositor, &compositor_listener, d); - } else if (wl_object_implements(object, "output", 1)) { - d->output = (struct wl_output *) object; + if (strcmp(interface, "compositor") == 0) { + d->compositor = wl_compositor_create(display, id); + wl_compositor_add_listener(d->compositor, + &compositor_listener, d); + } else if (strcmp(interface, "output") == 0) { + d->output = wl_output_create(display, id); wl_output_add_listener(d->output, &output_listener, d); - } else if (wl_object_implements(object, "input_device", 1)) { - display_add_input(d, object); - } else if (wl_object_implements(object, "shell", 1)) { - d->shell = (struct wl_shell *) object; + } else if (strcmp(interface, "input_device") == 0) { + display_add_input(d, id); + } else if (strcmp(interface, "shell") == 0) { + d->shell = wl_shell_create(display, id); wl_shell_add_listener(d->shell, &shell_listener, d); - } else if (wl_object_implements(object, "drm", 1)) { - d->drm = (struct wl_drm *) object; + } else if (strcmp(interface, "drm") == 0) { + d->drm = wl_drm_create(display, id); wl_drm_add_listener(d->drm, &drm_listener, d); } } diff --git a/scanner.c b/scanner.c index 1c56d7de..2ce88afd 100644 --- a/scanner.c +++ b/scanner.c @@ -260,6 +260,19 @@ emit_stubs(struct wl_list *message_list, struct interface *interface) struct message *m; struct arg *a, *ret; + /* We provide a hand written constructor for the display object */ + if (strcmp(interface->name, "display") != 0) + printf("static inline struct wl_%s *\n" + "wl_%s_create(struct wl_display *display, uint32_t id)\n" + "{\n" + "\treturn (struct wl_%s *)\n" + "\t\twl_proxy_create_for_id(display, &wl_%s_interface, id);\n" + "}\n\n", + interface->name, + interface->name, + interface->name, + interface->name); + if (wl_list_empty(message_list)) return; @@ -395,6 +408,24 @@ emit_structs(struct wl_list *message_list, struct interface *interface) } } +static const char client_prototypes[] = + "struct wl_proxy;\n\n" + + "extern void\n" + "wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);\n" + + "extern struct wl_proxy *\n" + "wl_proxy_create(struct wl_proxy *factory,\n" + "\t\tconst struct wl_interface *interface);\n" + + "extern struct wl_proxy *\n" + "wl_proxy_create_for_id(struct wl_display *display,\n" + "\t\t const struct wl_interface *interface, uint32_t id);\n" + + "extern int\n" + "wl_proxy_add_listener(struct wl_proxy *proxy,\n" + "\t\t void (**implementation)(void), void *data);\n\n"; + static void emit_header(struct protocol *protocol, int server) { @@ -417,19 +448,7 @@ emit_header(struct protocol *protocol, int server) printf("\n"); if (!server) - printf("struct wl_proxy;\n\n" - "extern void\n" - "wl_proxy_marshal(struct wl_proxy *p, " - "uint32_t opcode, ...);\n" - - "extern struct wl_proxy *\n" - "wl_proxy_create(struct wl_proxy *factory,\n" - "\t\tconst struct wl_interface *interface);\n" - - "extern int\n" - "wl_proxy_add_listener(struct wl_proxy *proxy,\n" - "\t\t void (**implementation)(void), " - "void *data);\n\n"); + printf(client_prototypes); wl_list_for_each(i, &protocol->interface_list, link) { printf("extern const struct wl_interface " diff --git a/wayland-client.c b/wayland-client.c index 9b1f01f5..71b4fee2 100644 --- a/wayland-client.c +++ b/wayland-client.c @@ -40,14 +40,6 @@ static const char socket_name[] = "\0wayland"; -struct wl_global { - uint32_t id; - char *interface; - uint32_t version; - struct wl_proxy *proxy; - struct wl_list link; -}; - struct wl_global_listener { wl_display_global_func_t handler; void *data; @@ -67,18 +59,6 @@ struct wl_proxy { void *user_data; }; -struct wl_compositor { - struct wl_proxy proxy; -}; - -struct wl_surface { - struct wl_proxy proxy; -}; - -struct wl_visual { - struct wl_proxy proxy; -}; - struct wl_display { struct wl_proxy proxy; struct wl_connection *connection; @@ -86,7 +66,6 @@ struct wl_display { uint32_t id, id_count, next_range; uint32_t mask; struct wl_hash_table *objects; - struct wl_list global_list; struct wl_listener listener; struct wl_list global_listener_list; @@ -99,8 +78,6 @@ struct wl_display { wl_display_global_func_t global_handler; void *global_handler_data; - - struct wl_compositor *compositor; }; static int @@ -117,20 +94,11 @@ connection_update(struct wl_connection *connection, return 0; } -WL_EXPORT int -wl_object_implements(struct wl_object *object, - const char *interface, int version) -{ - return strcmp(object->interface->name, interface) == 0 && - object->interface->version >= version; -} - WL_EXPORT struct wl_global_listener * wl_display_add_global_listener(struct wl_display *display, wl_display_global_func_t handler, void *data) { struct wl_global_listener *listener; - struct wl_global *global; listener = malloc(sizeof *listener); if (listener == NULL) @@ -140,12 +108,6 @@ wl_display_add_global_listener(struct wl_display *display, listener->data = data; wl_list_insert(display->global_listener_list.prev, &listener->link); - /* FIXME: Need a destructor for void *data? */ - - wl_list_for_each(global, &display->global_list, link) - if (global->proxy != NULL) - (*handler)(display, &global->proxy->base, data); - return listener; } @@ -157,50 +119,36 @@ wl_display_remove_global_listener(struct wl_display *display, free(listener); } -static struct wl_proxy * -wl_proxy_create_for_global(struct wl_display *display, - struct wl_global *global, - const struct wl_interface *interface) +WL_EXPORT struct wl_proxy * +wl_proxy_create_for_id(struct wl_display *display, + const struct wl_interface *interface, uint32_t id) { struct wl_proxy *proxy; - struct wl_global_listener *listener; proxy = malloc(sizeof *proxy); if (proxy == NULL) return NULL; proxy->base.interface = interface; - proxy->base.id = global->id; + proxy->base.id = id; proxy->display = display; - global->proxy = proxy; wl_list_init(&proxy->listener_list); wl_hash_table_insert(display->objects, proxy->base.id, proxy); - wl_list_for_each(listener, &display->global_listener_list, link) - (*listener->handler)(display, &proxy->base, listener->data); - return proxy; } WL_EXPORT struct wl_proxy * -wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface) +wl_proxy_create(struct wl_proxy *factory, + const struct wl_interface *interface) { - struct wl_proxy *proxy; - - proxy = malloc(sizeof *proxy); - if (proxy == NULL) - return NULL; - - proxy->base.interface = interface; - proxy->base.id = wl_display_allocate_id(factory->display); - proxy->display = factory->display; - wl_hash_table_insert(factory->display->objects, proxy->base.id, proxy); - - return proxy; + return wl_proxy_create_for_id(factory->display, interface, + wl_display_allocate_id(factory->display)); } WL_EXPORT int -wl_proxy_add_listener(struct wl_proxy *proxy, void (**implementation)(void), void *data) +wl_proxy_add_listener(struct wl_proxy *proxy, + void (**implementation)(void), void *data) { struct wl_listener *listener; @@ -228,13 +176,12 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...) } static void -add_visual(struct wl_display *display, struct wl_global *global) +add_visual(struct wl_display *display, uint32_t id) { struct wl_visual *visual; visual = (struct wl_visual *) - wl_proxy_create_for_global(display, global, - &wl_visual_interface); + wl_proxy_create_for_id(display, &wl_visual_interface, id); if (display->argb_visual == NULL) display->argb_visual = visual; else if (display->premultiplied_argb_visual == NULL) @@ -291,38 +238,17 @@ display_handle_global(void *data, struct wl_display *display, uint32_t id, const char *interface, uint32_t version) { - struct wl_global *global; - - global = malloc(sizeof *global); - if (global == NULL) - return; - - global->id = id; - global->interface = strdup(interface); - global->version = version; - wl_list_insert(display->global_list.prev, &global->link); + struct wl_global_listener *listener; - if (strcmp(global->interface, "display") == 0) + if (strcmp(interface, "display") == 0) wl_hash_table_insert(display->objects, id, &display->proxy.base); - else if (strcmp(global->interface, "compositor") == 0) - display->compositor = (struct wl_compositor *) - wl_proxy_create_for_global(display, global, - &wl_compositor_interface); - else if (strcmp(global->interface, "visual") == 0) - add_visual(display, global); - else if (strcmp(global->interface, "output") == 0) - wl_proxy_create_for_global(display, global, - &wl_output_interface); - else if (strcmp(global->interface, "input_device") == 0) - wl_proxy_create_for_global(display, global, - &wl_input_device_interface); - else if (strcmp(global->interface, "shell") == 0) - wl_proxy_create_for_global(display, global, - &wl_shell_interface); - else if (strcmp(global->interface, "drm") == 0) - wl_proxy_create_for_global(display, global, - &wl_drm_interface); + else if (strcmp(interface, "visual") == 0) + add_visual(display, id); + + wl_list_for_each(listener, &display->global_listener_list, link) + (*listener->handler)(display, + id, interface, version, listener->data); } static void @@ -370,7 +296,6 @@ wl_display_create(const char *name, size_t name_size) } display->objects = wl_hash_table_create(); - wl_list_init(&display->global_list); wl_list_init(&display->global_listener_list); display->proxy.base.interface = &wl_display_interface; @@ -396,20 +321,6 @@ wl_display_destroy(struct wl_display *display) free(display); } -WL_EXPORT uint32_t -wl_display_get_object_id(struct wl_display *display, - const char *interface, uint32_t version) -{ - struct wl_global *global; - - wl_list_for_each(global, &display->global_list, link) - if (strcmp(global->interface, interface) == 0 && - global->version >= version) - return global->id; - - return 0; -} - WL_EXPORT int wl_display_get_fd(struct wl_display *display, wl_display_update_func_t update, void *data) @@ -498,26 +409,18 @@ wl_display_allocate_id(struct wl_display *display) return display->id++; } -WL_EXPORT void -wl_display_write(struct wl_display *display, const void *data, size_t count) -{ - wl_connection_write(display->connection, data, count); -} - -WL_EXPORT struct wl_compositor * -wl_display_get_compositor(struct wl_display *display) -{ - return display->compositor; -} - WL_EXPORT void wl_surface_set_user_data(struct wl_surface *surface, void *user_data) { - surface->proxy.user_data = user_data; + struct wl_proxy *proxy = (struct wl_proxy *) surface; + + proxy->user_data = user_data; } WL_EXPORT void * wl_surface_get_user_data(struct wl_surface *surface) { - return surface->proxy.user_data; + struct wl_proxy *proxy = (struct wl_proxy *) surface; + + return proxy->user_data; } diff --git a/wayland-client.h b/wayland-client.h index ec6a3ca4..1a49fd79 100644 --- a/wayland-client.h +++ b/wayland-client.h @@ -33,22 +33,20 @@ extern "C" { #define WL_DISPLAY_READABLE 0x01 #define WL_DISPLAY_WRITABLE 0x02 -int -wl_object_implements(struct wl_object *object, - const char *interface, int version); - typedef int (*wl_display_update_func_t)(uint32_t mask, void *data); struct wl_display *wl_display_create(const char *name, size_t name_size); void wl_display_destroy(struct wl_display *display); int wl_display_get_fd(struct wl_display *display, wl_display_update_func_t update, void *data); - +uint32_t wl_display_allocate_id(struct wl_display *display); void wl_display_iterate(struct wl_display *display, uint32_t mask); struct wl_global_listener; typedef void (*wl_display_global_func_t)(struct wl_display *display, - struct wl_object *object, + uint32_t id, + const char *interface, + uint32_t version, void *data); void wl_display_remove_global_listener(struct wl_display *display, @@ -57,8 +55,6 @@ wl_display_remove_global_listener(struct wl_display *display, struct wl_global_listener * wl_display_add_global_listener(struct wl_display *display, wl_display_global_func_t handler, void *data); -struct wl_compositor * -wl_display_get_compositor(struct wl_display *display); struct wl_visual * wl_display_get_argb_visual(struct wl_display *display); struct wl_visual * @@ -66,46 +62,9 @@ wl_display_get_premultiplied_argb_visual(struct wl_display *display); struct wl_visual * wl_display_get_rgb_visual(struct wl_display *display); -int -wl_compositor_add_listener(struct wl_compositor *compostior, - const struct wl_compositor_listener *listener, - void *data); - -int -wl_shell_add_listener(struct wl_shell *shell, - const struct wl_shell_listener *listener, - void *data); -int -wl_drm_add_listener(struct wl_drm *drm, - const struct wl_drm_listener *listener, - void *data); - void wl_surface_set_user_data(struct wl_surface *surface, void *user_data); void *wl_surface_get_user_data(struct wl_surface *surface); -int -wl_output_add_listener(struct wl_output *output, - const struct wl_output_listener *listener, - void *data); - -int -wl_input_device_add_listener(struct wl_input_device *input_device, - const struct wl_input_device_listener *listener, - void *data); - - -/* These entry points are for client side implementation of custom - * objects. */ - -uint32_t wl_display_get_object_id(struct wl_display *display, - const char *interface, uint32_t version); -uint32_t wl_display_allocate_id(struct wl_display *display); -void wl_display_write(struct wl_display *display, - const void *data, - size_t count); -void wl_display_advertise_global(struct wl_display *display, - struct wl_object *object); - #ifdef __cplusplus } #endif