diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index dc436525..8550cf31 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -1021,21 +1021,21 @@ create_output(struct desktop *desktop, uint32_t id) if (!output) return; - output->output = wl_display_bind(display_get_display(desktop->display), - id, &wl_output_interface); + output->output = + display_bind(desktop->display, id, &wl_output_interface, 1); wl_list_insert(&desktop->outputs, &output->link); } static void -global_handler(struct wl_display *display, uint32_t id, +global_handler(struct display *display, uint32_t id, const char *interface, uint32_t version, void *data) { struct desktop *desktop = data; if (!strcmp(interface, "desktop_shell")) { - desktop->shell = - wl_display_bind(display, id, &desktop_shell_interface); + desktop->shell = display_bind(desktop->display, + id, &desktop_shell_interface, 1); desktop_shell_add_listener(desktop->shell, &listener, desktop); } else if (!strcmp(interface, "wl_output")) { create_output(desktop, id); @@ -1092,8 +1092,7 @@ int main(int argc, char *argv[]) } display_set_user_data(desktop.display, &desktop); - wl_display_add_global_listener(display_get_display(desktop.display), - global_handler, &desktop); + display_set_global_handler(desktop.display, global_handler); wl_list_for_each(output, &desktop.outputs, link) { struct wl_surface *surface; diff --git a/clients/editor.c b/clients/editor.c index ce0692fa..02ee5da1 100644 --- a/clients/editor.c +++ b/clients/editor.c @@ -835,14 +835,15 @@ editor_button_handler(struct widget *widget, } static void -global_handler(struct wl_display *display, uint32_t id, +global_handler(struct display *display, uint32_t name, const char *interface, uint32_t version, void *data) { struct editor *editor = data; if (!strcmp(interface, "text_model_factory")) { - editor->text_model_factory = wl_display_bind(display, id, - &text_model_factory_interface); + editor->text_model_factory = + display_bind(display, name, + &text_model_factory_interface, 1); } } @@ -856,9 +857,9 @@ main(int argc, char *argv[]) fprintf(stderr, "failed to create display: %m\n"); return -1; } - wl_display_add_global_listener(display_get_display(editor.display), - global_handler, &editor); + display_set_user_data(editor.display, &editor); + display_set_global_handler(editor.display, global_handler); editor.window = window_create(editor.display); editor.widget = frame_create(editor.window, &editor); diff --git a/clients/keyboard.c b/clients/keyboard.c index 19eb0346..4f62d9c3 100644 --- a/clients/keyboard.c +++ b/clients/keyboard.c @@ -395,15 +395,18 @@ static const struct input_method_listener input_method_listener = { }; static void -global_handler(struct wl_display *display, uint32_t id, +global_handler(struct display *display, uint32_t name, const char *interface, uint32_t version, void *data) { struct virtual_keyboard *keyboard = data; if (!strcmp(interface, "input_panel")) { - keyboard->input_panel = wl_display_bind(display, id, &input_panel_interface); + keyboard->input_panel = + display_bind(display, name, &input_panel_interface, 1); } else if (!strcmp(interface, "input_method")) { - keyboard->input_method = wl_display_bind(display, id, &input_method_interface); + keyboard->input_method = + display_bind(display, name, + &input_method_interface, 1); input_method_add_listener(keyboard->input_method, &input_method_listener, keyboard); } } @@ -464,10 +467,8 @@ main(int argc, char *argv[]) virtual_keyboard.context = NULL; virtual_keyboard.preedit_string = NULL; - wl_display_add_global_listener(display_get_display(virtual_keyboard.display), - global_handler, &virtual_keyboard); - display_set_user_data(virtual_keyboard.display, &virtual_keyboard); + display_set_global_handler(virtual_keyboard.display, global_handler); display_set_output_configure_handler(virtual_keyboard.display, handle_output_configure); display_run(virtual_keyboard.display); diff --git a/clients/screenshot.c b/clients/screenshot.c index 0fa4e4b7..8681a41c 100644 --- a/clients/screenshot.c +++ b/clients/screenshot.c @@ -109,23 +109,29 @@ static const struct screenshooter_listener screenshooter_listener = { }; static void -handle_global(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) { static struct screenshooter_output *output; if (strcmp(interface, "wl_output") == 0) { output = malloc(sizeof *output); - output->output = wl_display_bind(display, id, &wl_output_interface); + output->output = wl_registry_bind(registry, name, + &wl_output_interface, 1); wl_list_insert(&output_list, &output->link); wl_output_add_listener(output->output, &output_listener, output); } else if (strcmp(interface, "wl_shm") == 0) { - shm = wl_display_bind(display, id, &wl_shm_interface); + shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); } else if (strcmp(interface, "screenshooter") == 0) { - screenshooter = wl_display_bind(display, id, &screenshooter_interface); + screenshooter = wl_registry_bind(registry, name, + &screenshooter_interface, 1); } } +static const struct wl_registry_listener registry_listener = { + handle_global +}; + static struct wl_buffer * create_shm_buffer(int width, int height, void **data_out) { @@ -231,6 +237,7 @@ set_buffer_size(int *width, int *height) int main(int argc, char *argv[]) { struct wl_display *display; + struct wl_registry *registry; struct screenshooter_output *output; int width, height; @@ -241,8 +248,9 @@ int main(int argc, char *argv[]) } wl_list_init(&output_list); - wl_display_add_global_listener(display, handle_global, &screenshooter); - wl_display_iterate(display, WL_DISPLAY_READABLE); + registry = wl_display_get_registry(display); + wl_registry_add_listener(registry, ®istry_listener, NULL); + wl_display_dispatch(display); wl_display_roundtrip(display); if (screenshooter == NULL) { fprintf(stderr, "display doesn't support screenshooter\n"); diff --git a/clients/simple-egl.c b/clients/simple-egl.c index d6842afd..f956c811 100644 --- a/clients/simple-egl.c +++ b/clients/simple-egl.c @@ -41,6 +41,7 @@ struct seat; struct display { struct wl_display *display; + struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_seat *seat; @@ -51,7 +52,6 @@ struct display { EGLContext ctx; EGLConfig conf; } egl; - uint32_t mask; struct window *window; }; @@ -545,31 +545,28 @@ static const struct wl_seat_listener seat_listener = { }; static void -display_handle_global(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +registry_handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) { struct display *d = data; if (strcmp(interface, "wl_compositor") == 0) { d->compositor = - wl_display_bind(display, id, &wl_compositor_interface); + wl_registry_bind(registry, name, + &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_shell") == 0) { - d->shell = wl_display_bind(display, id, &wl_shell_interface); + d->shell = wl_registry_bind(registry, name, + &wl_shell_interface, 1); } else if (strcmp(interface, "wl_seat") == 0) { - d->seat = wl_display_bind(d->display, id, &wl_seat_interface); + d->seat = wl_registry_bind(registry, name, + &wl_seat_interface, 1); wl_seat_add_listener(d->seat, &seat_listener, d); } } -static int -event_mask_update(uint32_t mask, void *data) -{ - struct display *d = data; - - d->mask = mask; - - return 0; -} +static const struct wl_registry_listener registry_listener = { + registry_handle_global +}; static void signal_int(int signum) @@ -615,11 +612,11 @@ main(int argc, char **argv) display.display = wl_display_connect(NULL); assert(display.display); - wl_display_add_global_listener(display.display, - display_handle_global, &display); + display.registry = wl_display_get_registry(display.display); + wl_registry_add_listener(display.registry, + ®istry_listener, &display); - wl_display_get_fd(display.display, event_mask_update, &display); - wl_display_iterate(display.display, WL_DISPLAY_READABLE); + wl_display_dispatch(display.display); init_egl(&display, window.opaque); create_surface(&window); @@ -631,7 +628,7 @@ main(int argc, char **argv) sigaction(SIGINT, &sigint, NULL); while (running) - wl_display_iterate(display.display, display.mask); + wl_display_dispatch(display.display); fprintf(stderr, "simple-egl exiting\n"); diff --git a/clients/simple-shm.c b/clients/simple-shm.c index f62e54e1..fc05bb40 100644 --- a/clients/simple-shm.c +++ b/clients/simple-shm.c @@ -35,11 +35,11 @@ struct display { struct wl_display *display; + struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; uint32_t formats; - uint32_t mask; }; struct window { @@ -242,31 +242,28 @@ struct wl_shm_listener shm_listenter = { }; static void -display_handle_global(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +registry_handle_global(void *data, struct wl_registry *registry, + uint32_t id, const char *interface, uint32_t version) { struct display *d = data; if (strcmp(interface, "wl_compositor") == 0) { d->compositor = - wl_display_bind(display, id, &wl_compositor_interface); + wl_registry_bind(registry, + id, &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_shell") == 0) { - d->shell = wl_display_bind(display, id, &wl_shell_interface); + d->shell = wl_registry_bind(registry, + id, &wl_shell_interface, 1); } else if (strcmp(interface, "wl_shm") == 0) { - d->shm = wl_display_bind(display, id, &wl_shm_interface); + d->shm = wl_registry_bind(registry, + id, &wl_shm_interface, 1); wl_shm_add_listener(d->shm, &shm_listenter, d); } } -static int -event_mask_update(uint32_t mask, void *data) -{ - struct display *d = data; - - d->mask = mask; - - return 0; -} +static const struct wl_registry_listener registry_listener = { + registry_handle_global +}; static struct display * create_display(void) @@ -278,9 +275,15 @@ create_display(void) assert(display->display); display->formats = 0; - wl_display_add_global_listener(display->display, - display_handle_global, display); - wl_display_iterate(display->display, WL_DISPLAY_READABLE); + display->registry = wl_display_get_registry(display->display); + wl_registry_add_listener(display->registry, + ®istry_listener, display); + wl_display_roundtrip(display->display); + if (display->shm == NULL) { + fprintf(stderr, "No wl_shm global\n"); + exit(1); + } + wl_display_roundtrip(display->display); if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) { @@ -288,7 +291,7 @@ create_display(void) exit(1); } - wl_display_get_fd(display->display, event_mask_update, display); + wl_display_get_fd(display->display); return display; } @@ -341,7 +344,7 @@ main(int argc, char **argv) redraw(window, NULL, 0); while (running) - wl_display_iterate(display->display, display->mask); + wl_display_dispatch(display->display); fprintf(stderr, "simple-shm exiting\n"); destroy_window(window); diff --git a/clients/simple-touch.c b/clients/simple-touch.c index 03fd45b2..68fb3684 100644 --- a/clients/simple-touch.c +++ b/clients/simple-touch.c @@ -36,6 +36,7 @@ struct touch { struct wl_display *display; + struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; @@ -47,7 +48,6 @@ struct touch { struct wl_shell_surface *shell_surface; struct wl_buffer *buffer; int has_argb; - uint32_t mask; int width, height; void *data; }; @@ -236,35 +236,33 @@ static const struct wl_shell_surface_listener shell_surface_listener = { }; static void -handle_global(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) { struct touch *touch = data; if (strcmp(interface, "wl_compositor") == 0) { touch->compositor = - wl_display_bind(display, id, &wl_compositor_interface); + wl_registry_bind(registry, name, + &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_shell") == 0) { touch->shell = - wl_display_bind(display, id, &wl_shell_interface); + wl_registry_bind(registry, name, + &wl_shell_interface, 1); } else if (strcmp(interface, "wl_shm") == 0) { - touch->shm = wl_display_bind(display, id, &wl_shm_interface); + touch->shm = wl_registry_bind(registry, name, + &wl_shm_interface, 1); wl_shm_add_listener(touch->shm, &shm_listenter, touch); } else if (strcmp(interface, "wl_seat") == 0) { - touch->seat = wl_display_bind(display, id, &wl_seat_interface); + touch->seat = wl_registry_bind(registry, name, + &wl_seat_interface, 1); wl_seat_add_listener(touch->seat, &seat_listener, touch); } } -static int -event_mask_update(uint32_t mask, void *data) -{ - struct touch *touch = data; - - touch->mask = mask; - - return 0; -} +static const struct wl_registry_listener registry_listener = { + handle_global +}; static struct touch * touch_create(int width, int height) @@ -276,8 +274,9 @@ touch_create(int width, int height) assert(touch->display); touch->has_argb = 0; - wl_display_add_global_listener(touch->display, handle_global, touch); - wl_display_iterate(touch->display, WL_DISPLAY_READABLE); + touch->registry = wl_display_get_registry(touch->display); + wl_registry_add_listener(touch->registry, ®istry_listener, touch); + wl_display_dispatch(touch->display); wl_display_roundtrip(touch->display); if (!touch->has_argb) { @@ -285,7 +284,7 @@ touch_create(int width, int height) exit(1); } - wl_display_get_fd(touch->display, event_mask_update, touch); + wl_display_get_fd(touch->display); touch->width = width; touch->height = height; @@ -318,7 +317,7 @@ main(int argc, char **argv) touch = touch_create(600, 500); while (true) - wl_display_iterate(touch->display, touch->mask); + wl_display_dispatch(touch->display); return 0; } diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c index 0a669504..993da7cb 100644 --- a/clients/tablet-shell.c +++ b/clients/tablet-shell.c @@ -438,14 +438,15 @@ launcher_section_done(void *data) } static void -global_handler(struct wl_display *display, uint32_t id, +global_handler(struct display *display, uint32_t name, const char *interface, uint32_t version, void *data) { struct tablet *tablet = data; if (!strcmp(interface, "tablet_shell")) { tablet->tablet_shell = - wl_display_bind(display, id, &tablet_shell_interface); + display_bind(display, name, + &tablet_shell_interface, 1); tablet_shell_add_listener(tablet->tablet_shell, &tablet_shell_listener, tablet); } @@ -466,8 +467,8 @@ int main(int argc, char *argv[]) tablet.display = display; - wl_display_add_global_listener(display_get_display(tablet.display), - global_handler, &tablet); + display_set_user_data(tablet.display, &tablet); + display_set_global_handler(tablet.display, global_handler); tablet.homescreen = homescreen_create(&tablet); tablet_shell_set_homescreen(tablet.tablet_shell, diff --git a/clients/weston-info.c b/clients/weston-info.c index 95e45b14..edd826e0 100644 --- a/clients/weston-info.c +++ b/clients/weston-info.c @@ -88,6 +88,7 @@ struct seat_info { struct weston_info { struct wl_display *display; + struct wl_registry *registry; struct wl_list infos; bool roundtrip_needed; @@ -264,7 +265,8 @@ add_seat_info(struct weston_info *info, uint32_t id, uint32_t version) init_global_info(info, &seat->global, id, "wl_seat", version); seat->global.print = print_seat_info; - seat->seat = wl_display_bind(info->display, id, &wl_seat_interface); + seat->seat = wl_registry_bind(info->registry, + id, &wl_seat_interface, 1); wl_seat_add_listener(seat->seat, &seat_listener, seat); info->roundtrip_needed = true; @@ -293,7 +295,8 @@ add_shm_info(struct weston_info *info, uint32_t id, uint32_t version) shm->global.print = print_shm_info; wl_list_init(&shm->formats); - shm->shm = wl_display_bind(info->display, id, &wl_shm_interface); + shm->shm = wl_registry_bind(info->registry, + id, &wl_shm_interface, 1); wl_shm_add_listener(shm->shm, &shm_listener, shm); info->roundtrip_needed = true; @@ -350,8 +353,8 @@ add_output_info(struct weston_info *info, uint32_t id, uint32_t version) wl_list_init(&output->modes); - output->output = wl_display_bind(info->display, id, - &wl_output_interface); + output->output = wl_registry_bind(info->registry, id, + &wl_output_interface, 1); wl_output_add_listener(output->output, &output_listener, output); @@ -369,8 +372,8 @@ add_global_info(struct weston_info *info, uint32_t id, } static void -global_handler(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +global_handler(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) { struct weston_info *info = data; @@ -384,6 +387,10 @@ global_handler(struct wl_display *display, uint32_t id, add_global_info(info, id, interface, version); } +static const struct wl_registry_listener registry_listener = { + global_handler +}; + static void print_infos(struct wl_list *infos) { @@ -406,9 +413,8 @@ main(int argc, char **argv) wl_list_init(&info.infos); - wl_display_add_global_listener(info.display, - global_handler, - &info); + info.registry = wl_display_get_registry(info.display); + wl_registry_add_listener(info.registry, ®istry_listener, &info); do { info.roundtrip_needed = false; diff --git a/clients/window.c b/clients/window.c index b19c579d..8ea453d3 100644 --- a/clients/window.c +++ b/clients/window.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -69,8 +70,16 @@ struct shm_pool; +struct global { + uint32_t name; + char *interface; + uint32_t version; + struct wl_list link; +}; + struct display { struct wl_display *display; + struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; @@ -85,7 +94,6 @@ struct display { int display_fd; uint32_t display_fd_events; - uint32_t mask; struct task display_task; int epoll_fd; @@ -93,6 +101,7 @@ struct display { int running; + struct wl_list global_list; struct wl_list window_list; struct wl_list input_list; struct wl_list output_list; @@ -107,6 +116,7 @@ struct display { PFNEGLDESTROYIMAGEKHRPROC destroy_image; display_output_handler_t output_configure_handler; + display_global_handler_t global_handler; void *user_data; @@ -3495,7 +3505,7 @@ display_add_output(struct display *d, uint32_t id) memset(output, 0, sizeof *output); output->display = d; output->output = - wl_display_bind(d->display, id, &wl_output_interface); + wl_registry_bind(d->registry, id, &wl_output_interface, 1); wl_list_insert(d->output_list.prev, &output->link); wl_output_add_listener(output->output, &output_listener, output); @@ -3512,6 +3522,22 @@ output_destroy(struct output *output) free(output); } +void +display_set_global_handler(struct display *display, + display_global_handler_t handler) +{ + struct global *global; + + display->global_handler = handler; + if (!handler) + return; + + wl_list_for_each(global, &display->global_list, link) + display->global_handler(display, + global->name, global->interface, + global->version, display->user_data); +} + void display_set_output_configure_handler(struct display *display, display_output_handler_t handler) @@ -3590,7 +3616,7 @@ display_add_input(struct display *d, uint32_t id) memset(input, 0, sizeof *input); input->display = d; - input->seat = wl_display_bind(d->display, id, &wl_seat_interface); + input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1); input->pointer_focus = NULL; input->keyboard_focus = NULL; wl_list_insert(d->input_list.prev, &input->link); @@ -3640,7 +3666,8 @@ static void init_workspace_manager(struct display *d, uint32_t id) { d->workspace_manager = - wl_display_bind(d->display, id, &workspace_manager_interface); + wl_registry_bind(d->registry, id, + &workspace_manager_interface, 1); if (d->workspace_manager != NULL) workspace_manager_add_listener(d->workspace_manager, &workspace_manager_listener, @@ -3648,35 +3675,57 @@ init_workspace_manager(struct display *d, uint32_t id) } static void -display_handle_global(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) { struct display *d = data; + struct global *global; + + global = malloc(sizeof *global); + global->name = id; + global->interface = strdup(interface); + global->version = version; + wl_list_insert(d->global_list.prev, &global->link); if (strcmp(interface, "wl_compositor") == 0) { - d->compositor = - wl_display_bind(display, id, &wl_compositor_interface); + d->compositor = wl_registry_bind(registry, id, + &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_output") == 0) { display_add_output(d, id); } else if (strcmp(interface, "wl_seat") == 0) { display_add_input(d, id); } else if (strcmp(interface, "wl_shell") == 0) { - d->shell = wl_display_bind(display, id, &wl_shell_interface); + d->shell = wl_registry_bind(registry, + id, &wl_shell_interface, 1); } else if (strcmp(interface, "wl_shm") == 0) { - d->shm = wl_display_bind(display, id, &wl_shm_interface); + d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); } else if (strcmp(interface, "wl_data_device_manager") == 0) { d->data_device_manager = - wl_display_bind(display, id, - &wl_data_device_manager_interface); + wl_registry_bind(registry, id, + &wl_data_device_manager_interface, 1); } else if (strcmp(interface, "text_cursor_position") == 0) { d->text_cursor_position = - wl_display_bind(display, id, - &text_cursor_position_interface); + wl_registry_bind(registry, id, + &text_cursor_position_interface, 1); } else if (strcmp(interface, "workspace_manager") == 0) { init_workspace_manager(d, id); } + + if (d->global_handler) + d->global_handler(d, id, interface, version, d->user_data); } +void * +display_bind(struct display *display, uint32_t name, + const struct wl_interface *interface, uint32_t version) +{ + return wl_registry_bind(display->registry, name, interface, version); +} + +static const struct wl_registry_listener registry_listener = { + registry_handle_global +}; + #ifdef HAVE_CAIRO_EGL static int init_egl(struct display *d) @@ -3767,21 +3816,13 @@ fini_egl(struct display *display) } #endif -static int -event_mask_update(uint32_t mask, void *data) -{ - struct display *d = data; - - d->mask = mask; - - return 0; -} - static void handle_display_data(struct task *task, uint32_t events) { struct display *display = container_of(task, struct display, display_task); + struct epoll_event ep; + int ret; display->display_fd_events = events; @@ -3790,7 +3831,21 @@ handle_display_data(struct task *task, uint32_t events) return; } - wl_display_iterate(display->display, display->mask); + if (events & EPOLLIN) + wl_display_dispatch(display->display); + + if (events & EPOLLOUT) { + ret = wl_display_flush(display->display); + if (ret == 0) { + ep.events = EPOLLIN | EPOLLERR | EPOLLHUP; + ep.data.ptr = &display->display_task; + epoll_ctl(display->epoll_fd, EPOLL_CTL_MOD, + display->display_fd, &ep); + } else if (ret == -1 && errno != EAGAIN) { + display_exit(display); + return; + } + } } struct display * @@ -3811,7 +3866,7 @@ display_create(int argc, char *argv[]) } d->epoll_fd = os_epoll_create_cloexec(); - d->display_fd = wl_display_get_fd(d->display, event_mask_update, d); + d->display_fd = wl_display_get_fd(d->display); d->display_task.run = handle_display_data; display_watch_fd(d, d->display_fd, EPOLLIN | EPOLLERR | EPOLLHUP, &d->display_task); @@ -3819,6 +3874,7 @@ display_create(int argc, char *argv[]) wl_list_init(&d->deferred_list); wl_list_init(&d->input_list); wl_list_init(&d->output_list); + wl_list_init(&d->global_list); d->xkb_context = xkb_context_new(0); if (d->xkb_context == NULL) { @@ -3829,12 +3885,9 @@ display_create(int argc, char *argv[]) d->workspace = 0; d->workspace_count = 1; - /* Set up listener so we'll catch all events. */ - wl_display_add_global_listener(d->display, - display_handle_global, d); - - /* Process connection events. */ - wl_display_iterate(d->display, WL_DISPLAY_READABLE); + d->registry = wl_display_get_registry(d->display); + wl_registry_add_listener(d->registry, ®istry_listener, d); + wl_display_dispatch(d->display); #ifdef HAVE_CAIRO_EGL if (init_egl(d) < 0) return NULL; @@ -4052,12 +4105,10 @@ display_run(struct display *display) { struct task *task; struct epoll_event ep[16]; - int i, count; + int i, count, ret; display->running = 1; while (1) { - wl_display_flush(display->display); - while (!wl_list_empty(&display->deferred_list)) { task = container_of(display->deferred_list.prev, struct task, link); @@ -4068,7 +4119,17 @@ display_run(struct display *display) if (!display->running) break; - wl_display_flush(display->display); + ret = wl_display_flush(display->display); + if (ret < 0 && errno == EAGAIN) { + ep[0].events = + EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP; + ep[0].data.ptr = &display->display_task; + + epoll_ctl(display->epoll_fd, EPOLL_CTL_MOD, + display->display_fd, &ep[0]); + } else if (ret < 0) { + break; + } count = epoll_wait(display->epoll_fd, ep, ARRAY_LENGTH(ep), -1); diff --git a/clients/window.h b/clients/window.h index 0c09c68b..17d97d6f 100644 --- a/clients/window.h +++ b/clients/window.h @@ -73,6 +73,18 @@ display_get_output(struct display *display); uint32_t display_get_serial(struct display *display); +typedef void (*display_global_handler_t)(struct display *display, + uint32_t name, + const char *interface, + uint32_t version, void *data); + +void +display_set_global_handler(struct display *display, + display_global_handler_t handler); +void * +display_bind(struct display *display, uint32_t name, + const struct wl_interface *interface, uint32_t version); + typedef void (*display_output_handler_t)(struct output *output, void *data); /* diff --git a/clients/wscreensaver.c b/clients/wscreensaver.c index ecb253ad..e0c165ad 100644 --- a/clients/wscreensaver.c +++ b/clients/wscreensaver.c @@ -288,14 +288,14 @@ init_wscreensaver(struct wscreensaver *wscr, struct display *display) } static void -global_handler(struct wl_display *display, uint32_t id, +global_handler(struct display *display, uint32_t name, const char *interface, uint32_t version, void *data) { struct wscreensaver *screensaver = data; if (!strcmp(interface, "screensaver")) { screensaver->interface = - wl_display_bind(display, id, &screensaver_interface); + display_bind(display, name, &screensaver_interface, 1); } } @@ -321,8 +321,8 @@ int main(int argc, char *argv[]) if (!demo_mode) { /* iterates already known globals immediately */ - wl_display_add_global_listener(display_get_display(d), - global_handler, &screensaver); + display_set_user_data(d, &screensaver); + display_set_global_handler(d, global_handler); if (!screensaver.interface) { fprintf(stderr, "Server did not offer screensaver interface," diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index 8ddebf29..805137d5 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -48,6 +48,7 @@ struct wayland_compositor { struct { struct wl_display *wl_display; + struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_output *output; @@ -730,8 +731,8 @@ display_add_seat(struct wayland_compositor *c, uint32_t id) weston_seat_init(&input->base, &c->base); input->compositor = c; - input->seat = wl_display_bind(c->parent.wl_display, id, - &wl_seat_interface); + input->seat = wl_registry_bind(c->parent.registry, id, + &wl_seat_interface, 1); wl_list_insert(c->input_list.prev, &input->link); wl_seat_add_listener(input->seat, &seat_listener, input); @@ -739,37 +740,32 @@ display_add_seat(struct wayland_compositor *c, uint32_t id) } static void -display_handle_global(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, + const char *interface, uint32_t version) { struct wayland_compositor *c = data; if (strcmp(interface, "wl_compositor") == 0) { c->parent.compositor = - wl_display_bind(display, id, &wl_compositor_interface); + wl_registry_bind(registry, name, + &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_output") == 0) { c->parent.output = - wl_display_bind(display, id, &wl_output_interface); + wl_registry_bind(registry, name, + &wl_output_interface, 1); wl_output_add_listener(c->parent.output, &output_listener, c); } else if (strcmp(interface, "wl_shell") == 0) { c->parent.shell = - wl_display_bind(display, id, &wl_shell_interface); + wl_registry_bind(registry, name, + &wl_shell_interface, 1); } else if (strcmp(interface, "wl_seat") == 0) { - display_add_seat(c, id); + display_add_seat(c, name); } } -static int -update_event_mask(uint32_t mask, void *data) -{ - struct wayland_compositor *c = data; - - c->parent.event_mask = mask; - if (c->parent.wl_source) - wl_event_source_fd_update(c->parent.wl_source, mask); - - return 0; -} +static const struct wl_registry_listener registry_listener = { + registry_handle_global +}; static int wayland_compositor_handle_event(int fd, uint32_t mask, void *data) @@ -777,9 +773,9 @@ wayland_compositor_handle_event(int fd, uint32_t mask, void *data) struct wayland_compositor *c = data; if (mask & WL_EVENT_READABLE) - wl_display_iterate(c->parent.wl_display, WL_DISPLAY_READABLE); + wl_display_dispatch(c->parent.wl_display); if (mask & WL_EVENT_WRITABLE) - wl_display_iterate(c->parent.wl_display, WL_DISPLAY_WRITABLE); + wl_display_flush(c->parent.wl_display); return 1; } @@ -826,10 +822,9 @@ wayland_compositor_create(struct wl_display *display, } wl_list_init(&c->input_list); - wl_display_add_global_listener(c->parent.wl_display, - display_handle_global, c); - - wl_display_iterate(c->parent.wl_display, WL_DISPLAY_READABLE); + c->parent.registry = wl_display_get_registry(c->parent.wl_display); + wl_registry_add_listener(c->parent.registry, ®istry_listener, c); + wl_display_dispatch(c->parent.wl_display); c->base.wl_display = display; if (wayland_compositor_init_egl(c) < 0) @@ -856,9 +851,9 @@ wayland_compositor_create(struct wl_display *display, loop = wl_display_get_event_loop(c->base.wl_display); - fd = wl_display_get_fd(c->parent.wl_display, update_event_mask, c); + fd = wl_display_get_fd(c->parent.wl_display); c->parent.wl_source = - wl_event_loop_add_fd(loop, fd, c->parent.event_mask, + wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wayland_compositor_handle_event, c); if (c->parent.wl_source == NULL) goto err_display;