diff --git a/src/core/core.c b/src/core/core.c
index c2ec5fec4..bfeed9800 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -30,6 +30,11 @@
#include
#include
+#ifdef HAVE_XINPUT2
+#include
+#include "devices-xi2.h"
+#endif
+
/* Looks up the MetaWindow representing the frame of the given X window.
* Used as a helper function by a bunch of the functions below.
*
@@ -775,3 +780,69 @@ meta_invalidate_default_icons (void)
g_slist_free (windows);
}
+/* Selects events on an xwindow, using XInput2 if available/in use,
+ * this function doesn't require the xwindow to have a backing
+ * MetaWindow.
+ */
+void
+meta_core_select_events (Display *xdisplay,
+ Window xwindow,
+ gint evmask,
+ gboolean preserve_old_mask)
+{
+ MetaDisplay *display;
+
+ display = meta_display_for_x_display (xdisplay);
+
+#ifdef HAVE_XINPUT2
+ if (display->have_xinput2)
+ {
+ XIEventMask mask;
+
+ mask.deviceid = XIAllMasterDevices;
+ mask.mask = meta_device_xi2_translate_event_mask (evmask,
+ &mask.mask_len);
+
+ if (preserve_old_mask)
+ {
+ XIEventMask *prev;
+ gint n_masks, i, j;
+
+ prev = XIGetSelectedEvents (xdisplay, xwindow, &n_masks);
+
+ for (i = 0; i < n_masks; i++)
+ {
+ if (prev[i].deviceid != XIAllMasterDevices)
+ continue;
+
+ for (j = 0; j < MIN (mask.mask_len, prev[i].mask_len); j++)
+ mask.mask[j] |= prev[i].mask[j];
+ }
+
+ XFree (prev);
+ }
+
+ XISelectEvents (xdisplay, xwindow, &mask, 1);
+
+ /* Unset any input event so they are only handled via XInput2 */
+ evmask &= ~(KeyPressMask | KeyReleaseMask |
+ ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask |
+ PointerMotionMask | PointerMotionHintMask |
+ Button1MotionMask | Button2MotionMask |
+ Button3MotionMask | Button4MotionMask |
+ Button5MotionMask | ButtonMotionMask |
+ FocusChangeMask);
+ }
+#endif
+
+ if (preserve_old_mask)
+ {
+ XWindowAttributes attr;
+
+ if (XGetWindowAttributes (xdisplay, xwindow, &attr))
+ evmask |= attr.your_event_mask;
+ }
+
+ XSelectInput (xdisplay, xwindow, evmask);
+}
diff --git a/src/core/core.h b/src/core/core.h
index 12451bd63..95f8f466d 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -197,6 +197,12 @@ void meta_core_set_screen_cursor (Display *xdisplay,
Window frame_on_screen,
MetaCursor cursor);
+void meta_core_select_events (Display *xdisplay,
+ Window xwindow,
+ gint evmask,
+ gboolean preserve_old_mask);
+
+
/* Used because we ignore EnterNotify when a window is unmapped that
* really shouldn't cause focus changes, by comparing the event serial
* of the EnterNotify and the UnmapNotify.