[PATCH v3 xserver 1/2] xwayland: Port to Wayland 1.0 API

Tiago Vignatti tiago.vignatti at intel.com
Thu Nov 22 12:08:52 PST 2012


Co-authored-by: Daniel Stone <daniel at fooishbar.org>
Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
changes from v2:
- fix wl_registry_bind client version
- clean-up xwl_drm_authenticate round trips
- use wl_display_dispatch_pending properly, just before going to sleep at
  block handler.
- place wl_surface_commit in its correct place. hopefully.


 hw/xfree86/xwayland/xwayland-cursor.c  |   40 +++++++++-----
 hw/xfree86/xwayland/xwayland-drm.c     |   33 +++++++-----
 hw/xfree86/xwayland/xwayland-input.c   |   34 +++++++-----
 hw/xfree86/xwayland/xwayland-output.c  |   53 +++++++++---------
 hw/xfree86/xwayland/xwayland-private.h |   12 +++--
 hw/xfree86/xwayland/xwayland-window.c  |    1 +
 hw/xfree86/xwayland/xwayland.c         |   92 +++++++++++++++-----------------
 7 files changed, 144 insertions(+), 121 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c
index f69601a..f8860bd 100644
--- a/hw/xfree86/xwayland/xwayland-cursor.c
+++ b/hw/xfree86/xwayland/xwayland-cursor.c
@@ -147,16 +147,35 @@ xwl_unrealize_cursor(DeviceIntPtr device,
     return TRUE;
 }
 
+void
+xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
+{
+    struct wl_buffer *buffer;
+
+    if (!xwl_seat->x_cursor || !xwl_seat->wl_pointer)
+        return;
+
+    buffer = dixGetPrivate(&xwl_seat->x_cursor->devPrivates,
+                           &xwl_cursor_private_key);
+
+    wl_pointer_set_cursor(xwl_seat->wl_pointer,
+			  xwl_seat->pointer_enter_serial,
+			  xwl_seat->cursor,
+			  xwl_seat->x_cursor->bits->xhot,
+			  xwl_seat->x_cursor->bits->yhot);
+    wl_surface_attach(xwl_seat->cursor, buffer, 0, 0);
+    wl_surface_damage(xwl_seat->cursor, 0, 0,
+		      xwl_seat->x_cursor->bits->width,
+		      xwl_seat->x_cursor->bits->height);
+    wl_surface_commit(xwl_seat->cursor);
+}
+
 static void
 xwl_set_cursor(DeviceIntPtr device,
 	       ScreenPtr screen, CursorPtr cursor, int x, int y)
 {
     struct xwl_screen *xwl_screen;
     struct xwl_seat *xwl_seat;
-    struct wl_buffer *buffer;
-
-    if (!cursor)
-	return;
 
     xwl_screen = xwl_screen_get(screen);
 
@@ -164,17 +183,10 @@ xwl_set_cursor(DeviceIntPtr device,
 	return;
 
     xwl_seat = xorg_list_first_entry(&xwl_screen->seat_list,
-					     struct xwl_seat, link);
-
-    buffer = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
+		                     struct xwl_seat, link);
 
-    wl_pointer_set_cursor(xwl_seat->wl_pointer,
-			  xwl_seat->pointer_enter_serial,
-			  xwl_seat->cursor,
-			  cursor->bits->xhot, cursor->bits->yhot);
-    wl_surface_attach(xwl_seat->cursor, buffer, 0, 0);
-    wl_surface_damage(xwl_seat->cursor, 0, 0,
-		      cursor->bits->width, cursor->bits->height);
+    xwl_seat->x_cursor = cursor;
+    xwl_seat_set_cursor(xwl_seat);
 }
 
 static void
diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
index 6ac5c7d..c19eb84 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -75,29 +75,30 @@ static const struct wl_drm_listener xwl_drm_listener =
 };
 
 static void
-drm_handler(struct wl_display *display_,
-	      uint32_t id,
-	      const char *interface,
-	      uint32_t version,
-	      void *data)
+drm_handler(void *data, struct wl_registry *registry, uint32_t id,
+	    const char *interface, uint32_t version)
 {
     struct xwl_screen *xwl_screen = data;
 
     if (strcmp (interface, "wl_drm") == 0) {
-	xwl_screen->drm = wl_display_bind(xwl_screen->display,
-					  id, &wl_drm_interface);
-	wl_drm_add_listener (xwl_screen->drm, &xwl_drm_listener, xwl_screen);
+	xwl_screen->drm = wl_registry_bind(xwl_screen->registry, id,
+                                           &wl_drm_interface, 1);
+	wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
     }
 }
 
+static const struct wl_registry_listener drm_listener = {
+    drm_handler,
+};
+
 int
 xwl_drm_pre_init(struct xwl_screen *xwl_screen)
 {
     uint32_t magic;
 
-    xwl_screen->drm_listener =
-	wl_display_add_global_listener(xwl_screen->display,
-				       drm_handler, xwl_screen);
+    xwl_screen->drm_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->drm_registry, &drm_listener,
+                             xwl_screen);
 
     /* Ensure drm_handler has seen all the interfaces */
     wl_display_roundtrip(xwl_screen->display);
@@ -145,14 +146,18 @@ int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
 int xwl_drm_authenticate(struct xwl_screen *xwl_screen,
 			    uint32_t magic)
 {
+    int ret;
+
     xwl_screen->authenticated = 0;
 
     if (xwl_screen->drm)
 	wl_drm_authenticate (xwl_screen->drm, magic);
 
-    wl_display_iterate (xwl_screen->display, WL_DISPLAY_WRITABLE);
-    while (!xwl_screen->authenticated)
-	wl_display_iterate (xwl_screen->display, WL_DISPLAY_READABLE);
+    ret = wl_display_roundtrip(xwl_screen->display);
+    if (ret == -1)
+	return BadAlloc;
+    if (!xwl_screen->authenticated)
+	return BadAlloc;
 
     return Success;
 }
diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
index d9f352f..44a14ba 100644
--- a/hw/xfree86/xwayland/xwayland-input.c
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -27,6 +27,7 @@
 #include "xorg-config.h"
 #endif
 
+#include <errno.h>
 #include <stdint.h>
 #include <unistd.h>
 #include <linux/input.h>
@@ -52,6 +53,9 @@
 
 #include "xwayland.h"
 #include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+extern const struct xserver_listener xwl_server_listener;
 
 static void
 xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
@@ -473,6 +477,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
 	    xwl_seat->wl_pointer = wl_seat_get_pointer(seat);
 	    wl_pointer_add_listener(xwl_seat->wl_pointer,
 				    &pointer_listener, xwl_seat);
+            xwl_seat_set_cursor(xwl_seat);
 	}
 
 	if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
@@ -488,8 +493,7 @@ static const struct wl_seat_listener seat_listener = {
 };
 
 static void
-create_input_device(struct xwl_screen *xwl_screen, uint32_t id,
-		    uint32_t version)
+create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
 {
     struct xwl_seat *xwl_seat;
 
@@ -503,7 +507,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id,
     xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
 
     xwl_seat->seat =
-	wl_display_bind(xwl_screen->display, id, &wl_seat_interface);
+	wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 1);
     xwl_seat->id = id;
 
     xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
@@ -512,23 +516,29 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id,
 }
 
 static void
-input_handler(struct wl_display *display,
-	      uint32_t id,
-	      const char *interface,
-	      uint32_t version,
-	      void *data)
+input_handler(void *data, struct wl_registry *registry, uint32_t id,
+	      const char *interface, uint32_t version)
 {
     struct xwl_screen *xwl_screen = data;
 
     if (strcmp (interface, "wl_seat") == 0) {
-        create_input_device(xwl_screen, id, 1);
+        create_input_device(xwl_screen, id);
+    } else if (strcmp(interface, "xserver") == 0) {
+        xwl_screen->xorg_server =
+            wl_registry_bind(registry, id, &xserver_interface, 1);
+        xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
+                             xwl_screen);
     }
 }
 
+static const struct wl_registry_listener input_listener = {
+    input_handler,
+};
+
 void
 xwl_input_init(struct xwl_screen *xwl_screen)
 {
-    xwl_screen->input_listener =
-	wl_display_add_global_listener(xwl_screen->display,
-				       input_handler, xwl_screen);
+    xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
+                             xwl_screen);
 }
diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c
index f9e6067..8f087f6 100644
--- a/hw/xfree86/xwayland/xwayland-output.c
+++ b/hw/xfree86/xwayland/xwayland-output.c
@@ -212,14 +212,9 @@ static const xf86CrtcConfigFuncsRec config_funcs = {
 };
 
 static void
-display_handle_geometry(void *data,
-			struct wl_output *wl_output,
-			int x, int y,
-			int physical_width,
-			int physical_height,
-			int subpixel,
-			const char *make,
-			const char *model)
+display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
+			int physical_width, int physical_height, int subpixel,
+			const char *make, const char *model, int transform)
 {
     struct xwl_output *xwl_output = data;
     struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
@@ -255,12 +250,8 @@ display_handle_geometry(void *data,
 }
 
 static void
-display_handle_mode(void *data,
-		    struct wl_output *wl_output,
-		    uint32_t flags,
-		    int width,
-		    int height,
-		    int refresh)
+display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+		    int width, int height, int refresh)
 {
     struct xwl_output *xwl_output = data;
 
@@ -276,39 +267,43 @@ static const struct wl_output_listener output_listener = {
 };
 
 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 xwl_screen *xwl_screen = data;
     struct xwl_output *xwl_output;
 
     if (strcmp (interface, "wl_output") == 0) {
 	xwl_output = xwl_output_create(xwl_screen);
-
-	xwl_output->output = wl_display_bind(xwl_screen->display,
-					     id, &wl_output_interface);
+	xwl_output->output = wl_registry_bind(registry, id,
+	                                      &wl_output_interface, 1);
 	wl_output_add_listener(xwl_output->output,
 			       &output_listener, xwl_output);
     }
 }
 
+static const struct wl_registry_listener global_listener = {
+    global_handler,
+};
+
 void
 xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo)
 {
+    int ret;
+
     xf86CrtcConfigInit(scrninfo, &config_funcs);
 
     xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192);
 
-    xwl_screen->global_listener =
-	wl_display_add_global_listener(xwl_screen->display,
-				       global_handler, xwl_screen);
+    xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
+                             xwl_screen);
+
+    while (!xwl_screen->xwl_output) {
+        ret = wl_display_roundtrip(xwl_screen->display);
+        if (ret == -1)
+            FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+    }
 
-    wl_display_flush(xwl_screen->display);
-    while (xwl_screen->xwl_output == NULL)
-	wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
-    
     xf86InitialConfiguration(scrninfo, TRUE);
 }
diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
index 8d8590f..23263d0 100644
--- a/hw/xfree86/xwayland/xwayland-private.h
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -46,10 +46,11 @@ struct xwl_screen {
     int				 wayland_fd;
     struct xwl_output		*xwl_output;
     struct wl_display		*display;
+    struct wl_registry          *registry;
+    struct wl_registry          *drm_registry;
+    struct wl_registry          *input_registry;
+    struct wl_registry          *output_registry;
     struct wl_compositor	*compositor;
-    struct wl_global_listener   *global_listener;
-    struct wl_global_listener   *drm_listener;
-    struct wl_global_listener   *input_listener;
     struct wl_drm		*drm;
     struct wl_shm		*shm;
     struct xserver		*xorg_server;
@@ -96,6 +97,7 @@ struct xwl_seat {
     uint32_t			 id;
     uint32_t			 pointer_enter_serial;
     struct xorg_list		 link;
+    CursorPtr                    x_cursor;
 };
 
 struct xwl_screen *xwl_screen_get(ScreenPtr screen);
@@ -113,4 +115,8 @@ void xwl_input_init(struct xwl_screen *screen);
 
 Bool xwl_drm_initialised(struct xwl_screen *screen);
 
+void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
+
+extern const struct xserver_listener xwl_server_listener;
+
 #endif /* _XWAYLAND_PRIVATE_H_ */
diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c
index 63d3886..41c4376 100644
--- a/hw/xfree86/xwayland/xwayland-window.c
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -81,6 +81,7 @@ xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap)
     wl_surface_damage(xwl_window->surface, 0, 0,
 		      pixmap->drawable.width,
 		      pixmap->drawable.height);
+    wl_surface_commit(xwl_window->surface);
 
     callback = wl_display_sync(xwl_screen->display);
     wl_callback_add_listener(callback, &free_pixmap_listener, pixmap);
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
index 67ac7d4..98e036e 100644
--- a/hw/xfree86/xwayland/xwayland.c
+++ b/hw/xfree86/xwayland/xwayland.c
@@ -68,7 +68,7 @@ xserver_listen_socket(void *data, struct xserver *xserver, int fd)
     ListenOnOpenFD(fd, TRUE);
 }
 
-static const struct xserver_listener xserver_listener = {
+const struct xserver_listener xwl_server_listener = {
     xserver_client,
     xserver_listen_socket
 };
@@ -77,20 +77,11 @@ static void
 xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
 {
     struct xwl_screen *xwl_screen = data;
-    uint32_t id;
 
     ErrorF("xwl_input_delayed_init\n");
 
     wl_callback_destroy(callback);
     xwl_input_init(xwl_screen);
-
-    id = wl_display_get_global(xwl_screen->display, "xserver", 1);
-    if (id != 0) {
-        xwl_screen->xorg_server = wl_display_bind(xwl_screen->display,
-						  id, &xserver_interface);
-	xserver_add_listener(xwl_screen->xorg_server,
-			     &xserver_listener, xwl_screen);
-    }
 }
 
 static const struct wl_callback_listener delayed_init_listner = {
@@ -98,53 +89,54 @@ static const struct wl_callback_listener delayed_init_listner = {
 };
 
 static void
-global_handler(struct wl_display *display_,
-	       uint32_t id,
-	       const char *interface,
-	       uint32_t version,
-	       void *data)
+registry_global(void *data, struct wl_registry *registry, uint32_t id,
+	        const char *interface, uint32_t version)
 {
     struct xwl_screen *xwl_screen = data;
 
     if (strcmp (interface, "wl_compositor") == 0) {
 	xwl_screen->compositor =
-		wl_display_bind(xwl_screen->display,
-				id, &wl_compositor_interface);
-    } else if (strcmp (interface, "wl_shm") == 0) {
-        xwl_screen->shm = wl_display_bind(xwl_screen->display,
-					  id, &wl_shm_interface);
+            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+    } else if (strcmp(interface, "wl_shm") == 0) {
+        xwl_screen->shm =
+            wl_registry_bind(registry, id, &wl_shm_interface, 1);
     }
 }
 
-static int
-source_update(uint32_t mask, void *data)
-{
-    struct xwl_screen *xwl_screen = data;
-
-    xwl_screen->mask = mask;
-
-    return 0;
-}
+static const struct wl_registry_listener registry_listener = {
+    registry_global,
+};
 
 static void
 wakeup_handler(pointer data, int err, pointer read_mask)
 {
     struct xwl_screen *xwl_screen = data;
+    int ret;
 
-    if (err >= 0 && FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
-	wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
+    if (err < 0)
+        return;
+
+    if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
+        return;
+
+    ret = wl_display_dispatch(xwl_screen->display);
+    if (ret == -1)
+        FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
 }
 
 static void
 block_handler(pointer data, struct timeval **tv, pointer read_mask)
 {
     struct xwl_screen *xwl_screen = data;
+    int ret;
 
-    /* The X servers "main loop" doesn't let us select for
-     * writable, so let's just do a blocking write here. */
+    ret = wl_display_dispatch_pending(xwl_screen->display);
+    if (ret == -1)
+	FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
 
-    while (xwl_screen->mask & WL_DISPLAY_WRITABLE)
-	wl_display_iterate(xwl_screen->display, WL_DISPLAY_WRITABLE);
+    ret = wl_display_flush(xwl_screen->display);
+    if (ret == -1)
+        FatalError("failed to write to XWayland fd: %s\n", strerror(errno));
 }
 
 int
@@ -228,10 +220,11 @@ Bool
 xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
 		    uint32_t flags, struct xwl_driver *driver)
 {
+    int ret;
+
     noScreenSaverExtension = TRUE;
 
     xdnd_atom = MakeAtom("XdndSelection", 13, 1);
-    ErrorF("xdnd_atom: %d\n", xdnd_atom);
     if (!AddCallback(&SelectionCallback,
 		     xwayland_selection_callback, xwl_screen)) {
 	return FALSE;
@@ -243,19 +236,21 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
     xwl_screen->scrninfo = scrninfo;
     xwl_screen->driver = driver;
     xwl_screen->flags = flags;
+    xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
 
     if (xorgRootless)
 	xwl_screen->flags |= XWL_FLAGS_ROOTLESS;
 
     /* Set up listener so we'll catch all events. */
-    xwl_screen->global_listener =
-	    wl_display_add_global_listener(xwl_screen->display,
-					   global_handler, xwl_screen);
-
-    wl_display_roundtrip(xwl_screen->display);
-
-    xwl_screen->wayland_fd =
-	wl_display_get_fd(xwl_screen->display, source_update, xwl_screen);
+    xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->registry, &registry_listener,
+                             xwl_screen);
+    ret = wl_display_roundtrip(xwl_screen->display);
+    if (ret == -1) {
+        xf86DrvMsg(scrninfo->scrnIndex, X_ERROR,
+                   "failed to dispatch Wayland events: %s\n", strerror(errno));
+        return FALSE;
+    }
 
 #ifdef WITH_LIBDRM
     if (xwl_screen->driver->use_drm && !xwl_drm_initialised(xwl_screen))
@@ -293,10 +288,9 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
     struct xwl_seat *xwl_seat, *itmp;
     struct xwl_window *xwl_window, *wtmp;
 
-    if (xwl_screen->input_listener)
-	wl_display_remove_global_listener(xwl_screen->display,
-					  xwl_screen->input_listener);
-
+    if (xwl_screen->registry)
+        wl_registry_destroy(xwl_screen->registry);
+    xwl_screen->registry = NULL;
 
     xorg_list_for_each_entry_safe(xwl_seat, itmp,
 				  &xwl_screen->seat_list, link) {
@@ -310,7 +304,6 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
 	free(xwl_window);
     }
 
-    xwl_screen->input_listener = NULL;
     xorg_list_init(&xwl_screen->seat_list);
     xorg_list_init(&xwl_screen->damage_window_list);
     xorg_list_init(&xwl_screen->window_list);
@@ -349,6 +342,7 @@ void xwl_screen_post_damage(struct xwl_screen *xwl_screen)
 			      box->x2 - box->x1 + 1,
 			      box->y2 - box->y1 + 1);
 	}
+	wl_surface_commit(xwl_window->surface);
 	DamageEmpty(xwl_window->damage);
     }
 
-- 
1.7.9.5



More information about the wayland-devel mailing list