[mutter/wip/xinput2b: 6/22] core: Add method to select events on a window



commit 59de68546e6515e5fdea4fb5a7805109ec8f4ace
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Jun 12 21:21:21 2011 +0200

    core: Add method to select events on a window
    
    This function handles XInput2 vs core in input events.

 src/core/core.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/core/core.h |   13 +++++--
 2 files changed, 103 insertions(+), 4 deletions(-)
---
diff --git a/src/core/core.c b/src/core/core.c
index c2ec5fe..fea3e50 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -775,3 +775,97 @@ meta_invalidate_default_icons (void)
   g_slist_free (windows);
 }
 
+guchar *
+meta_core_translate_xi2_mask (guint  evmask,
+                              gint  *len)
+{
+  guchar *mask;
+
+  *len = XIMaskLen (XI_LASTEVENT);
+  mask = g_new0 (guchar, *len);
+
+  if (evmask & KeyPressMask)
+    XISetMask (mask, XI_KeyPress);
+  if (evmask & KeyReleaseMask)
+    XISetMask (mask, XI_KeyRelease);
+  if (evmask & ButtonPressMask)
+    XISetMask (mask, XI_ButtonPress);
+  if (evmask & ButtonReleaseMask)
+    XISetMask (mask, XI_ButtonRelease);
+  if (evmask & EnterWindowMask)
+    XISetMask (mask, XI_Enter);
+  if (evmask & LeaveWindowMask)
+    XISetMask (mask, XI_Leave);
+
+  /* No motion hints in XI2 at the moment... */
+  if (evmask & PointerMotionMask ||
+      evmask & PointerMotionHintMask)
+    XISetMask (mask, XI_Motion);
+
+  if (evmask & FocusChangeMask)
+    {
+      XISetMask (mask, XI_FocusIn);
+      XISetMask (mask, XI_FocusOut);
+    }
+
+  return mask;
+}
+
+/* Selects events on an xwindow, using XInput2 if possible.
+ * 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)
+{
+  XIEventMask mask;
+
+  mask.deviceid = XIAllMasterDevices;
+  mask.mask = meta_core_translate_xi2_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);
+
+  g_free (mask.mask);
+
+  /* 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);
+
+  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 12451bd..000c73f 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -197,6 +197,15 @@ void       meta_core_set_screen_cursor (Display *xdisplay,
                                         Window   frame_on_screen,
                                         MetaCursor cursor);
 
+guchar *   meta_core_translate_xi2_mask (guint  evmask,
+                                         gint  *len);
+
+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.
@@ -206,7 +215,3 @@ void meta_core_increment_event_serial (Display *display);
 void meta_invalidate_default_icons (void);
 
 #endif
-
-
-
-



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]