diff options
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | src/egl/eglut/Makefile.am | 15 | ||||
-rw-r--r-- | src/egl/eglut/eglut_wayland.c | 135 |
3 files changed, 163 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 4f6f16f..be9caa1 100644 --- a/configure.ac +++ b/configure.ac @@ -206,6 +206,16 @@ if test "x$x11_enabled" != "xno"; then PKG_CHECK_MODULES(X11, [x11 xext], [x11_enabled=yes], [x11_enabled=no]) fi +AC_ARG_ENABLE([wayland], + [AS_HELP_STRING([--enable-wayland], + [enable support for wayland @<:@default=no@:>@])], + [wayland_enabled="$enableval"], + [wayland_enabled=no]) + +if test "x$wayland_enabled" != "xno"; then + PKG_CHECK_MODULES(WAYLAND, [wayland-client wayland-egl], [wayland_enabled=yes], [wayland_enabled=no]) +fi + dnl GBM is needed for EGL on KMS AC_ARG_ENABLE([gbm], [AS_HELP_STRING([--enable-gbm], @@ -283,6 +293,9 @@ AC_SUBST([OSMESA_LIBS]) AC_SUBST([OSMESA16_LIBS]) AC_SUBST([OSMESA32_LIBS]) AC_SUBST([MESA_GLAPI]) +AC_SUBST([WAYLAND_CFLAGS]) +AC_SUBST([WAYLAND_LIBS]) + AM_CONDITIONAL(HAVE_EGL, test "x$egl_enabled" = "xyes") AM_CONDITIONAL(HAVE_GLESV1, test "x$glesv1_enabled" = "xyes") @@ -296,6 +309,7 @@ AM_CONDITIONAL(HAVE_OSMESA, test "x$osmesa_enabled" = "xyes") AM_CONDITIONAL(HAVE_DRM, test "x$drm_enabled" = "xyes") AM_CONDITIONAL(BUILD_GLTRACE, false) AM_CONDITIONAL(HAVE_MESA_SOURCE, test "x$mesa_source_enabled" = "xyes") +AM_CONDITIONAL(HAVE_WAYLAND, test "x$wayland_enabled" = "xyes") AC_OUTPUT([ Makefile diff --git a/src/egl/eglut/Makefile.am b/src/egl/eglut/Makefile.am index f0ab283..2d2f2af 100644 --- a/src/egl/eglut/Makefile.am +++ b/src/egl/eglut/Makefile.am @@ -29,7 +29,11 @@ if HAVE_EGL if HAVE_X11 eglut_x11 = libeglut_x11.la endif -noinst_LTLIBRARIES = libeglut_screen.la $(eglut_x11) +if HAVE_WAYLAND +eglut_wayland = libeglut_wayland.la +endif + +noinst_LTLIBRARIES = libeglut_screen.la $(eglut_x11) $(eglut_wayland) endif libeglut_screen_la_SOURCES = \ @@ -44,3 +48,12 @@ libeglut_x11_la_SOURCES = \ eglut_x11.c libeglut_x11_la_CFLAGS = $(X11_CFLAGS) $(EGL_CFLAGS) libeglut_x11_la_LIBADD = $(X11_LIBS) $(EGL_LIBS) + + +libeglut_wayland_la_SOURCES = \ + eglut.c \ + eglutint.h \ + eglut_wayland.c + +libeglut_wayland_la_CFLAGS = $(WAYLAND_CFLAGS) $(EGL_CFLAGS) +libeglut_wayland_la_LIBADD = $(WAYLAND_LIBS) $(EGL_LIBS) diff --git a/src/egl/eglut/eglut_wayland.c b/src/egl/eglut/eglut_wayland.c new file mode 100644 index 0000000..61207d2 --- /dev/null +++ b/src/egl/eglut/eglut_wayland.c @@ -0,0 +1,135 @@ +#include <wayland-client.h> +#include <wayland-egl.h> + +#include "eglutint.h" + +struct display { + struct wl_display *display; + struct wl_compositor *compositor; + struct wl_shell *shell; + uint32_t mask; +}; + +struct window { + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; + struct wl_callback *callback; +}; + +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) +{ + struct display *d = data; + + if (strcmp(interface, "wl_compositor") == 0) { + d->compositor = + wl_display_bind(display, id, &wl_compositor_interface); + } else if (strcmp(interface, "wl_shell") == 0) { + d->shell = wl_display_bind(display, id, &wl_shell_interface); + } +} + +static int +event_mask_update(uint32_t mask, void *data) +{ + struct display *d = data; + + d->mask = mask; + + return 0; +} + +void +_eglutNativeInitDisplay(void) +{ + _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); + + _eglut->surface_type = EGL_WINDOW_BIT; +} + +void +_eglutNativeFiniDisplay(void) +{ + wl_display_flush(_eglut->native_dpy); + wl_display_disconnect(_eglut->native_dpy); +} + +void +_eglutNativeInitWindow(struct eglut_window *win, const char *title, + int x, int y, int w, int h) +{ + struct wl_egl_window *native; + + window.surface = wl_compositor_create_surface(display.compositor); + window.shell_surface = wl_shell_get_shell_surface(display.shell, + window.surface); + native = wl_egl_window_create(window.surface, w, h); + + wl_shell_surface_set_toplevel(window.shell_surface); + + win->native.u.window = native; + win->native.width = w; + win->native.height = h; +} + +void +_eglutNativeFiniWindow(struct eglut_window *win) +{ + wl_egl_window_destroy(win->native.u.window); + + wl_shell_surface_destroy(window.shell_surface); + wl_surface_destroy(window.surface); + + if (window.callback) + wl_callback_destroy(window.callback); +} + +static void +draw(void *data, struct wl_callback *callback, uint32_t time); + +static const struct wl_callback_listener frame_listener = { + draw +}; + +static void +draw(void *data, struct wl_callback *callback, uint32_t time) +{ + struct window *window = (struct window *)data; + struct eglut_window *win = _eglut->current; + + if (win->display_cb) + win->display_cb(); + eglSwapBuffers(_eglut->dpy, win->surface); + + if (callback) + wl_callback_destroy(callback); + + window->callback = wl_surface_frame(window->surface); + wl_callback_add_listener(window->callback, &frame_listener, window); +} + +void +_eglutNativeEventLoop(void) +{ + draw(&window, NULL, 0); + + while (1) { + wl_display_iterate(display.display, display.mask); + + if (_eglut->idle_cb) + _eglut->idle_cb(); + } +} |