[gtk+/multitouch: 5/27] Make touch events go through csw/widget event handling.



commit 0bd09b0df484e9c20cc20b257b21e98bbd658e1f
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Feb 28 21:21:17 2011 +0100

    Make touch events go through csw/widget event handling.
    
    In GtkWidget, touch events go through the same handler
    than motion events, with the difference that touch_id
    will have something meaningful there.
    
    Touch events need to be explicitly selected, so if this
    is enabled, the possibility of different motion streams
    with different touch IDs must be handled in some way.

 gdk/gdkwindow.c |   67 ++++++++++++++++++++++++++++++++++++++++++------------
 gtk/gtkmain.c   |   13 ++++++++--
 gtk/gtkwidget.c |    3 ++
 3 files changed, 65 insertions(+), 18 deletions(-)
---
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 8fc22f6..c9587b3 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -8090,6 +8090,8 @@ is_button_type (GdkEventType type)
 	 type == GDK_2BUTTON_PRESS ||
 	 type == GDK_3BUTTON_PRESS ||
 	 type == GDK_BUTTON_RELEASE ||
+         type == GDK_TOUCH_PRESS ||
+         type == GDK_TOUCH_RELEASE ||
 	 type == GDK_SCROLL;
 }
 
@@ -8097,6 +8099,7 @@ static gboolean
 is_motion_type (GdkEventType type)
 {
   return type == GDK_MOTION_NOTIFY ||
+         type == GDK_TOUCH_MOTION ||
 	 type == GDK_ENTER_NOTIFY ||
 	 type == GDK_LEAVE_NOTIFY;
 }
@@ -8159,6 +8162,7 @@ _gdk_make_event (GdkWindow    *window,
   switch (type)
     {
     case GDK_MOTION_NOTIFY:
+    case GDK_TOUCH_MOTION:
       event->motion.time = the_time;
       event->motion.axes = NULL;
       event->motion.state = the_state;
@@ -9239,7 +9243,8 @@ proxy_pointer_event (GdkDisplay                 *display,
 				       serial, non_linear);
       _gdk_display_set_window_under_pointer (display, device, pointer_window);
     }
-  else if (source_event->type == GDK_MOTION_NOTIFY)
+  else if (source_event->type == GDK_MOTION_NOTIFY ||
+           source_event->type == GDK_TOUCH_MOTION)
     {
       GdkWindow *event_win;
       guint evmask;
@@ -9258,6 +9263,15 @@ proxy_pointer_event (GdkDisplay                 *display,
           gdk_window_get_device_events (event_win, device) == 0)
         return TRUE;
 
+      /* Block motion events coming from touch devices, only if
+       * the event mask allows both motion and touch events, since
+       * the latter will come right after.
+       */
+      if ((evmask & GDK_TOUCH_MASK) &&
+          gdk_device_get_source (source_device) == GDK_SOURCE_TOUCH &&
+          source_event->type == GDK_MOTION_NOTIFY)
+        return TRUE;
+
       /* The last device to interact with the window was a touch device,
        * which synthesized a leave notify event, so synthesize another enter
        * notify to tell the pointer is on the window.
@@ -9270,6 +9284,7 @@ proxy_pointer_event (GdkDisplay                 *display,
                                          toplevel_x, toplevel_y,
                                          state, time_, NULL,
                                          serial, FALSE);
+
       is_hint = FALSE;
 
       if (event_win &&
@@ -9290,21 +9305,37 @@ proxy_pointer_event (GdkDisplay                 *display,
 	    }
 	}
 
-      if (event_win && !display->ignore_core_events)
-	{
-	  event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
-	  event->motion.time = time_;
-	  convert_toplevel_coords_to_window (event_win,
-					     toplevel_x, toplevel_y,
-					     &event->motion.x, &event->motion.y);
-	  event->motion.x_root = source_event->motion.x_root;
-	  event->motion.y_root = source_event->motion.y_root;
-	  event->motion.state = state;
-	  event->motion.is_hint = is_hint;
-	  event->motion.device = source_event->motion.device;
+      if (!event_win)
+        return TRUE;
+
+      if (!display->ignore_core_events)
+        {
+          GdkEventType event_type;
+          guint touch_id;
+
+          gdk_event_get_touch_id (source_event, &touch_id);
+          event_type = source_event->type;
+
+          event = gdk_event_new (event_type);
+          event->any.window = g_object_ref (event_win);
+          event->any.send_event = source_event->any.send_event;
+          event->motion.time = time_;
+          convert_toplevel_coords_to_window (event_win,
+                                             toplevel_x, toplevel_y,
+                                             &event->motion.x, &event->motion.y);
+          event->motion.x_root = source_event->motion.x_root;
+          event->motion.y_root = source_event->motion.y_root;
+          event->motion.state = state;
+          event->motion.is_hint = is_hint;
+          event->motion.device = source_event->motion.device;
           event->motion.axes = g_memdup (source_event->motion.axes,
                                          sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
+          event->motion.touch_id = touch_id;
           gdk_event_set_source_device (event, source_device);
+
+          /* Just insert the event */
+          _gdk_event_queue_insert_after (gdk_window_get_display (event_win),
+                                         source_event, event);
 	}
     }
 
@@ -9431,6 +9462,8 @@ proxy_button_event (GdkEvent *source_event,
     {
     case GDK_BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+    case GDK_TOUCH_PRESS:
+    case GDK_TOUCH_RELEASE:
       event->button.button = source_event->button.button;
       convert_toplevel_coords_to_window (event_win,
 					 toplevel_x, toplevel_y,
@@ -9441,6 +9474,7 @@ proxy_button_event (GdkEvent *source_event,
       event->button.device = source_event->button.device;
       event->button.axes = g_memdup (source_event->button.axes,
                                      sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
+      event->button.touch_id = source_event->button.touch_id;
 
       gdk_event_set_source_device (event, source_device);
 
@@ -9703,7 +9737,9 @@ _gdk_windowing_got_event (GdkDisplay *display,
   pointer_info->toplevel_y = y;
   gdk_event_get_state (event, &pointer_info->state);
   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)
     pointer_info->button = event->button.button;
 
   if (device &&
@@ -9720,7 +9756,8 @@ _gdk_windowing_got_event (GdkDisplay *display,
     unlink_event = proxy_button_event (event,
 				       serial);
 
-  if (event->type == GDK_BUTTON_RELEASE &&
+  if ((event->type == GDK_BUTTON_RELEASE ||
+       event->type == GDK_TOUCH_RELEASE) &&
       !event->any.send_event)
     {
       button_release_grab =
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index d4d1651..343d524 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1644,7 +1644,9 @@ gtk_main_do_event (GdkEvent *event)
     case GDK_BUTTON_PRESS:
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
-      if ((event->type == GDK_BUTTON_PRESS) &&
+    case GDK_TOUCH_PRESS:
+      if ((event->type == GDK_BUTTON_PRESS ||
+           event->type == GDK_TOUCH_PRESS) &&
           event->button.button == 1)
         {
           /* Handle press and hold on the grab widget before propagating up,
@@ -1707,10 +1709,14 @@ gtk_main_do_event (GdkEvent *event)
     case GDK_BUTTON_RELEASE:
     case GDK_PROXIMITY_IN:
     case GDK_PROXIMITY_OUT:
-      if ((event->type == GDK_BUTTON_RELEASE) &&
+    case GDK_TOUCH_MOTION:
+    case GDK_TOUCH_RELEASE:
+      if ((event->type == GDK_BUTTON_RELEASE ||
+           event->type == GDK_TOUCH_RELEASE) &&
           event->button.button == 1)
         _gtk_widget_press_and_hold_check_cancel (grab_widget, &event->button);
-      else if (event->type == GDK_MOTION_NOTIFY)
+      else if (event->type == GDK_MOTION_NOTIFY ||
+               event->type == GDK_TOUCH_MOTION)
         _gtk_widget_press_and_hold_check_threshold (grab_widget,
                                                     &event->motion);
 
@@ -1760,6 +1766,7 @@ gtk_main_do_event (GdkEvent *event)
       || event->type == GDK_DRAG_ENTER
       || event->type == GDK_GRAB_BROKEN
       || event->type == GDK_MOTION_NOTIFY
+      || event->type == GDK_TOUCH_MOTION
       || event->type == GDK_SCROLL)
     {
       _gtk_tooltip_handle_event (event);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index d643934..b570e83 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -6251,15 +6251,18 @@ gtk_widget_event_internal (GtkWidget *widget,
 	case GDK_BUTTON_PRESS:
 	case GDK_2BUTTON_PRESS:
 	case GDK_3BUTTON_PRESS:
+        case GDK_TOUCH_PRESS:
 	  signal_num = BUTTON_PRESS_EVENT;
 	  break;
 	case GDK_SCROLL:
 	  signal_num = SCROLL_EVENT;
 	  break;
 	case GDK_BUTTON_RELEASE:
+        case GDK_TOUCH_RELEASE:
 	  signal_num = BUTTON_RELEASE_EVENT;
 	  break;
 	case GDK_MOTION_NOTIFY:
+        case GDK_TOUCH_MOTION:
 	  signal_num = MOTION_NOTIFY_EVENT;
 	  break;
 	case GDK_DELETE:



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