[mutter] backend: Poll events from the host X11 server ourselves
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] backend: Poll events from the host X11 server ourselves
- Date: Tue, 22 Apr 2014 14:26:25 +0000 (UTC)
commit 3d091e514df1cb13b080413fa22351ec4ac4b3d9
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Tue Apr 22 10:14:59 2014 -0400
backend: Poll events from the host X11 server ourselves
I was accidentally pulling events from the Xwayland server under
nested for the idle monitor, which is wrong. Whoops.
src/backends/meta-backend-private.h | 2 +
src/backends/meta-backend.c | 16 +++
src/backends/x11/meta-backend-x11.c | 172 ++++++++++++++++++++++++++++-------
src/core/events.c | 6 -
4 files changed, 157 insertions(+), 39 deletions(-)
---
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index d0de72b..1f866d0 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -49,6 +49,8 @@ struct _MetaBackendClass
{
GObjectClass parent_class;
+ void (* post_init) (MetaBackend *backend);
+
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
int device_id);
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend);
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 42a4197..cda4bc3 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -78,12 +78,20 @@ meta_backend_finalize (GObject *object)
}
static void
+meta_backend_real_post_init (MetaBackend *backend)
+{
+ /* Do nothing */
+}
+
+static void
meta_backend_class_init (MetaBackendClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_backend_constructed;
object_class->finalize = meta_backend_finalize;
+
+ klass->post_init = meta_backend_real_post_init;
}
static void
@@ -109,6 +117,12 @@ meta_backend_create_idle_monitor (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id);
}
+static void
+meta_backend_post_init (MetaBackend *backend)
+{
+ META_BACKEND_GET_CLASS (backend)->post_init (backend);
+}
+
MetaIdleMonitor *
meta_backend_get_idle_monitor (MetaBackend *backend,
int device_id)
@@ -217,4 +231,6 @@ meta_clutter_init (void)
source = g_source_new (&event_funcs, sizeof (GSource));
g_source_attach (source, NULL);
g_source_unref (source);
+
+ meta_backend_post_init (_backend);
}
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index c8fa772..2a3636d 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -26,15 +26,149 @@
#include "meta-backend-x11.h"
-#include <gdk/gdkx.h>
#include <clutter/x11/clutter-x11.h>
+#include <X11/extensions/sync.h>
+
#include <meta/util.h>
#include "meta-idle-monitor-xsync.h"
#include "meta-monitor-manager-xrandr.h"
#include "backends/meta-monitor-manager-dummy.h"
-G_DEFINE_TYPE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND);
+struct _MetaBackendX11Private
+{
+ /* The host X11 display */
+ Display *xdisplay;
+ GSource *source;
+
+ int xsync_event_base;
+ int xsync_error_base;
+};
+typedef struct _MetaBackendX11Private MetaBackendX11Private;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND);
+
+static void
+handle_alarm_notify (MetaBackend *backend,
+ XEvent *xevent)
+{
+ int i;
+
+ for (i = 0; i <= backend->device_id_max; i++)
+ if (backend->device_monitors[i])
+ meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*)xevent);
+}
+
+static void
+handle_host_xevent (MetaBackend *backend,
+ XEvent *xevent)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+
+ if (xevent->type == (priv->xsync_event_base + XSyncAlarmNotify))
+ handle_alarm_notify (backend, xevent);
+
+ clutter_x11_handle_event (xevent);
+}
+
+typedef struct {
+ GSource base;
+ GPollFD event_poll_fd;
+ MetaBackend *backend;
+} XEventSource;
+
+static gboolean
+x_event_source_prepare (GSource *source,
+ int *timeout)
+{
+ XEventSource *x_source = (XEventSource *) source;
+ MetaBackend *backend = x_source->backend;
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+
+ *timeout = -1;
+
+ return XPending (priv->xdisplay);
+}
+
+static gboolean
+x_event_source_check (GSource *source)
+{
+ XEventSource *x_source = (XEventSource *) source;
+ MetaBackend *backend = x_source->backend;
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ MetaBackendX11Private *priv = meta_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 = (XEventSource *) source;
+ MetaBackend *backend = x_source->backend;
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+
+ while (XPending (priv->xdisplay))
+ {
+ XEvent xev;
+
+ XNextEvent (priv->xdisplay, &xev);
+
+ handle_host_xevent (backend, &xev);
+ }
+
+ 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 (MetaBackend *backend)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+ GSource *source;
+ XEventSource *x_source;
+
+ source = g_source_new (&x_event_funcs, sizeof (XEventSource));
+ x_source = (XEventSource *) source;
+ x_source->backend = backend;
+ x_source->event_poll_fd.fd = ConnectionNumber (priv->xdisplay);
+ x_source->event_poll_fd.events = G_IO_IN;
+ g_source_add_poll (source, &x_source->event_poll_fd);
+
+ g_source_attach (source, NULL);
+ return source;
+}
+
+static void
+meta_backend_x11_post_init (MetaBackend *backend)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+ int major, minor;
+
+ priv->xdisplay = clutter_x11_get_default_display ();
+
+ priv->source = x_event_source_new (backend);
+
+ if (!XSyncQueryExtension (priv->xdisplay, &priv->xsync_event_base, &priv->xsync_error_base))
+ meta_fatal ("Could not initialize XSync");
+
+ if (!XSyncInitialize (priv->xdisplay, &major, &minor))
+ meta_fatal ("Could not initialize XSync");
+
+ META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
+}
static MetaIdleMonitor *
meta_backend_x11_create_idle_monitor (MetaBackend *backend,
@@ -62,6 +196,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
{
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
+ backend_class->post_init = meta_backend_x11_post_init;
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;
}
@@ -69,35 +204,6 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
static void
meta_backend_x11_init (MetaBackendX11 *x11)
{
- /* When running as an X11 compositor, we install our own event filter and
- * pass events to Clutter explicitly, so we need to prevent Clutter from
- * handling our events.
- *
- * However, when running as a Wayland compostior under X11 nested, Clutter
- * Clutter needs to see events related to its own window. We need to
- * eventually replace this with a proper frontend / backend split: Clutter
- * under nested is connecting to the "host X server" to get its events it
- * needs to put up a window, and GTK+ is connecting to the "inner X server".
- * The two would the same in the X11 compositor case, but not when running
- * XWayland as a Wayland compositor.
- */
- if (!meta_is_wayland_compositor ())
- {
- clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
- clutter_x11_disable_event_retrieval ();
- }
-}
-
-void
-meta_backend_x11_handle_alarm_notify (MetaBackend *backend,
- XEvent *xevent)
-{
- int i;
-
- if (!META_IS_BACKEND_X11 (backend))
- return;
-
- for (i = 0; i <= backend->device_id_max; i++)
- if (backend->device_monitors[i])
- meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*)xevent);
+ /* We do X11 event retrieval ourselves */
+ clutter_x11_disable_event_retrieval ();
}
diff --git a/src/core/events.c b/src/core/events.c
index 5a70c6d..370c3af 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -35,7 +35,6 @@
#include "bell.h"
#include "workspace-private.h"
#include "backends/meta-backend.h"
-#include "backends/x11/meta-backend-x11.h"
#include "backends/native/meta-idle-monitor-native.h"
#include "x11/window-x11.h"
@@ -1264,11 +1263,6 @@ handle_other_xevent (MetaDisplay *display,
meta_window_update_sync_request_counter (alarm_window, new_counter_value);
bypass_gtk = TRUE; /* GTK doesn't want to see this really */
}
- else
- {
- MetaBackend *backend = meta_get_backend ();
- meta_backend_x11_handle_alarm_notify (backend, event);
- }
goto out;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]