[mutter] backends/x11: Split up X11 backend into Cm and Nested
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] backends/x11: Split up X11 backend into Cm and Nested
- Date: Wed, 15 Feb 2017 06:04:57 +0000 (UTC)
commit 6d6412384938b1fe2a5e93e4d793d97aa0ad6bca
Author: Jonas Ådahl <jadahl gmail com>
Date: Fri Jan 27 23:04:02 2017 +0800
backends/x11: Split up X11 backend into Cm and Nested
Split up the X11 backend into two parts, one for running as a
Compositing Manager, and one for running as a nested Wayland
compositor.
This commit also cleans up the compositor configuration calculation,
attempting to make it more approachable.
https://bugzilla.gnome.org/show_bug.cgi?id=777800
src/Makefile.am | 4 +
src/backends/x11/cm/meta-backend-x11-cm.c | 177 +++++++++++++++
src/backends/x11/cm/meta-backend-x11-cm.h | 31 +++
src/backends/x11/meta-backend-x11.c | 245 +++------------------
src/backends/x11/meta-backend-x11.h | 7 +
src/backends/x11/nested/meta-backend-x11-nested.c | 168 ++++++++++++++
src/backends/x11/nested/meta-backend-x11-nested.h | 31 +++
src/core/main.c | 68 +++++-
8 files changed, 511 insertions(+), 220 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b5c0d5a..2e30596 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -135,6 +135,10 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/x11/meta-clutter-backend-x11.h \
backends/x11/meta-cursor-renderer-x11.c \
backends/x11/meta-cursor-renderer-x11.h \
+ backends/x11/cm/meta-backend-x11-cm.c \
+ backends/x11/cm/meta-backend-x11-cm.h \
+ backends/x11/nested/meta-backend-x11-nested.c \
+ backends/x11/nested/meta-backend-x11-nested.h \
backends/x11/nested/meta-cursor-renderer-x11-nested.c \
backends/x11/nested/meta-cursor-renderer-x11-nested.h \
backends/x11/meta-idle-monitor-xsync.c \
diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c
new file mode 100644
index 0000000..ac9fc25
--- /dev/null
+++ b/src/backends/x11/cm/meta-backend-x11-cm.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "backends/x11/cm/meta-backend-x11-cm.h"
+
+#include "backends/meta-backend-private.h"
+#include "backends/x11/meta-cursor-renderer-x11.h"
+#include "backends/x11/meta-monitor-manager-xrandr.h"
+
+struct _MetaBackendX11Cm
+{
+ MetaBackendX11 parent;
+};
+
+G_DEFINE_TYPE (MetaBackendX11Cm, meta_backend_x11_cm, META_TYPE_BACKEND_X11)
+
+static void
+take_touch_grab (MetaBackend *backend)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
+ unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
+ XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
+ XIGrabModifiers mods = { XIAnyModifier, 0 };
+
+ XISetMask (mask.mask, XI_TouchBegin);
+ XISetMask (mask.mask, XI_TouchUpdate);
+ XISetMask (mask.mask, XI_TouchEnd);
+
+ XIGrabTouchBegin (xdisplay, META_VIRTUAL_CORE_POINTER_ID,
+ DefaultRootWindow (xdisplay),
+ False, &mask, 1, &mods);
+}
+
+static void
+meta_backend_x11_cm_post_init (MetaBackend *backend)
+{
+ MetaBackendClass *parent_backend_class =
+ META_BACKEND_CLASS (meta_backend_x11_cm_parent_class);
+
+ parent_backend_class->post_init (backend);
+
+ take_touch_grab (backend);
+}
+
+static MetaMonitorManager *
+meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend)
+{
+ return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
+}
+
+static MetaCursorRenderer *
+meta_backend_x11_cm_create_cursor_renderer (MetaBackend *backend)
+{
+ return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
+}
+
+static void
+meta_backend_x11_cm_update_screen_size (MetaBackend *backend,
+ int width,
+ int height)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
+ Window xwin = meta_backend_x11_get_xwindow (x11);
+
+ XResizeWindow (xdisplay, xwin, width, height);
+}
+
+static void
+meta_backend_x11_cm_select_stage_events (MetaBackend *backend)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
+ Window xwin = meta_backend_x11_get_xwindow (x11);
+ unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
+ XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
+
+ XISetMask (mask.mask, XI_KeyPress);
+ XISetMask (mask.mask, XI_KeyRelease);
+ XISetMask (mask.mask, XI_ButtonPress);
+ XISetMask (mask.mask, XI_ButtonRelease);
+ XISetMask (mask.mask, XI_Enter);
+ XISetMask (mask.mask, XI_Leave);
+ XISetMask (mask.mask, XI_FocusIn);
+ XISetMask (mask.mask, XI_FocusOut);
+ XISetMask (mask.mask, XI_Motion);
+
+ XISelectEvents (xdisplay, xwin, &mask, 1);
+}
+
+static gboolean
+meta_backend_x11_cm_handle_host_xevent (MetaBackendX11 *backend_x11,
+ XEvent *event)
+{
+ MetaBackend *backend = META_BACKEND (backend_x11);
+ MetaMonitorManager *monitor_manager =
+ meta_backend_get_monitor_manager (backend);
+ MetaMonitorManagerXrandr *monitor_manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (monitor_manager);
+
+ return meta_monitor_manager_xrandr_handle_xevent (monitor_manager_xrandr,
+ event);
+}
+
+static void
+meta_backend_x11_cm_translate_device_event (MetaBackendX11 *x11,
+ XIDeviceEvent *device_event)
+{
+ Window stage_window = meta_backend_x11_get_xwindow (x11);
+
+ if (device_event->event != stage_window)
+ {
+ device_event->event = stage_window;
+
+ /* As an X11 compositor, the stage window is always at 0,0, so
+ * using root coordinates will give us correct stage coordinates
+ * as well... */
+ device_event->event_x = device_event->root_x;
+ device_event->event_y = device_event->root_y;
+ }
+}
+
+static void
+meta_backend_x11_cm_translate_crossing_event (MetaBackendX11 *x11,
+ XIEnterEvent *enter_event)
+{
+ Window stage_window = meta_backend_x11_get_xwindow (x11);
+
+ if (enter_event->event != stage_window)
+ {
+ enter_event->event = stage_window;
+ enter_event->event_x = enter_event->root_x;
+ enter_event->event_y = enter_event->root_y;
+ }
+}
+
+static void
+meta_backend_x11_cm_init (MetaBackendX11Cm *backend_x11_cm)
+{
+}
+
+static void
+meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass)
+{
+ MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
+ MetaBackendX11Class *backend_x11_class = META_BACKEND_X11_CLASS (klass);
+
+ backend_class->post_init = meta_backend_x11_cm_post_init;
+ backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager;
+ backend_class->create_cursor_renderer = meta_backend_x11_cm_create_cursor_renderer;
+ backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size;
+ backend_class->select_stage_events = meta_backend_x11_cm_select_stage_events;
+
+ backend_x11_class->handle_host_xevent = meta_backend_x11_cm_handle_host_xevent;
+ backend_x11_class->translate_device_event = meta_backend_x11_cm_translate_device_event;
+ backend_x11_class->translate_crossing_event = meta_backend_x11_cm_translate_crossing_event;
+}
+
diff --git a/src/backends/x11/cm/meta-backend-x11-cm.h b/src/backends/x11/cm/meta-backend-x11-cm.h
new file mode 100644
index 0000000..5332da1
--- /dev/null
+++ b/src/backends/x11/cm/meta-backend-x11-cm.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_BACKEND_X11_CM_H
+#define META_BACKEND_X11_CM_H
+
+#include <glib-object.h>
+
+#include "backends/x11/meta-backend-x11.h"
+
+#define META_TYPE_BACKEND_X11_CM (meta_backend_x11_cm_get_type ())
+G_DECLARE_FINAL_TYPE (MetaBackendX11Cm, meta_backend_x11_cm,
+ META, BACKEND_X11_CM, MetaBackendX11)
+
+#endif /* META_BACKEND_X11_CM_H */
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index 9237f27..92a13dc 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -39,30 +39,15 @@
#include <xkbcommon/xkbcommon-x11.h>
#include "meta-idle-monitor-xsync.h"
-#include "meta-monitor-manager-xrandr.h"
-#include "backends/meta-monitor-manager-dummy.h"
#include "backends/meta-stage.h"
-#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
#include "backends/x11/meta-clutter-backend-x11.h"
#include "backends/x11/meta-renderer-x11.h"
#include "meta/meta-cursor-tracker.h"
-#include "meta-cursor-renderer-x11.h"
-#ifdef HAVE_WAYLAND
-#include "wayland/meta-wayland.h"
-#endif
#include <meta/util.h>
#include "display-private.h"
#include "compositor/compositor-private.h"
-typedef enum {
- /* We're a traditional CM running under the host. */
- META_BACKEND_X11_MODE_COMPOSITOR,
-
- /* We're a nested X11 client */
- META_BACKEND_X11_MODE_NESTED,
-} MetaBackendX11Mode;
-
struct _MetaBackendX11Private
{
/* The host X11 display */
@@ -70,8 +55,6 @@ struct _MetaBackendX11Private
xcb_connection_t *xcb;
GSource *source;
- MetaBackendX11Mode mode;
-
int xsync_event_base;
int xsync_error_base;
@@ -107,27 +90,22 @@ handle_alarm_notify (MetaBackend *backend,
}
static void
+meta_backend_x11_translate_device_event (MetaBackendX11 *x11,
+ XIDeviceEvent *device_event)
+{
+ MetaBackendX11Class *backend_x11_class =
+ META_BACKEND_X11_GET_CLASS (x11);
+
+ backend_x11_class->translate_device_event (x11, device_event);
+}
+
+static void
translate_device_event (MetaBackendX11 *x11,
XIDeviceEvent *device_event)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
- Window stage_window = meta_backend_x11_get_xwindow (x11);
- if (device_event->event != stage_window)
- {
- /* This codepath should only ever trigger as an X11 compositor,
- * and never under nested, as under nested all backend events
- * should be reported with respect to the stage window. */
- g_assert (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR);
-
- device_event->event = stage_window;
-
- /* As an X11 compositor, the stage window is always at 0,0, so
- * using root coordinates will give us correct stage coordinates
- * as well... */
- device_event->event_x = device_event->root_x;
- device_event->event_y = device_event->root_y;
- }
+ meta_backend_x11_translate_device_event (x11, device_event);
if (!device_event->send_event && device_event->time != CurrentTime)
{
@@ -146,11 +124,20 @@ translate_device_event (MetaBackendX11 *x11,
}
static void
+meta_backend_x11_translate_crossing_event (MetaBackendX11 *x11,
+ XIEnterEvent *enter_event)
+{
+ MetaBackendX11Class *backend_x11_class =
+ META_BACKEND_X11_GET_CLASS (x11);
+
+ if (backend_x11_class->translate_crossing_event)
+ backend_x11_class->translate_crossing_event (x11, enter_event);
+}
+
+static void
translate_crossing_event (MetaBackendX11 *x11,
XIEnterEvent *enter_event)
{
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
-
/* Throw out weird events generated by grabs. */
if (enter_event->mode == XINotifyGrab ||
enter_event->mode == XINotifyUngrab)
@@ -159,14 +146,7 @@ translate_crossing_event (MetaBackendX11 *x11,
return;
}
- Window stage_window = meta_backend_x11_get_xwindow (x11);
- if (enter_event->event != stage_window &&
- priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
- {
- enter_event->event = meta_backend_x11_get_xwindow (x11);
- enter_event->event_x = enter_event->root_x;
- enter_event->event_y = enter_event->root_y;
- }
+ meta_backend_x11_translate_crossing_event (x11, enter_event);
}
static void
@@ -254,6 +234,16 @@ keymap_changed (MetaBackend *backend)
g_signal_emit_by_name (backend, "keymap-changed", 0);
}
+static gboolean
+meta_backend_x11_handle_host_xevent (MetaBackendX11 *backend_x11,
+ XEvent *event)
+{
+ MetaBackendX11Class *backend_x11_class =
+ META_BACKEND_X11_GET_CLASS (backend_x11);
+
+ return backend_x11_class->handle_host_xevent (backend_x11, event);
+}
+
static void
handle_host_xevent (MetaBackend *backend,
XEvent *event)
@@ -275,24 +265,8 @@ handle_host_xevent (MetaBackend *backend,
}
}
- if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn)
- {
-#ifdef HAVE_WAYLAND
- Window xwin = meta_backend_x11_get_xwindow(x11);
- XEvent xev;
-
- if (event->xfocus.window == xwin)
- {
- /* Since we've selected for KeymapStateMask, every FocusIn is followed immediately
- * by a KeymapNotify event */
- XMaskEvent(priv->xdisplay, KeymapStateMask, &xev);
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
- meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8);
- }
-#else
- g_assert_not_reached ();
-#endif
- }
+ bypass_clutter = (meta_backend_x11_handle_host_xevent (x11, event) ||
+ bypass_clutter);
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
handle_alarm_notify (backend, event);
@@ -322,13 +296,6 @@ handle_host_xevent (MetaBackend *backend,
}
}
- {
- MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
- if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
- meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
- bypass_clutter = TRUE;
- }
-
if (!bypass_clutter)
{
handle_input_event (x11, event);
@@ -417,24 +384,6 @@ x_event_source_new (MetaBackend *backend)
}
static void
-take_touch_grab (MetaBackend *backend)
-{
- MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
- unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
- XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
- XIGrabModifiers mods = { XIAnyModifier, 0 };
-
- XISetMask (mask.mask, XI_TouchBegin);
- XISetMask (mask.mask, XI_TouchUpdate);
- XISetMask (mask.mask, XI_TouchEnd);
-
- XIGrabTouchBegin (priv->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
- DefaultRootWindow (priv->xdisplay),
- False, &mask, 1, &mods);
-}
-
-static void
on_device_added (ClutterDeviceManager *device_manager,
ClutterInputDevice *device,
gpointer user_data)
@@ -490,10 +439,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
if (!has_xi)
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
- /* We only take the passive touch grab if we are a X11 compositor */
- if (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
- take_touch_grab (backend);
-
priv->xcb = XGetXCBConnection (priv->xdisplay);
if (!xkb_x11_setup_xkb_extension (priv->xcb,
XKB_X11_MIN_MAJOR_XKB_VERSION,
@@ -530,42 +475,6 @@ meta_backend_x11_create_idle_monitor (MetaBackend *backend,
NULL);
}
-static MetaMonitorManager *
-meta_backend_x11_create_monitor_manager (MetaBackend *backend)
-{
- MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
-
- switch (priv->mode)
- {
- case META_BACKEND_X11_MODE_COMPOSITOR:
- return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
- case META_BACKEND_X11_MODE_NESTED:
- return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
- default:
- g_assert_not_reached ();
- }
-}
-
-static MetaCursorRenderer *
-meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
-{
- MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
-
- switch (priv->mode)
- {
- case META_BACKEND_X11_MODE_COMPOSITOR:
- return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
- break;
- case META_BACKEND_X11_MODE_NESTED:
- return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
static MetaRenderer *
meta_backend_x11_create_renderer (MetaBackend *backend)
{
@@ -857,79 +766,6 @@ meta_backend_x11_handle_event (MetaBackendX11 *x11,
}
static void
-meta_backend_x11_update_screen_size (MetaBackend *backend,
- int width, int height)
-{
- MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
-
- if (priv->mode == META_BACKEND_X11_MODE_NESTED)
- {
- ClutterActor *stage = meta_backend_get_stage (backend);
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
-
- if (meta_is_stage_views_enabled ())
- meta_renderer_rebuild_views (renderer);
- clutter_actor_set_size (stage, width, height);
- }
- else
- {
- Window xwin = meta_backend_x11_get_xwindow (x11);
- XResizeWindow (priv->xdisplay, xwin, width, height);
- }
-}
-
-static void
-meta_backend_x11_select_stage_events (MetaBackend *backend)
-{
- MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
- Window xwin = meta_backend_x11_get_xwindow (x11);
- unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
- XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
-
- XISetMask (mask.mask, XI_KeyPress);
- XISetMask (mask.mask, XI_KeyRelease);
- XISetMask (mask.mask, XI_ButtonPress);
- XISetMask (mask.mask, XI_ButtonRelease);
- XISetMask (mask.mask, XI_Enter);
- XISetMask (mask.mask, XI_Leave);
- XISetMask (mask.mask, XI_FocusIn);
- XISetMask (mask.mask, XI_FocusOut);
- XISetMask (mask.mask, XI_Motion);
-
- if (priv->mode == META_BACKEND_X11_MODE_NESTED)
- {
- /* When we're an X11 compositor, we can't take these events or else
- * replaying events from our passive root window grab will cause
- * them to come back to us.
- *
- * When we're a nested application, we want to behave like any other
- * application, so select these events like normal apps do.
- */
- XISetMask (mask.mask, XI_TouchBegin);
- XISetMask (mask.mask, XI_TouchEnd);
- XISetMask (mask.mask, XI_TouchUpdate);
- }
-
- XISelectEvents (priv->xdisplay, xwin, &mask, 1);
-
- if (priv->mode == META_BACKEND_X11_MODE_NESTED)
- {
- /* We have no way of tracking key changes when the stage doesn't have
- * focus, so we select for KeymapStateMask so that we get a complete
- * dump of the keyboard state in a KeymapNotify event that immediately
- * follows each FocusIn (and EnterNotify, but we ignore that.)
- */
- XWindowAttributes xwa;
-
- XGetWindowAttributes(priv->xdisplay, xwin, &xwa);
- XSelectInput(priv->xdisplay, xwin,
- xwa.your_event_mask | FocusChangeMask | KeymapStateMask);
- }
-}
-
-static void
meta_backend_x11_class_init (MetaBackendX11Class *klass)
{
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
@@ -937,8 +773,6 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend;
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;
- backend_class->create_cursor_renderer = meta_backend_x11_create_cursor_renderer;
backend_class->create_renderer = meta_backend_x11_create_renderer;
backend_class->grab_device = meta_backend_x11_grab_device;
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
@@ -947,25 +781,16 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->set_keymap = meta_backend_x11_set_keymap;
backend_class->get_keymap = meta_backend_x11_get_keymap;
backend_class->lock_layout_group = meta_backend_x11_lock_layout_group;
- backend_class->update_screen_size = meta_backend_x11_update_screen_size;
- backend_class->select_stage_events = meta_backend_x11_select_stage_events;
backend_class->set_numlock = meta_backend_x11_set_numlock;
}
static void
meta_backend_x11_init (MetaBackendX11 *x11)
{
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
-
clutter_x11_request_reset_on_video_memory_purge ();
/* We do X11 event retrieval ourselves */
clutter_x11_disable_event_retrieval ();
-
- if (meta_is_wayland_compositor ())
- priv->mode = META_BACKEND_X11_MODE_NESTED;
- else
- priv->mode = META_BACKEND_X11_MODE_COMPOSITOR;
}
Display *
diff --git a/src/backends/x11/meta-backend-x11.h b/src/backends/x11/meta-backend-x11.h
index 8bb3388..9c163eb 100644
--- a/src/backends/x11/meta-backend-x11.h
+++ b/src/backends/x11/meta-backend-x11.h
@@ -38,6 +38,13 @@ G_DECLARE_DERIVABLE_TYPE (MetaBackendX11, meta_backend_x11,
struct _MetaBackendX11Class
{
MetaBackendClass parent_class;
+
+ gboolean (* handle_host_xevent) (MetaBackendX11 *x11,
+ XEvent *event);
+ void (* translate_device_event) (MetaBackendX11 *x11,
+ XIDeviceEvent *device_event);
+ void (* translate_crossing_event) (MetaBackendX11 *x11,
+ XIEnterEvent *enter_event);
};
Display * meta_backend_x11_get_xdisplay (MetaBackendX11 *backend);
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c
b/src/backends/x11/nested/meta-backend-x11-nested.c
new file mode 100644
index 0000000..cf9cea7
--- /dev/null
+++ b/src/backends/x11/nested/meta-backend-x11-nested.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "backends/x11/nested/meta-backend-x11-nested.h"
+
+#include "backends/meta-monitor-manager-dummy.h"
+#include "backends/x11/nested/meta-backend-x11-nested.h"
+#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
+
+#include "wayland/meta-wayland.h"
+
+struct _MetaBackendX11Nested
+{
+ MetaBackendX11 parent;
+};
+
+G_DEFINE_TYPE (MetaBackendX11Nested, meta_backend_x11_nested,
+ META_TYPE_BACKEND_X11)
+
+static MetaMonitorManager *
+meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend)
+{
+ return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
+}
+
+static MetaCursorRenderer *
+meta_backend_x11_nested_create_cursor_renderer (MetaBackend *backend)
+{
+ return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
+}
+
+static void
+meta_backend_x11_nested_update_screen_size (MetaBackend *backend,
+ int width,
+ int height)
+{
+ ClutterActor *stage = meta_backend_get_stage (backend);
+ MetaRenderer *renderer = meta_backend_get_renderer (backend);
+
+ if (meta_is_stage_views_enabled ())
+ meta_renderer_rebuild_views (renderer);
+ clutter_actor_set_size (stage, width, height);
+}
+
+static void
+meta_backend_x11_nested_select_stage_events (MetaBackend *backend)
+{
+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
+ Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
+ Window xwin = meta_backend_x11_get_xwindow (x11);
+ unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
+ XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
+
+ XISetMask (mask.mask, XI_KeyPress);
+ XISetMask (mask.mask, XI_KeyRelease);
+ XISetMask (mask.mask, XI_ButtonPress);
+ XISetMask (mask.mask, XI_ButtonRelease);
+ XISetMask (mask.mask, XI_Enter);
+ XISetMask (mask.mask, XI_Leave);
+ XISetMask (mask.mask, XI_FocusIn);
+ XISetMask (mask.mask, XI_FocusOut);
+ XISetMask (mask.mask, XI_Motion);
+
+ /*
+ * When we're an X11 compositor, we can't take these events or else replaying
+ * events from our passive root window grab will cause them to come back to
+ * us.
+ *
+ * When we're a nested application, we want to behave like any other
+ * application, so select these events like normal apps do.
+ */
+ XISetMask (mask.mask, XI_TouchBegin); XISetMask (mask.mask, XI_TouchEnd);
+ XISetMask (mask.mask, XI_TouchUpdate);
+
+ XISelectEvents (xdisplay, xwin, &mask, 1);
+
+ /*
+ * We have no way of tracking key changes when the stage doesn't have focus,
+ * so we select for KeymapStateMask so that we get a complete dump of the
+ * keyboard state in a KeymapNotify event that immediately follows each
+ * FocusIn (and EnterNotify, but we ignore that.)
+ */
+ XWindowAttributes xwa;
+
+ XGetWindowAttributes(xdisplay, xwin, &xwa);
+ XSelectInput(xdisplay, xwin,
+ xwa.your_event_mask | FocusChangeMask | KeymapStateMask);
+}
+
+static gboolean
+meta_backend_x11_nested_handle_host_xevent (MetaBackendX11 *x11,
+ XEvent *event)
+{
+#ifdef HAVE_WAYLAND
+ if (event->type == FocusIn)
+ {
+ Window xwin = meta_backend_x11_get_xwindow (x11);
+ XEvent xev;
+
+ if (event->xfocus.window == xwin)
+ {
+ MetaWaylandCompositor *compositor =
+ meta_wayland_compositor_get_default ();
+ Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
+
+ /*
+ * Since we've selected for KeymapStateMask, every FocusIn is
+ * followed immediately by a KeymapNotify event.
+ */
+ XMaskEvent (xdisplay, KeymapStateMask, &xev);
+ meta_wayland_compositor_update_key_state (compositor,
+ xev.xkeymap.key_vector,
+ 32, 8);
+ }
+ }
+#endif
+
+ return FALSE;
+}
+
+static void
+meta_backend_x11_nested_translate_device_event (MetaBackendX11 *x11,
+ XIDeviceEvent *device_event)
+{
+ /* This codepath should only ever trigger as an X11 compositor,
+ * and never under nested, as under nested all backend events
+ * should be reported with respect to the stage window.
+ */
+ g_assert (device_event->event == meta_backend_x11_get_xwindow (x11));
+}
+
+static void
+meta_backend_x11_nested_init (MetaBackendX11Nested *backend_x11_nested)
+{
+}
+
+static void
+meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
+{
+ MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
+ MetaBackendX11Class *backend_x11_class = META_BACKEND_X11_CLASS (klass);
+
+ backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
+ backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer;
+ backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size;
+ backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events;
+
+ backend_x11_class->handle_host_xevent = meta_backend_x11_nested_handle_host_xevent;
+ backend_x11_class->translate_device_event = meta_backend_x11_nested_translate_device_event;
+}
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.h
b/src/backends/x11/nested/meta-backend-x11-nested.h
new file mode 100644
index 0000000..31ae96f
--- /dev/null
+++ b/src/backends/x11/nested/meta-backend-x11-nested.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_BACKEND_X11_NESTED_H
+#define META_BACKEND_X11_NESTED_H
+
+#include <glib-object.h>
+
+#include "backends/x11/meta-backend-x11.h"
+
+#define META_TYPE_BACKEND_X11_NESTED (meta_backend_x11_nested_get_type ())
+G_DECLARE_FINAL_TYPE (MetaBackendX11Nested, meta_backend_x11_nested,
+ META, BACKEND_X11_NESTED, MetaBackendX11)
+
+#endif /* META_BACKEND_X11_NESTED_H */
diff --git a/src/core/main.c b/src/core/main.c
index dc40f6e..9b82ca7 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -80,10 +80,12 @@
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland.h"
+#include "backends/x11/nested/meta-backend-x11-nested.h"
# endif
#include "backends/meta-backend-private.h"
#include "backends/x11/meta-backend-x11.h"
+#include "backends/x11/cm/meta-backend-x11-cm.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
@@ -397,6 +399,26 @@ check_for_wayland_session_type (void)
}
#endif
+/*
+ * Determine the compositor configuration, i.e. whether to run as a Wayland
+ * compositor, as well as what backend to use.
+ *
+ * There are various different flags affecting this:
+ *
+ * --nested always forces the use of the nested X11 backend
+ * --display-server always forces the use of the native backend
+ * --wayland always forces the compositor type to be a Wayland compositor
+ *
+ * If no flag is passed that forces the compositor type, the compositor type
+ * is determined first from the logind session type, or if that fails, from the
+ * XDG_SESSION_TYPE enviornment variable.
+ *
+ * If no flag is passed that forces the backend type, the backend type is
+ * determined given the compositor type. If the compositor is a Wayland
+ * compositor, then the native backend is used, or the nested backend, would
+ * the native backend not be enabled at build time. If the compositor is not a
+ * Wayland compositor, then the X11 Compositing Manager backend is used.
+ */
static void
calculate_compositor_configuration (MetaCompositorType *compositor_type,
GType *backend_gtype)
@@ -413,22 +435,48 @@ calculate_compositor_configuration (MetaCompositorType *compositor_type,
if (!run_as_wayland_compositor)
run_as_wayland_compositor = check_for_wayland_session_type ();
+#endif /* HAVE_NATIVE_BACKEND */
-#ifdef CLUTTER_WINDOWING_EGL
- if (opt_display_server || (run_as_wayland_compositor && !opt_nested))
- *backend_gtype = META_TYPE_BACKEND_NATIVE;
+ if (run_as_wayland_compositor)
+ *compositor_type = META_COMPOSITOR_TYPE_WAYLAND;
else
-#endif
-#endif
-#endif
- *backend_gtype = META_TYPE_BACKEND_X11;
+#endif /* HAVE_WAYLAND */
+ *compositor_type = META_COMPOSITOR_TYPE_X11;
+
+ if (opt_nested)
+ {
+ *backend_gtype = META_TYPE_BACKEND_X11_NESTED;
+ return;
+ }
+
+#ifdef HAVE_NATIVE_BACKEND
+ if (opt_display_server)
+ {
+ *backend_gtype = META_TYPE_BACKEND_NATIVE;
+ return;
+ }
#ifdef HAVE_WAYLAND
if (run_as_wayland_compositor)
- *compositor_type = META_COMPOSITOR_TYPE_WAYLAND;
+ {
+ *backend_gtype = META_TYPE_BACKEND_NATIVE;
+ return;
+ }
+#endif /* HAVE_WAYLAND */
+#endif /* HAVE_NATIVE_BACKEND */
+
+#ifdef HAVE_WAYLAND
+ if (run_as_wayland_compositor)
+ {
+ *backend_gtype = META_TYPE_BACKEND_X11_NESTED;
+ return;
+ }
else
-#endif
- *compositor_type = META_COMPOSITOR_TYPE_X11;
+#endif /* HAVE_WAYLAND */
+ {
+ *backend_gtype = META_TYPE_BACKEND_X11_CM;
+ return;
+ }
}
static gboolean _compositor_configuration_overridden = FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]