[gtk+/touch-for-3.4: 35/65] xi2: Handle touch events



commit 605c7e161ba8ace1acb17cfc74fc54d5b904ae06
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Feb 28 21:14:50 2011 +0100

    xi2: Handle touch events
    
    GdkDeviceManagerXI2 now handles touch events.
    TouchMotion events are translated to GDK_TOUCH_MOTION events,
    TouchBegin/End events are translated to the newly introduced
    GDK_TOUCH_PRESS/RELEASE events.

 gdk/gdkevents.c                |   26 ++++++-
 gdk/gdkevents.h                |   24 ++++++-
 gdk/gdktypes.h                 |    7 ++
 gdk/gdkwindow.c                |    4 +-
 gdk/x11/Makefile.am            |    2 +
 gdk/x11/gdkdevice-xi2.c        |   34 ++++++++-
 gdk/x11/gdkdevicemanager-x11.c |    4 +
 gdk/x11/gdkdevicemanager-xi2.c |  162 ++++++++++++++++++++++++----------------
 gdk/x11/gdkprivate-x11.h       |    5 +-
 9 files changed, 193 insertions(+), 75 deletions(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index eda926f..6aeedfd 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -455,6 +455,8 @@ gdk_event_new (GdkEventType type)
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       new_event->button.x = 0.;
       new_event->button.y = 0.;
       new_event->button.x_root = 0.;
@@ -559,6 +561,8 @@ gdk_event_copy (const GdkEvent *event)
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       if (event->button.axes)
         new_event->button.axes = g_memdup (event->button.axes,
                                            sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
@@ -641,6 +645,8 @@ gdk_event_free (GdkEvent *event)
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       g_free (event->button.axes);
       break;
       
@@ -705,6 +711,8 @@ gdk_event_get_time (const GdkEvent *event)
       case GDK_2BUTTON_PRESS:
       case GDK_3BUTTON_PRESS:
       case GDK_BUTTON_RELEASE:
+      case GDK_TOUCH_PRESS:
+      case GDK_TOUCH_RELEASE:
 	return event->button.time;
       case GDK_SCROLL:
         return event->scroll.time;
@@ -782,6 +790,8 @@ gdk_event_get_state (const GdkEvent        *event,
       case GDK_2BUTTON_PRESS:
       case GDK_3BUTTON_PRESS:
       case GDK_BUTTON_RELEASE:
+      case GDK_TOUCH_PRESS:
+      case GDK_TOUCH_RELEASE:
         *state =  event->button.state;
         return TRUE;
       case GDK_SCROLL:
@@ -870,6 +880,8 @@ gdk_event_get_coords (const GdkEvent *event,
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       x = event->button.x;
       y = event->button.y;
       break;
@@ -926,6 +938,8 @@ gdk_event_get_root_coords (const GdkEvent *event,
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       x = event->button.x_root;
       y = event->button.y_root;
       break;
@@ -1180,6 +1194,8 @@ gdk_event_get_axis (const GdkEvent *event,
 	  break;
 	case GDK_BUTTON_PRESS:
 	case GDK_BUTTON_RELEASE:
+        case GDK_TOUCH_PRESS:
+        case GDK_TOUCH_RELEASE:
 	  x = event->button.x;
 	  y = event->button.y;
 	  break;
@@ -1201,7 +1217,9 @@ gdk_event_get_axis (const GdkEvent *event,
       return TRUE;
     }
   else if (event->type == GDK_BUTTON_PRESS ||
-	   event->type == GDK_BUTTON_RELEASE)
+	   event->type == GDK_BUTTON_RELEASE ||
+           event->type == GDK_TOUCH_PRESS ||
+           event->type == GDK_TOUCH_RELEASE)
     {
       device = event->button.device;
       axes = event->button.axes;
@@ -1251,6 +1269,8 @@ gdk_event_set_device (GdkEvent  *event,
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       event->button.device = device;
       break;
     case GDK_SCROLL:
@@ -1298,6 +1318,8 @@ gdk_event_get_device (const GdkEvent *event)
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       return event->button.device;
     case GDK_SCROLL:
       return event->scroll.device;
@@ -1317,6 +1339,8 @@ gdk_event_get_device (const GdkEvent *event)
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
     case GDK_FOCUS_CHANGE:
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index eea09e0..da5d282 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -265,6 +265,10 @@ typedef GdkFilterReturn (*GdkFilterFunc) (GdkXEvent *xevent,
  *   was added in 2.14.
  * @GDK_TOUCH_MOTION: A touch device has been updated. This event type
  *   was added in 3.4.
+ * @GDK_TOUCH_PRESS: A new touch stream has just started. This event type
+ *   was added in 3.4.
+ * @GDK_TOUCH_RELEASE: A touch stream has finished. This event type
+ *   was added in 3.4.
  * @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration. Added in 2.18
  *
  * Specifies the type of the event.
@@ -313,6 +317,8 @@ typedef enum
   GDK_GRAB_BROKEN       = 35,
   GDK_DAMAGE            = 36,
   GDK_TOUCH_MOTION      = 37,
+  GDK_TOUCH_PRESS       = 38,
+  GDK_TOUCH_RELEASE     = 39,
   GDK_EVENT_LAST        /* helper variable for decls */
 } GdkEventType;
 
@@ -568,6 +574,10 @@ struct _GdkEventVisibility
  * @touch_id: touch ID, only meaningful if event is of type %GDK_TOUCH_MOTION.
  *
  * Generated when the pointer/touch moves.
+ *
+ * If the event has a type of %GDK_TOUCH_MOTION, this event will
+ * pertain to a sequence identified by gdk_event_get_touch_id().
+ * With multitouch devices, there may be several ongoing sequences.
  */
 struct _GdkEventMotion
 {
@@ -588,7 +598,8 @@ struct _GdkEventMotion
 /**
  * GdkEventButton:
  * @type: the type of the event (%GDK_BUTTON_PRESS, %GDK_2BUTTON_PRESS,
- *   %GDK_3BUTTON_PRESS or %GDK_BUTTON_RELEASE).
+ *   %GDK_3BUTTON_PRESS, %GDK_BUTTON_RELEASE, %GDK_TOUCH_PRESS or
+ *   %GDK_TOUCH_RELEASE).
  * @window: the window which received the event.
  * @send_event: %TRUE if the event was sent explicitly (e.g. using
  *   <function>XSendEvent</function>).
@@ -609,10 +620,13 @@ struct _GdkEventMotion
  *   screen.
  * @y_root: the y coordinate of the pointer relative to the root of the
  *   screen.
+ * @touch_id: touch ID, only meaningful if event is of type %GDK_TOUCH_PRESS
+ *   or %GDK_TOUCH_RELEASE.
  *
  * Used for button press and button release events. The
  * @type field will be one of %GDK_BUTTON_PRESS,
- * %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS, and %GDK_BUTTON_RELEASE.
+ * %GDK_2BUTTON_PRESS, %GDK_3BUTTON_PRESS, %GDK_BUTTON_RELEASE,
+ * %GDK_TOUCH_PRESS and %GDK_TOUCH_RELEASE.
  *
  * Double and triple-clicks result in a sequence of events being received.
  * For double-clicks the order of events will be:
@@ -644,6 +658,11 @@ struct _GdkEventMotion
  * For a double click to occur, the second button press must occur within
  * 1/4 of a second of the first. For a triple click to occur, the third
  * button press must also occur within 1/2 second of the first button press.
+ *
+ * If the event has a type of %GDK_TOUCH_PRESS or %GDK_TOUCH_RELEASE,
+ * this event will pertain to a sequence identified by
+ * gdk_event_get_touch_id(). With multitouch devices, there may be
+ * several ongoing sequences.
  */
 struct _GdkEventButton
 {
@@ -658,6 +677,7 @@ struct _GdkEventButton
   guint button;
   GdkDevice *device;
   gdouble x_root, y_root;
+  guint touch_id;
 };
 
 /**
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
index 8f0bdf3..23f971f 100644
--- a/gdk/gdktypes.h
+++ b/gdk/gdktypes.h
@@ -366,6 +366,13 @@ typedef enum
  * some of which are marked as a hint (the is_hint member is %TRUE).
  * To receive more motion events after a motion hint event, the application
  * needs to asks for more, by calling gdk_event_request_motions().
+ *
+ * If %GDK_TOUCH_MASK is enabled, the window will receive (multi)touch events
+ * from touch-enabled devices. Those will come as sequences #GdkEventMotion
+ * with type %GDK_TOUCH_MOTION, enclosed by 2 #GdkEventButton events with
+ * type %GDK_TOUCH_PRESS / %GDK_TOUCH_RELEASE. gdk_event_get_touch_id() will
+ * return the touch ID on those events, so different sequences may be
+ * distinguished.
  */
 typedef enum
 {
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index a2a3a50..55b36c5 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -8119,7 +8119,9 @@ static const guint type_masks[] = {
   0, /* GDK_OWNER_CHANGE = 34 */
   0, /* GDK_GRAB_BROKEN = 35 */
   0, /* GDK_DAMAGE = 36 */
-  GDK_TOUCH_MASK | GDK_BUTTON_MOTION_MASK /* GDK_TOUCH_MOTION = 37 */
+  GDK_TOUCH_MASK | GDK_BUTTON_MOTION_MASK | GDK_POINTER_MOTION_MASK, /* GDK_TOUCH_MOTION = 37 */
+  GDK_TOUCH_MASK | GDK_BUTTON_PRESS_MASK, /* GDK_TOUCH_PRESS   = 38 */
+  GDK_TOUCH_MASK | GDK_BUTTON_RELEASE_MASK /* GDK_TOUCH_RELEASE = 39 */
 };
 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
 
diff --git a/gdk/x11/Makefile.am b/gdk/x11/Makefile.am
index 3b0d1bd..d8abfd5 100644
--- a/gdk/x11/Makefile.am
+++ b/gdk/x11/Makefile.am
@@ -7,6 +7,8 @@ libgdkx11includedir = $(includedir)/gtk-3.0/gdk/x11
 AM_CPPFLAGS = 			\
 	-DG_LOG_DOMAIN=\"Gdk\"	\
 	-DGDK_COMPILATION	\
+	-DXINPUT2_2_USE_UNSTABLE_PROTOCOL \
+	-DXINPUT2_1_USE_UNSTABLE_PROTOCOL \
 	-I$(top_srcdir)		\
 	-I$(top_srcdir)/gdk	\
 	-I$(top_builddir)/gdk	\
diff --git a/gdk/x11/gdkdevice-xi2.c b/gdk/x11/gdkdevice-xi2.c
index bc6261b..3b009e5 100644
--- a/gdk/x11/gdkdevice-xi2.c
+++ b/gdk/x11/gdkdevice-xi2.c
@@ -388,6 +388,7 @@ gdk_x11_device_xi2_grab (GdkDevice    *device,
                          guint32       time_)
 {
   GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
+  GdkX11DeviceManagerXI2 *device_manager_xi2;
   GdkDisplay *display;
   XIEventMask mask;
   Window xwindow;
@@ -395,6 +396,7 @@ gdk_x11_device_xi2_grab (GdkDevice    *device,
   gint status;
 
   display = gdk_device_get_display (device);
+  device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
 
   /* FIXME: confine_to is actually unused */
 
@@ -409,7 +411,9 @@ gdk_x11_device_xi2_grab (GdkDevice    *device,
     }
 
   mask.deviceid = device_xi2->device_id;
-  mask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &mask.mask_len);
+  mask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
+                                                        event_mask,
+                                                        &mask.mask_len);
 
 #ifdef G_ENABLE_DEBUG
   if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
@@ -625,10 +629,17 @@ gdk_x11_device_xi2_select_window_events (GdkDevice    *device,
                                          GdkEventMask  event_mask)
 {
   GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
+  GdkX11DeviceManagerXI2 *device_manager_xi2;
+  GdkDisplay *display;
   XIEventMask evmask;
 
+  display = gdk_device_get_display (device);
+  device_manager_xi2 = GDK_X11_DEVICE_MANAGER_XI2 (gdk_display_get_device_manager (display));
+
   evmask.deviceid = device_xi2->device_id;
-  evmask.mask = _gdk_x11_device_xi2_translate_event_mask (event_mask, &evmask.mask_len);
+  evmask.mask = _gdk_x11_device_xi2_translate_event_mask (device_manager_xi2,
+                                                          event_mask,
+                                                          &evmask.mask_len);
 
   XISelectEvents (GDK_WINDOW_XDISPLAY (window),
                   GDK_WINDOW_XID (window),
@@ -638,10 +649,14 @@ gdk_x11_device_xi2_select_window_events (GdkDevice    *device,
 }
 
 guchar *
-_gdk_x11_device_xi2_translate_event_mask (GdkEventMask  event_mask,
-                                          gint         *len)
+_gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
+                                          GdkEventMask            event_mask,
+                                          gint                   *len)
 {
   guchar *mask;
+  gint minor;
+
+  g_object_get (device_manager_xi2, "minor", &minor, NULL);
 
   *len = XIMaskLen (XI_LASTEVENT);
   mask = g_new0 (guchar, *len);
@@ -690,6 +705,17 @@ _gdk_x11_device_xi2_translate_event_mask (GdkEventMask  event_mask,
       XISetMask (mask, XI_FocusOut);
     }
 
+#ifdef XINPUT_2_2
+  /* XInput 2.2 includes multitouch support */
+  if (minor >= 2 &&
+      event_mask & GDK_TOUCH_MASK)
+    {
+      XISetMask (mask, XI_TouchBegin);
+      XISetMask (mask, XI_TouchUpdate);
+      XISetMask (mask, XI_TouchEnd);
+    }
+#endif /* XINPUT_2_2 */
+
   return mask;
 }
 
diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c
index 64f6797..c119870 100644
--- a/gdk/x11/gdkdevicemanager-x11.c
+++ b/gdk/x11/gdkdevicemanager-x11.c
@@ -54,7 +54,11 @@ _gdk_x11_device_manager_new (GdkDisplay *display)
           int major, minor;
 
           major = 2;
+#ifdef XINPUT_2_2
+	  minor = 2;
+#else
           minor = 0;
+#endif /* XINPUT_2_2 */
 
           if (!_gdk_disable_multidevice &&
               XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index cec2596..2371bde 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -166,8 +166,10 @@ _gdk_x11_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
 static void
 translate_valuator_class (GdkDisplay          *display,
                           GdkDevice           *device,
-                          XIValuatorClassInfo *info,
-                          gint                 n_valuator)
+                          Atom                 valuator_label,
+                          gdouble              min,
+                          gdouble              max,
+                          gdouble              resolution)
 {
   static gboolean initialized = FALSE;
   static Atom label_atoms [GDK_AXIS_LAST] = { 0 };
@@ -188,24 +190,19 @@ translate_valuator_class (GdkDisplay          *display,
 
   for (i = GDK_AXIS_IGNORE; i < GDK_AXIS_LAST; i++)
     {
-      if (label_atoms[i] == info->label)
+      if (label_atoms[i] == valuator_label)
         {
           use = i;
           break;
         }
     }
 
-  if (info->label != None)
-    label = gdk_x11_xatom_to_atom_for_display (display, info->label);
+  if (valuator_label != None)
+    label = gdk_x11_xatom_to_atom_for_display (display, valuator_label);
   else
     label = GDK_NONE;
 
-  _gdk_device_add_axis (device,
-                        label,
-                        use,
-                        info->min,
-                        info->max,
-                        info->resolution);
+  _gdk_device_add_axis (device, label, use, min, max, resolution);
 }
 
 static void
@@ -214,7 +211,7 @@ translate_device_classes (GdkDisplay      *display,
                           XIAnyClassInfo **classes,
                           guint            n_classes)
 {
-  gint i, n_valuator = 0;
+  gint i;
 
   g_object_freeze_notify (G_OBJECT (device));
 
@@ -236,10 +233,14 @@ translate_device_classes (GdkDisplay      *display,
           }
           break;
         case XIValuatorClass:
-          translate_valuator_class (display, device,
-                                    (XIValuatorClassInfo *) class_info,
-                                    n_valuator);
-          n_valuator++;
+          {
+            XIValuatorClassInfo *valuator_info = (XIValuatorClassInfo *) class_info;
+            translate_valuator_class (display, device,
+                                      valuator_info->label,
+                                      valuator_info->min,
+                                      valuator_info->max,
+                                      valuator_info->resolution);
+          }
           break;
         default:
           /* Ignore */
@@ -859,6 +860,11 @@ get_event_window (GdkEventTranslator *translator,
     case XI_ButtonPress:
     case XI_ButtonRelease:
     case XI_Motion:
+#ifdef XINPUT_2_2
+    case XI_TouchUpdate:
+    case XI_TouchBegin:
+    case XI_TouchEnd:
+#endif /* XINPUT_2_2 */
       {
         XIDeviceEvent *xev = (XIDeviceEvent *) ev;
 
@@ -1079,56 +1085,55 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
       break;
     case XI_ButtonPress:
     case XI_ButtonRelease:
+#ifdef XINPUT_2_2
+    case XI_TouchBegin:
+    case XI_TouchEnd:
+#endif /* XINPUT_2_2 */
       {
         XIDeviceEvent *xev = (XIDeviceEvent *) ev;
         GdkDevice *source_device;
 
-        switch (xev->detail)
+        if (ev->evtype == XI_ButtonPress &&
+            (xev->detail >= 4 && xev->detail <= 7))
           {
-          case 4:
-          case 5:
-          case 6:
-          case 7:
-             /* Button presses of button 4-7 are scroll events */
-            if (ev->evtype == XI_ButtonPress)
-              {
-                event->scroll.type = GDK_SCROLL;
-
-                if (xev->detail == 4)
-                  event->scroll.direction = GDK_SCROLL_UP;
-                else if (xev->detail == 5)
-                  event->scroll.direction = GDK_SCROLL_DOWN;
-                else if (xev->detail == 6)
-                  event->scroll.direction = GDK_SCROLL_LEFT;
-                else
-                  event->scroll.direction = GDK_SCROLL_RIGHT;
-
-                event->scroll.window = window;
-                event->scroll.time = xev->time;
-                event->scroll.x = (gdouble) xev->event_x;
-                event->scroll.y = (gdouble) xev->event_y;
-                event->scroll.x_root = (gdouble) xev->root_x;
-                event->scroll.y_root = (gdouble) xev->root_y;
-
-                event->scroll.device = g_hash_table_lookup (device_manager->id_table,
-                                                            GUINT_TO_POINTER (xev->deviceid));
-
-                source_device = g_hash_table_lookup (device_manager->id_table,
-                                                     GUINT_TO_POINTER (xev->sourceid));
-                gdk_event_set_source_device (event, source_device);
-
-                event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
-                break;
-              }
-            /* Button presses of button 4-7 are scroll events, so ignore the release */
-            else if (ev->evtype == XI_ButtonRelease)
-              {
-                return_val = FALSE;
-                break;
-              }
-            /* else (XI_ButtonRelease) fall thru */
-          default:
-            event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
+            /* Button presses of button 4-7 are scroll events */
+            event->scroll.type = GDK_SCROLL;
+
+            if (xev->detail == 4)
+              event->scroll.direction = GDK_SCROLL_UP;
+            else if (xev->detail == 5)
+              event->scroll.direction = GDK_SCROLL_DOWN;
+            else if (xev->detail == 6)
+              event->scroll.direction = GDK_SCROLL_LEFT;
+            else
+              event->scroll.direction = GDK_SCROLL_RIGHT;
+
+            event->scroll.window = window;
+            event->scroll.time = xev->time;
+            event->scroll.x = (gdouble) xev->event_x;
+            event->scroll.y = (gdouble) xev->event_y;
+            event->scroll.x_root = (gdouble) xev->root_x;
+            event->scroll.y_root = (gdouble) xev->root_y;
+
+            event->scroll.device = g_hash_table_lookup (device_manager->id_table,
+                                                        GUINT_TO_POINTER (xev->deviceid));
+
+            source_device = g_hash_table_lookup (device_manager->id_table,
+                                                 GUINT_TO_POINTER (xev->sourceid));
+            gdk_event_set_source_device (event, source_device);
+
+            event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
+          }
+        else
+          {
+#ifdef XINPUT_2_2
+            if (ev->evtype == XI_TouchBegin)
+              event->button.type = GDK_TOUCH_PRESS;
+	    else if (ev->evtype == XI_TouchEnd)
+              event->button.type = GDK_TOUCH_RELEASE;
+            else
+#endif /* XINPUT_2_2 */
+              event->button.type = (ev->evtype == XI_ButtonPress) ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
 
             event->button.window = window;
             event->button.time = xev->time;
@@ -1160,7 +1165,17 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
               }
 
             event->button.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
-            event->button.button = xev->detail;
+
+#ifdef XINPUT_2_2
+            if (ev->evtype == XI_TouchBegin ||
+                ev->evtype == XI_TouchEnd)
+              {
+                event->button.button = 1;
+                event->button.touch_id = xev->detail;
+              }
+            else
+#endif /* XINPUT_2_2 */
+              event->button.button = xev->detail;
           }
 
         if (return_val == FALSE)
@@ -1178,11 +1193,25 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
         break;
       }
     case XI_Motion:
+#ifdef XINPUT_2_2
+    case XI_TouchUpdate:
+#endif /* XINPUT_2_2 */
       {
         XIDeviceEvent *xev = (XIDeviceEvent *) ev;
         GdkDevice *source_device;
 
-        event->motion.type = GDK_MOTION_NOTIFY;
+        if (ev->evtype == XI_Motion)
+          {
+            event->motion.touch_id = 0;
+            event->motion.type = GDK_MOTION_NOTIFY;
+          }
+#ifdef XINPUT_2_2
+        else
+          {
+            event->motion.touch_id = xev->detail;
+            event->motion.type = GDK_TOUCH_MOTION;
+          }
+#endif
 
         event->motion.window = window;
 
@@ -1316,7 +1345,8 @@ gdk_x11_device_manager_xi2_get_handled_events (GdkEventTranslator *translator)
           GDK_BUTTON2_MOTION_MASK |
           GDK_BUTTON3_MOTION_MASK |
           GDK_BUTTON_MOTION_MASK |
-          GDK_FOCUS_CHANGE_MASK);
+          GDK_FOCUS_CHANGE_MASK |
+          GDK_TOUCH_MASK);
 }
 
 static void
@@ -1330,7 +1360,9 @@ gdk_x11_device_manager_xi2_select_window_events (GdkEventTranslator *translator,
   device_manager = GDK_DEVICE_MANAGER (translator);
 
   event_mask.deviceid = XIAllMasterDevices;
-  event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (evmask, &event_mask.mask_len);
+  event_mask.mask = _gdk_x11_device_xi2_translate_event_mask (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
+                                                              evmask,
+                                                              &event_mask.mask_len);
 
   _gdk_x11_device_manager_xi2_select_events (device_manager, window, &event_mask);
   g_free (event_mask.mask);
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 7a65581..803dad7 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -247,8 +247,9 @@ void _gdk_x11_device_xi_translate_axes     (GdkDevice *device,
 #endif
 
 #ifdef XINPUT_2
-guchar * _gdk_x11_device_xi2_translate_event_mask (GdkEventMask     event_mask,
-                                                   gint            *len);
+guchar * _gdk_x11_device_xi2_translate_event_mask (GdkX11DeviceManagerXI2 *device_manager_xi2,
+                                                   GdkEventMask            event_mask,
+                                                   gint                   *len);
 guint    _gdk_x11_device_xi2_translate_state      (XIModifierState *mods_state,
                                                    XIButtonState   *buttons_state,
                                                    XIGroupState    *group_state);



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