[mutter] clutter/x11: Add minimal support for pad devices



commit 9abf6892c4d25887ed76a14d138c8923bc3a1448
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Oct 25 17:11:04 2016 +0200

    clutter/x11: Add minimal support for pad devices
    
    We most notably handle button events (acquired through a passive grab on
    all device buttons) which are translated to CLUTTER_PAD_BUTTON* events,
    so there is generic handling of pad actions on X11.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=773779

 clutter/clutter/x11/clutter-device-manager-xi2.c |   89 ++++++++++++++++++++++
 1 files changed, 89 insertions(+), 0 deletions(-)
---
diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c 
b/clutter/clutter/x11/clutter-device-manager-xi2.c
index 32ddbfc..62a12c4 100644
--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
@@ -395,6 +395,8 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
         source = CLUTTER_ERASER_DEVICE;
       else if (strstr (name, "cursor") != NULL)
         source = CLUTTER_CURSOR_DEVICE;
+      else if (strstr (name, " pad") != NULL)
+        source = CLUTTER_PAD_DEVICE;
       else if (strstr (name, "wacom") != NULL || strstr (name, "pen") != NULL)
         source = CLUTTER_PEN_DEVICE;
       else if (strstr (name, "touchpad") != NULL)
@@ -461,6 +463,46 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
   return retval;
 }
 
+static void
+pad_passive_button_grab (ClutterInputDevice *device)
+{
+  XIGrabModifiers xi_grab_mods = { XIAnyModifier, };
+  XIEventMask xi_event_mask;
+  gint device_id, rc;
+
+  device_id = clutter_input_device_get_device_id (device);
+
+  xi_event_mask.deviceid = device_id;
+  xi_event_mask.mask_len = XIMaskLen (XI_LASTEVENT);
+  xi_event_mask.mask = g_new0 (unsigned char, xi_event_mask.mask_len);
+
+  XISetMask (xi_event_mask.mask, XI_Motion);
+  XISetMask (xi_event_mask.mask, XI_ButtonPress);
+  XISetMask (xi_event_mask.mask, XI_ButtonRelease);
+
+  clutter_x11_trap_x_errors ();
+  rc = XIGrabButton (clutter_x11_get_default_display (),
+                     device_id, XIAnyButton,
+                     clutter_x11_get_root_window (), None,
+                     XIGrabModeSync, XIGrabModeSync,
+                     True, &xi_event_mask, 1, &xi_grab_mods);
+  if (rc != 0)
+    {
+      g_warning ("Could not passively grab pad device: %s",
+                 clutter_input_device_get_device_name (device));
+    }
+  else
+    {
+      XIAllowEvents (clutter_x11_get_default_display (),
+                     device_id, XIAsyncDevice,
+                     CLUTTER_CURRENT_TIME);
+    }
+
+  clutter_x11_untrap_x_errors ();
+
+  g_free (xi_event_mask.mask);
+}
+
 static ClutterInputDevice *
 add_device (ClutterDeviceManagerXI2 *manager_xi2,
             ClutterBackendX11       *backend_x11,
@@ -495,6 +537,9 @@ add_device (ClutterDeviceManagerXI2 *manager_xi2,
     g_warning ("Unhandled device: %s",
                clutter_input_device_get_device_name (device));
 
+  if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
+    pad_passive_button_grab (device);
+
   /* relationships between devices and signal emissions are not
    * necessary while we're constructing the device manager instance
    */
@@ -1079,6 +1124,50 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
             stage != NULL)
           _clutter_input_device_set_stage (device, stage);
 
+       if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
+          {
+            /* We got these events because of the passive button grab */
+            XIAllowEvents (clutter_x11_get_default_display (),
+                           xev->sourceid,
+                           XIAsyncDevice,
+                           xev->time);
+
+           /* Ignore 4-7 buttons */
+            if (xev->detail >= 4 && xev->detail <= 7)
+              return CLUTTER_TRANSLATE_REMOVE;
+
+            event->pad_button.type =
+              (xi_event->evtype == XI_ButtonPress) ? CLUTTER_PAD_BUTTON_PRESS
+                                                   : CLUTTER_PAD_BUTTON_RELEASE;
+            event->pad_button.time = xev->time;
+            event->pad_button.stage = stage;
+
+            /* The 4-7 button range is taken as non-existent on pad devices,
+             * let the buttons above that take over this range.
+             */
+            if (xev->detail > 7)
+              xev->detail -= 4;
+
+            /* Pad buttons are 0-indexed */
+            event->pad_button.button = xev->detail - 1;
+            clutter_event_set_source_device (event, source_device);
+
+            CLUTTER_NOTE (EVENT,
+                          "%s: win:0x%x, device:%d '%s', time:%d "
+                          "(button:%d)",
+                          event->any.type == CLUTTER_BUTTON_PRESS
+                            ? "pad button press  "
+                            : "pad button release",
+                          (unsigned int) stage_x11->xwin,
+                          device->id,
+                          device->device_name,
+                          event->any.time,
+                          event->pad_button.button);
+
+            retval = CLUTTER_TRANSLATE_QUEUE;
+            break;
+          }
+
         switch (xev->detail)
           {
           case 4:


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