[PATCH] eglut_wayland: Update to the Wayland 1.0 API

Neil Roberts neil at linux.intel.com
Wed Sep 11 11:33:32 PDT 2013


This fixes build errors with the eglut_wayland backend. In particular
it now uses the wl_registry and the new main loop mechanism from the
Wayland 1.0 API.
---
 src/egl/eglut/eglut_wayland.c | 108 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 94 insertions(+), 14 deletions(-)

diff --git a/src/egl/eglut/eglut_wayland.c b/src/egl/eglut/eglut_wayland.c
index 61207d2..25a51bc 100644
--- a/src/egl/eglut/eglut_wayland.c
+++ b/src/egl/eglut/eglut_wayland.c
@@ -1,6 +1,10 @@
 #include <wayland-client.h>
 #include <wayland-egl.h>
 
+#include <poll.h>
+#include <errno.h>
+#include <string.h>
+
 #include "eglutint.h"
 
 struct display {
@@ -20,42 +24,74 @@ static struct display display = {0, };
 static struct window window = {0, };
 
 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);
    }
 }
 
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+                              uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+   registry_handle_global,
+   registry_handle_global_remove
+};
+
+static void
+sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
+{
+   int *done = data;
+
+   *done = 1;
+   wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener sync_listener = {
+   sync_callback
+};
+
 static int
-event_mask_update(uint32_t mask, void *data)
+wayland_roundtrip(struct wl_display *display)
 {
-   struct display *d = data;
+   struct wl_callback *callback;
+   int done = 0, ret = 0;
 
-   d->mask = mask;
+   callback = wl_display_sync(display);
+   wl_callback_add_listener(callback, &sync_listener, &done);
+   while (ret != -1 && !done)
+      ret = wl_display_dispatch(display);
 
-   return 0;
+   if (!done)
+      wl_callback_destroy(callback);
+
+   return ret;
 }
 
 void
 _eglutNativeInitDisplay(void)
 {
+   struct wl_registry *registry;
+
    _eglut->native_dpy =  display.display = wl_display_connect(NULL);
 
    if (!_eglut->native_dpy)
       _eglutFatal("failed to initialize native display");
 
-   wl_display_add_global_listener(_eglut->native_dpy,
-         display_handle_global, &display);
-
-   wl_display_get_fd(_eglut->native_dpy, event_mask_update, &display);
-   wl_display_iterate(_eglut->native_dpy, WL_DISPLAY_READABLE);
+   registry = wl_display_get_registry(_eglut->native_dpy);
+   wl_registry_add_listener(registry, &registry_listener, &display);
+   wayland_roundtrip(_eglut->native_dpy);
+   wl_registry_destroy(registry);
 
    _eglut->surface_type = EGL_WINDOW_BIT;
 }
@@ -124,12 +160,56 @@ draw(void *data, struct wl_callback *callback, uint32_t time)
 void
 _eglutNativeEventLoop(void)
 {
+   struct pollfd pollfd;
+   int ret;
+
    draw(&window, NULL, 0);
 
+   pollfd.fd = wl_display_get_fd(display.display);
+   pollfd.events = POLLIN;
+   pollfd.revents = 0;
+
    while (1) {
-      wl_display_iterate(display.display, display.mask);
+      wl_display_dispatch_pending(display.display);
 
       if (_eglut->idle_cb)
          _eglut->idle_cb();
+
+      ret = wl_display_flush(display.display);
+      if (ret < 0 && errno == EAGAIN)
+         pollfd.events |= POLLOUT;
+      else if (ret < 0)
+         break;
+
+      if (poll(&pollfd, 1, _eglut->redisplay ? 0 : -1) == -1)
+         break;
+
+      if (pollfd.revents & (POLLERR | POLLHUP))
+         break;
+
+      if (pollfd.revents & POLLIN) {
+         ret = wl_display_dispatch(display.display);
+         if (ret == -1)
+            break;
+      }
+
+      if (pollfd.revents & POLLOUT) {
+         ret = wl_display_flush(display.display);
+         if (ret == 0)
+            pollfd.events &= ~POLLOUT;
+         else if (ret == -1 && errno != EAGAIN)
+            break;
+      }
+
+      if (_eglut->redisplay) {
+         struct eglut_window *win = _eglut->current;
+
+         _eglut->redisplay = 0;
+
+         if (win->display_cb)
+            win->display_cb();
+
+         eglSwapBuffers(_eglut->dpy, win->surface);
+      }
    }
 }
-- 
1.8.3.1



More information about the wayland-devel mailing list