[RFC wayland v2] Add libwayland-glib for GLib main loop integration

Kristian Høgsberg hoegsberg at gmail.com
Fri Oct 25 20:01:51 CEST 2013


On Wed, Oct 23, 2013 at 02:10:26PM +0200, Quentin Glidic wrote:
> 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.

I'm not convinced we need a separate glib shared library for this.
It's only 150 lines of code and gtk+ already has integration code for
this.  Further, any glib use of wayland that isn't also a gtk+ user
seems very niche, so I don't expect a lot of user of this library.

Kristian

>  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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list