[PATCH] Update to new fd and wl_registry APIs

Kristian Høgsberg krh at bitplanet.net
Wed Oct 10 18:37:41 PDT 2012


This commit updates the clients and the wayland compositor backend to
use the new wl_registry mechanism and the thread safe fd API.
---

This is the weston patch that goes with the 8 thread-safety wayland patches.
The wl_registry changes are mostly mechanical, while the fd changes are a
little more subtle.

Kristian

 clients/desktop-shell.c  |   13 +++--
 clients/editor.c         |   11 ++--
 clients/keyboard.c       |   13 ++---
 clients/screenshot.c     |   22 +++++---
 clients/simple-egl.c     |   37 ++++++-------
 clients/simple-shm.c     |   43 ++++++++-------
 clients/simple-touch.c   |   39 +++++++-------
 clients/tablet-shell.c   |    9 ++--
 clients/weston-info.c    |   24 +++++----
 clients/window.c         |  133 +++++++++++++++++++++++++++++++++-------------
 clients/window.h         |   12 +++++
 clients/wscreensaver.c   |    8 +--
 src/compositor-wayland.c |   49 ++++++++---------
 13 files changed, 248 insertions(+), 165 deletions(-)

diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index dc43652..8550cf3 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 ce0692f..02ee5da 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 19eb034..4f62d9c 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 0fa4e4b..8681a41 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, &registry_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 d6842af..f956c81 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,
+				 &registry_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 f62e54e..fc05bb4 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,
+				 &registry_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 03fd45b..68fb368 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, &registry_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 0a66950..993da7c 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 95e45b1..edd826e 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, &registry_listener, &info);
 
 	do {
 		info.roundtrip_needed = false;
diff --git a/clients/window.c b/clients/window.c
index b19c579..8ea453d 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -30,6 +30,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 #include <math.h>
 #include <assert.h>
 #include <time.h>
@@ -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);
@@ -3513,6 +3523,22 @@ output_destroy(struct output *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, &registry_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 0c09c68..17d97d6 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 ecb253a..e0c165a 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 8ddebf2..805137d 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, &registry_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;
-- 
1.7.10.2



More information about the wayland-devel mailing list