[PATCH] eglut_wayland: Update to the Wayland 1.0 API
Armin K.
krejzi at email.com
Wed Sep 11 12:54:42 PDT 2013
On 09/11/2013 08:33 PM, Neil Roberts wrote:
> 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.
> ---
FYI, I've posted a patch to mesa-dev few weeks ago too, but yours seems
better, since mine didn't include polling stuff, but es2gears did
actually work.
http://lists.freedesktop.org/archives/mesa-dev/2013-August/043858.html
> 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, ®istry_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);
> + }
> }
> }
>
More information about the wayland-devel
mailing list