[gnome-flashback] backends: open a connection to the X server
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] backends: open a connection to the X server
- Date: Sat, 9 Sep 2017 22:18:41 +0000 (UTC)
commit 2636c3d5bdec2945e144f234084eb41f59dd28a3
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Sat Sep 9 23:28:21 2017 +0300
backends: open a connection to the X server
backends/gf-backend-native.c | 11 ++
backends/gf-backend-private.h | 2 +
backends/gf-backend-x11-cm.c | 12 +++
backends/gf-backend-x11-nested.c | 12 +++
backends/gf-backend-x11-private.h | 6 +
backends/gf-backend-x11.c | 198 +++++++++++++++++++++++++++++++++++++
backends/gf-backend.c | 9 ++
configure.ac | 1 +
8 files changed, 251 insertions(+), 0 deletions(-)
---
diff --git a/backends/gf-backend-native.c b/backends/gf-backend-native.c
index 8ae51ba..4f1aef0 100644
--- a/backends/gf-backend-native.c
+++ b/backends/gf-backend-native.c
@@ -34,8 +34,19 @@ struct _GfBackendNative
G_DEFINE_TYPE (GfBackendNative, gf_backend_native, GF_TYPE_BACKEND)
static void
+gf_backend_native_post_init (GfBackend *backend)
+{
+ GF_BACKEND_CLASS (gf_backend_native_parent_class)->post_init (backend);
+}
+
+static void
gf_backend_native_class_init (GfBackendNativeClass *native_class)
{
+ GfBackendClass *backend_class;
+
+ backend_class = GF_BACKEND_CLASS (native_class);
+
+ backend_class->post_init = gf_backend_native_post_init;
}
static void
diff --git a/backends/gf-backend-private.h b/backends/gf-backend-private.h
index ac33adf..01643b3 100644
--- a/backends/gf-backend-private.h
+++ b/backends/gf-backend-private.h
@@ -33,6 +33,8 @@ G_BEGIN_DECLS
struct _GfBackendClass
{
GObjectClass parent_class;
+
+ void (* post_init) (GfBackend *backend);
};
G_END_DECLS
diff --git a/backends/gf-backend-x11-cm.c b/backends/gf-backend-x11-cm.c
index f5ff12a..876e398 100644
--- a/backends/gf-backend-x11-cm.c
+++ b/backends/gf-backend-x11-cm.c
@@ -29,9 +29,21 @@ struct _GfBackendX11Cm
G_DEFINE_TYPE (GfBackendX11Cm, gf_backend_x11_cm, GF_TYPE_BACKEND_X11)
+static gboolean
+gf_backend_x11_cm_handle_host_xevent (GfBackendX11 *x11,
+ XEvent *event)
+{
+ return FALSE;
+}
+
static void
gf_backend_x11_cm_class_init (GfBackendX11CmClass *x11_cm_class)
{
+ GfBackendX11Class *backend_x11_class;
+
+ backend_x11_class = GF_BACKEND_X11_CLASS (x11_cm_class);
+
+ backend_x11_class->handle_host_xevent = gf_backend_x11_cm_handle_host_xevent;
}
static void
diff --git a/backends/gf-backend-x11-nested.c b/backends/gf-backend-x11-nested.c
index 591eda0..a129df3 100644
--- a/backends/gf-backend-x11-nested.c
+++ b/backends/gf-backend-x11-nested.c
@@ -29,9 +29,21 @@ struct _GfBackendX11Nested
G_DEFINE_TYPE (GfBackendX11Nested, gf_backend_x11_nested, GF_TYPE_BACKEND_X11)
+static gboolean
+gf_backend_x11_nested_handle_host_xevent (GfBackendX11 *x11,
+ XEvent *event)
+{
+ return FALSE;
+}
+
static void
gf_backend_x11_nested_class_init (GfBackendX11NestedClass *x11_nested_class)
{
+ GfBackendX11Class *backend_x11_class;
+
+ backend_x11_class = GF_BACKEND_X11_CLASS (x11_nested_class);
+
+ backend_x11_class->handle_host_xevent = gf_backend_x11_nested_handle_host_xevent;
}
static void
diff --git a/backends/gf-backend-x11-private.h b/backends/gf-backend-x11-private.h
index 22d9e6a..d3bd209 100644
--- a/backends/gf-backend-x11-private.h
+++ b/backends/gf-backend-x11-private.h
@@ -26,6 +26,7 @@
#ifndef GF_BACKEND_X11_PRIVATE_H
#define GF_BACKEND_X11_PRIVATE_H
+#include <X11/Xlib.h>
#include "gf-backend-private.h"
G_BEGIN_DECLS
@@ -37,8 +38,13 @@ G_DECLARE_DERIVABLE_TYPE (GfBackendX11, gf_backend_x11,
struct _GfBackendX11Class
{
GfBackendClass parent_class;
+
+ gboolean (* handle_host_xevent) (GfBackendX11 *x11,
+ XEvent *event);
};
+Display *gf_backend_x11_get_xdisplay (GfBackendX11 *x11);
+
G_END_DECLS
#endif
diff --git a/backends/gf-backend-x11.c b/backends/gf-backend-x11.c
index 5101690..9f3f068 100644
--- a/backends/gf-backend-x11.c
+++ b/backends/gf-backend-x11.c
@@ -29,24 +29,165 @@
#include "gf-backend-x11-private.h"
+typedef struct
+{
+ GSource source;
+ GPollFD event_poll_fd;
+
+ GfBackend *backend;
+} XEventSource;
+
+typedef struct
+{
+ Display *xdisplay;
+
+ GSource *source;
+} GfBackendX11Private;
+
static void
initable_iface_init (GInitableIface *initable_iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GfBackendX11, gf_backend_x11, GF_TYPE_BACKEND,
+ G_ADD_PRIVATE (GfBackendX11)
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
initable_iface_init))
+static void
+handle_host_xevent (GfBackend *backend,
+ XEvent *event)
+{
+ GfBackendX11 *x11;
+ GfBackendX11Private *priv;
+
+ x11 = GF_BACKEND_X11 (backend);
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ XGetEventData (priv->xdisplay, &event->xcookie);
+
+ GF_BACKEND_X11_GET_CLASS (x11)->handle_host_xevent (x11, event);
+
+ XFreeEventData (priv->xdisplay, &event->xcookie);
+}
+
+static gboolean
+x_event_source_prepare (GSource *source,
+ int *timeout)
+{
+ XEventSource *x_source;
+ GfBackendX11 *x11;
+ GfBackendX11Private *priv;
+
+ x_source = (XEventSource *) source;
+ x11 = GF_BACKEND_X11 (x_source->backend);
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ *timeout = -1;
+
+ return XPending (priv->xdisplay);
+}
+
+static gboolean
+x_event_source_check (GSource *source)
+{
+ XEventSource *x_source;
+ GfBackendX11 *x11;
+ GfBackendX11Private *priv;
+
+ x_source = (XEventSource *) source;
+ x11 = GF_BACKEND_X11 (x_source->backend);
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ return XPending (priv->xdisplay);
+}
+
+static gboolean
+x_event_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ XEventSource *x_source;
+ GfBackendX11 *x11;
+ GfBackendX11Private *priv;
+
+ x_source = (XEventSource *) source;
+ x11 = GF_BACKEND_X11 (x_source->backend);
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ while (XPending (priv->xdisplay))
+ {
+ XEvent event;
+
+ XNextEvent (priv->xdisplay, &event);
+
+ handle_host_xevent (x_source->backend, &event);
+ }
+
+ return TRUE;
+}
+
+static GSourceFuncs x_event_funcs =
+ {
+ x_event_source_prepare,
+ x_event_source_check,
+ x_event_source_dispatch,
+ };
+
+static GSource *
+x_event_source_new (GfBackend *backend)
+{
+ GfBackendX11 *x11;
+ GfBackendX11Private *priv;
+ GSource *source;
+ XEventSource *x_source;
+
+ x11 = GF_BACKEND_X11 (backend);
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ source = g_source_new (&x_event_funcs, sizeof (XEventSource));
+
+ x_source = (XEventSource *) source;
+ x_source->event_poll_fd.fd = ConnectionNumber (priv->xdisplay);
+ x_source->event_poll_fd.events = G_IO_IN;
+ x_source->backend = backend;
+
+ g_source_add_poll (source, &x_source->event_poll_fd);
+ g_source_attach (source, NULL);
+
+ return source;
+}
+
static gboolean
gf_backend_x11_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
GfBackendX11 *x11;
+ GfBackendX11Private *priv;
GInitableIface *parent_iface;
+ const gchar *display;
x11 = GF_BACKEND_X11 (initable);
+ priv = gf_backend_x11_get_instance_private (x11);
parent_iface = g_type_interface_peek_parent (G_INITABLE_GET_IFACE (x11));
+ display = g_getenv ("DISPLAY");
+ if (!display)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Unable to open display, DISPLAY not set");
+
+ return FALSE;
+ }
+
+ priv->xdisplay = XOpenDisplay (display);
+ if (!priv->xdisplay)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Unable to open display '%s'", display);
+
+ return FALSE;
+ }
+
return parent_iface->init (initable, cancellable, error);
}
@@ -57,11 +198,68 @@ initable_iface_init (GInitableIface *initable_iface)
}
static void
+gf_backend_x11_finalize (GObject *object)
+{
+ GfBackendX11 *x11;
+ GfBackendX11Private *priv;
+
+ x11 = GF_BACKEND_X11 (object);
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ if (priv->source != NULL)
+ {
+ g_source_unref (priv->source);
+ priv->source = NULL;
+ }
+
+ if (priv->xdisplay != NULL)
+ {
+ XCloseDisplay (priv->xdisplay);
+ priv->xdisplay = NULL;
+ }
+
+ G_OBJECT_CLASS (gf_backend_x11_parent_class)->finalize (object);
+}
+
+static void
+gf_backend_x11_post_init (GfBackend *backend)
+{
+ GfBackendX11 *x11;
+ GfBackendX11Private *priv;
+
+ x11 = GF_BACKEND_X11 (backend);
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ priv->source = x_event_source_new (backend);
+
+ GF_BACKEND_CLASS (gf_backend_x11_parent_class)->post_init (backend);
+}
+
+static void
gf_backend_x11_class_init (GfBackendX11Class *x11_class)
{
+ GObjectClass *object_class;
+ GfBackendClass *backend_class;
+
+ object_class = G_OBJECT_CLASS (x11_class);
+ backend_class = GF_BACKEND_CLASS (x11_class);
+
+ object_class->finalize = gf_backend_x11_finalize;
+
+ backend_class->post_init = gf_backend_x11_post_init;
}
static void
gf_backend_x11_init (GfBackendX11 *x11)
{
}
+
+Display *
+gf_backend_x11_get_xdisplay (GfBackendX11 *x11)
+{
+ GfBackendX11Private *priv;
+
+ priv = gf_backend_x11_get_instance_private (x11);
+
+ return priv->xdisplay;
+}
diff --git a/backends/gf-backend.c b/backends/gf-backend.c
index 28f6d71..b822bf7 100644
--- a/backends/gf-backend.c
+++ b/backends/gf-backend.c
@@ -86,6 +86,11 @@ gf_backend_dispose (GObject *object)
}
static void
+gf_backend_real_post_init (GfBackend *backend)
+{
+}
+
+static void
gf_backend_class_init (GfBackendClass *backend_class)
{
GObjectClass *object_class;
@@ -93,6 +98,8 @@ gf_backend_class_init (GfBackendClass *backend_class)
object_class = G_OBJECT_CLASS (backend_class);
object_class->dispose = gf_backend_dispose;
+
+ backend_class->post_init = gf_backend_real_post_init;
}
static void
@@ -139,5 +146,7 @@ gf_backend_new (GfBackendType type)
return NULL;
}
+ GF_BACKEND_GET_CLASS (backend)->post_init (backend);
+
return backend;
}
diff --git a/configure.ac b/configure.ac
index 983e4af..cacd905 100644
--- a/configure.ac
+++ b/configure.ac
@@ -102,6 +102,7 @@ PKG_CHECK_MODULES([BACKENDS], [
gio-2.0 >= $GLIB_REQUIRED
gio-unix-2.0 >= $GLIB_REQUIRED
glib-2.0 >= $GLIB_REQUIRED
+ x11
])
PKG_CHECK_MODULES([GNOME_FLASHBACK], [
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]