[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