[RFC wayland v2] Add libwayland-glib for GLib main loop integration
Quentin Glidic
sardemff7+wayland at sardemff7.net
Wed Oct 23 14:10:26 CEST 2013
From: Quentin Glidic <sardemff7+git at sardemff7.net>
Signed-off-by: Quentin Glidic <sardemff7+git at sardemff7.net>
---
Here is a new version of my GLib main loop integration for Wayland.
Now everything is in libwayland-client (I didn’t work on the server
side) and package detection can be done using the pkg-config file
or the header if needed.
configure.ac | 22 ++++-
src/Makefile.am | 17 ++++
src/wayland-client-glib.c | 182 ++++++++++++++++++++++++++++++++++++++++++
src/wayland-client-glib.h | 46 +++++++++++
src/wayland-client-glib.pc.in | 9 +++
5 files changed, 275 insertions(+), 1 deletion(-)
create mode 100644 src/wayland-client-glib.c
create mode 100644 src/wayland-client-glib.h
create mode 100644 src/wayland-client-glib.pc.in
diff --git a/configure.ac b/configure.ac
index fa924ae..ca50c65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,7 +50,7 @@ AC_CHECK_DECL(TFD_CLOEXEC,[],
AC_CHECK_DECL(CLOCK_MONOTONIC,[],
[AC_MSG_ERROR("CLOCK_MONOTONIC is needed to compile wayland")],
[[#include <time.h>]])
-AC_CHECK_HEADERS([execinfo.h])
+AC_CHECK_HEADERS([execinfo.h errno.h])
AC_ARG_ENABLE([scanner],
[AC_HELP_STRING([--disable-scanner],
@@ -126,6 +126,25 @@ if test "x$enable_documentation" = "xyes"; then
fi
AM_CONDITIONAL([HAVE_PUBLICAN], [test "x$PUBLICAN" != "x"])
+
+# GLib main loop integration library
+
+glib_min_major="2"
+glib_min_minor="36"
+glib_min_version="${glib_min_major}.${glib_min_minor}"
+
+AC_ARG_ENABLE([glib],
+ [AC_HELP_STRING([--enable-glib],
+ [Enable GLib main loop integration library])],
+ [],
+ [enable_glib=no])
+if test "x$enable_glib" = "xyes"; then
+ PKG_CHECK_MODULES(GLIB, [glib-2.0 >= $glib_min_version])
+ AC_DEFINE_UNQUOTED([GLIB_VERSION_MIN_REQUIRED], [(G_ENCODE_VERSION(${glib_min_major},${glib_min_minor}))], [The lower GLib version supported])
+fi
+AM_CONDITIONAL([ENABLE_GLIB], [test "x$enable_glib" = "xyes"])
+
+
AC_CONFIG_FILES([Makefile
cursor/Makefile
cursor/wayland-cursor.pc
@@ -140,6 +159,7 @@ AC_CONFIG_FILES([Makefile
src/wayland-scanner-uninstalled.pc
src/wayland-server.pc
src/wayland-client.pc
+ src/wayland-client-glib.pc
src/wayland-scanner.pc
src/wayland-version.h
protocol/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 4226f63..9026e5a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,6 +28,8 @@ libwayland_server_la_SOURCES = \
libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm
libwayland_client_la_LDFLAGS = -version-info 1:0:1
+libwayland_client_la_CFLAGS = $(AM_CFLAGS)
+libwayland_client_la_CPPFLAGS = $(AM_CPPFLAGS)
libwayland_client_la_SOURCES = \
wayland-protocol.c \
wayland-client.c
@@ -35,6 +37,21 @@ libwayland_client_la_SOURCES = \
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = wayland-client.pc wayland-server.pc
+if ENABLE_GLIB
+pkgconfig_DATA += wayland-client-glib.pc
+
+include_HEADERS += \
+ wayland-client-glib.h
+
+libwayland_client_la_SOURCES += \
+ wayland-client-glib.h \
+ wayland-client-glib.c
+
+libwayland_client_la_CPPFLAGS += -DG_LOG_DOMAIN=\"GWayland\"
+libwayland_client_la_CFLAGS += $(GLIB_CFLAGS)
+libwayland_client_la_LIBADD += $(GLIB_LIBS)
+endif
+
AM_CPPFLAGS = $(FFI_CFLAGS)
AM_CFLAGS = $(GCC_CFLAGS)
diff --git a/src/wayland-client-glib.c b/src/wayland-client-glib.c
new file mode 100644
index 0000000..1577abb
--- /dev/null
+++ b/src/wayland-client-glib.c
@@ -0,0 +1,182 @@
+/*
+ * wayland-client-glib - Wayland integration to GLib main loop
+ *
+ * Copyright © 2012-2013 Quentin "Sardem FF7" Glidic
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif /* HAVE_ERRNO_H */
+
+#include <glib.h>
+#include <wayland-client.h>
+
+#include <wayland-client-glib.h>
+
+struct _GWaylandSource {
+ GSource source;
+ gboolean display_owned;
+ struct wl_display *display;
+ gpointer fd;
+ int error;
+};
+
+static gboolean
+_g_wayland_source_prepare(GSource *source, gint *timeout)
+{
+ GWaylandSource *self = (GWaylandSource *)source;
+
+ if ( wl_display_flush(self->display) < 0)
+ self->error = errno;
+
+ *timeout = -1;
+ return FALSE;
+}
+
+static gboolean
+_g_wayland_source_check(GSource *source)
+{
+ GWaylandSource *self = (GWaylandSource *)source;
+
+ return ( g_source_query_unix_fd(source, self->fd) > 0 );
+}
+
+static gboolean
+_g_wayland_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
+{
+ GWaylandSource *self = (GWaylandSource *)source;
+
+ if ( self->error > 0 )
+ {
+ errno = self->error;
+ if ( callback != NULL )
+ return callback(user_data);
+ return FALSE;
+ }
+
+ GIOCondition revents;
+ revents = g_source_query_unix_fd(source, self->fd);
+
+ if ( revents & G_IO_IN )
+ {
+ if ( wl_display_dispatch(self->display) < 0 )
+ {
+ if ( callback != NULL )
+ return callback(user_data);
+ return FALSE;
+ }
+ }
+
+ errno = 0;
+ if ( revents & (G_IO_ERR | G_IO_HUP) )
+ {
+ if ( callback != NULL )
+ return callback(user_data);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+_g_wayland_source_finalize(GSource *source)
+{
+ GWaylandSource *self = (GWaylandSource *)source;
+
+ if ( self->display_owned )
+ wl_display_disconnect(self->display);
+}
+
+static GSourceFuncs _g_wayland_source_funcs = {
+ _g_wayland_source_prepare,
+ _g_wayland_source_check,
+ _g_wayland_source_dispatch,
+ _g_wayland_source_finalize
+};
+
+
+WL_EXPORT GWaylandSource *
+g_wayland_source_new(GMainContext *context, const gchar *name)
+{
+ struct wl_display *display;
+ GWaylandSource *source;
+
+ display = wl_display_connect(name);
+ if ( display == NULL )
+ return NULL;
+
+ source = g_wayland_source_new_for_display(context, display);
+ source->display_owned = TRUE;
+ return source;
+}
+
+WL_EXPORT GWaylandSource *
+g_wayland_source_new_for_display(GMainContext *context, struct wl_display *display)
+{
+ GWaylandSource *source;
+
+ source = (GWaylandSource *)g_source_new(&_g_wayland_source_funcs, sizeof(GWaylandSource));
+
+ source->display = display;
+
+ source->fd = g_source_add_unix_fd((GSource *)source, wl_display_get_fd(display), G_IO_IN | G_IO_ERR | G_IO_HUP);
+
+ g_source_attach((GSource *)source, context);
+
+ return source;
+}
+
+WL_EXPORT void
+g_wayland_source_ref(GWaylandSource *self)
+{
+ g_return_if_fail(self != NULL);
+
+ g_source_ref((GSource *)self);
+}
+
+WL_EXPORT void
+g_wayland_source_unref(GWaylandSource *self)
+{
+ g_return_if_fail(self != NULL);
+
+ g_source_unref((GSource *)self);
+}
+
+WL_EXPORT void
+g_wayland_source_set_error_callback(GWaylandSource *self, GSourceFunc callback, gpointer user_data, GDestroyNotify destroy_notify)
+{
+ g_return_if_fail(self != NULL);
+
+ g_source_set_callback((GSource *)self, callback, user_data, destroy_notify);
+}
+
+WL_EXPORT struct wl_display *
+g_wayland_source_get_display(GWaylandSource *self)
+{
+ g_return_val_if_fail(self != NULL, NULL);
+
+ return self->display;
+}
diff --git a/src/wayland-client-glib.h b/src/wayland-client-glib.h
new file mode 100644
index 0000000..0c10bd0
--- /dev/null
+++ b/src/wayland-client-glib.h
@@ -0,0 +1,46 @@
+/*
+ * wayland-client-glib - Wayland integration to GLib main loop
+ *
+ * Copyright © 2012-2013 Quentin "Sardem FF7" Glidic
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef WAYLAND_CLIENT_GLIB_H
+#define WAYLAND_CLIENT_GLIB_H
+
+#include <wayland-client.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GWaylandSource GWaylandSource;
+
+GWaylandSource *g_wayland_source_new(GMainContext *context, const gchar *name);
+GWaylandSource *g_wayland_source_new_for_display(GMainContext *context, struct wl_display *display);
+void g_wayland_source_ref(GWaylandSource *self);
+void g_wayland_source_unref(GWaylandSource *self);
+
+void g_wayland_source_set_error_callback(GWaylandSource *self, GSourceFunc callback, gpointer user_data, GDestroyNotify destroy_notify);
+struct wl_display *g_wayland_source_get_display(GWaylandSource *source);
+
+G_END_DECLS
+
+#endif /* WAYLAND_CLIENT_GLIB_H */
diff --git a/src/wayland-client-glib.pc.in b/src/wayland-client-glib.pc.in
new file mode 100644
index 0000000..b88de4f
--- /dev/null
+++ b/src/wayland-client-glib.pc.in
@@ -0,0 +1,9 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: wayland-client-glib
+Description: Wayland integration to GLib main loop
+Version: @VERSION@
+Requires: wayland-client glib-2.0
--
1.8.4.1
More information about the wayland-devel
mailing list