[gtk+/touch-for-3.4-2: 31/44] gdk: Add internal API to deal with touch implicit grabs



commit 07b38f465816092099cd4a0f66973672af44342e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Dec 28 02:14:18 2011 +0100

    gdk: Add internal API to deal with touch implicit grabs
    
    The necessary information about a touch implicit grab is stored in
    GdkTouchGrabInfo structs, these are meant to be transient to the
    touch sequence.

 gdk/gdkdisplay.c        |  103 +++++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkdisplayprivate.h |   29 +++++++++++++
 2 files changed, 132 insertions(+), 0 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index bb4be5f..5684247 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -186,6 +186,7 @@ gdk_display_init (GdkDisplay *display)
   display->double_click_time = 250;
   display->double_click_distance = 5;
 
+  display->touch_implicit_grabs = g_array_new (FALSE, FALSE, sizeof (GdkTouchGrabInfo));
   display->device_grabs = g_hash_table_new (NULL, NULL);
   display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
                                                      (GDestroyNotify) g_free);
@@ -234,6 +235,8 @@ gdk_display_finalize (GObject *object)
                                NULL);
   g_hash_table_destroy (display->device_grabs);
 
+  g_array_free (display->touch_implicit_grabs, TRUE);
+
   g_hash_table_destroy (display->motion_hint_info);
   g_hash_table_destroy (display->pointers_info);
   g_hash_table_destroy (display->multiple_click_info);
@@ -692,6 +695,79 @@ _gdk_display_add_device_grab (GdkDisplay       *display,
   return info;
 }
 
+static void
+_gdk_display_break_touch_grabs (GdkDisplay *display,
+                                GdkDevice  *device,
+                                GdkWindow  *new_grab_window)
+{
+  guint i = 0;
+
+  while (i < display->touch_implicit_grabs->len)
+    {
+      GdkTouchGrabInfo *info;
+
+      info = &g_array_index (display->touch_implicit_grabs,
+                             GdkTouchGrabInfo, i);
+
+      if (info->device == device &&
+          info->window != new_grab_window)
+        {
+          generate_grab_broken_event (GDK_WINDOW (info->window),
+                                      device, TRUE, new_grab_window);
+          g_array_remove_index_fast (display->touch_implicit_grabs, i);
+        }
+      else
+        i++;
+    }
+}
+
+void
+_gdk_display_add_touch_grab (GdkDisplay       *display,
+                             GdkDevice        *device,
+                             GdkEventSequence *sequence,
+                             GdkWindow        *window,
+                             GdkWindow        *native_window,
+                             GdkEventMask      event_mask,
+                             unsigned long     serial,
+                             guint32           time)
+{
+  GdkTouchGrabInfo info;
+
+  info.device = device;
+  info.sequence = sequence;
+  info.window = g_object_ref (window);
+  info.native_window = g_object_ref (native_window);
+  info.serial = serial;
+  info.event_mask = event_mask;
+  info.time = time;
+
+  g_array_append_val (display->touch_implicit_grabs, info);
+}
+
+gboolean
+_gdk_display_end_touch_grab (GdkDisplay       *display,
+                             GdkDevice        *device,
+                             GdkEventSequence *sequence)
+{
+  guint i;
+
+  for (i = 0; i < display->touch_implicit_grabs->len; i++)
+    {
+      GdkTouchGrabInfo *info;
+
+      info = &g_array_index (display->touch_implicit_grabs,
+                             GdkTouchGrabInfo, i);
+
+      if (info->device == device && info->sequence == sequence)
+        {
+          g_array_remove_index_fast (display->touch_implicit_grabs, i);
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
 /* _gdk_synthesize_crossing_events only works inside one toplevel.
    This function splits things into two calls if needed, converting the
    coordinates to the right toplevel */
@@ -1037,6 +1113,33 @@ _gdk_display_has_device_grab (GdkDisplay *display,
   return NULL;
 }
 
+GdkTouchGrabInfo *
+_gdk_display_has_touch_grab (GdkDisplay       *display,
+                             GdkDevice        *device,
+                             GdkEventSequence *sequence,
+                             gulong            serial)
+{
+  guint i;
+
+  for (i = 0; i < display->touch_implicit_grabs->len; i++)
+    {
+      GdkTouchGrabInfo *info;
+
+      info = &g_array_index (display->touch_implicit_grabs,
+                             GdkTouchGrabInfo, i);
+
+      if (info->device == device && info->sequence == sequence)
+        {
+          if (serial >= info->serial)
+            return info;
+          else
+            return NULL;
+        }
+    }
+
+  return NULL;
+}
+
 /* Returns true if last grab was ended
  * If if_child is non-NULL, end the grab only if the grabbed
  * window is the same as if_child or a descendant of it */
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index 62c2cc0..8713cf7 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -58,6 +58,19 @@ typedef struct
   guint implicit : 1;
 } GdkDeviceGrabInfo;
 
+/* Tracks information about a touch implicit grab on this display */
+typedef struct
+{
+  GdkDevice *device;
+  GdkEventSequence *sequence;
+
+  GdkWindow *window;
+  GdkWindow *native_window;
+  gulong serial;
+  guint event_mask;
+  guint32 time;
+} GdkTouchGrabInfo;
+
 /* Tracks information about which window and position the pointer last was in.
  * This is useful when we need to synthesize events later.
  * Note that we track toplevel_under_pointer using enter/leave events,
@@ -103,6 +116,7 @@ struct _GdkDisplay
   guint closed             : 1;  /* Whether this display has been closed */
   guint ignore_core_events : 1;  /* Don't send core motion and button event */
 
+  GArray *touch_implicit_grabs;
   GHashTable *device_grabs;
   GHashTable *motion_hint_info;
   GdkDeviceManager *device_manager;
@@ -260,6 +274,21 @@ gboolean            _gdk_display_end_device_grab      (GdkDisplay       *display
 gboolean            _gdk_display_check_grab_ownership (GdkDisplay       *display,
                                                        GdkDevice        *device,
                                                        gulong            serial);
+void                _gdk_display_add_touch_grab       (GdkDisplay       *display,
+                                                       GdkDevice        *device,
+                                                       GdkEventSequence *sequence,
+                                                       GdkWindow        *window,
+                                                       GdkWindow        *native_window,
+                                                       GdkEventMask      event_mask,
+                                                       unsigned long     serial_start,
+                                                       guint32           time);
+GdkTouchGrabInfo *  _gdk_display_has_touch_grab       (GdkDisplay       *display,
+                                                       GdkDevice        *device,
+                                                       GdkEventSequence *sequence,
+                                                       gulong            serial);
+gboolean            _gdk_display_end_touch_grab       (GdkDisplay       *display,
+                                                       GdkDevice        *device,
+                                                       GdkEventSequence *sequence);
 void                _gdk_display_enable_motion_hints  (GdkDisplay       *display,
                                                        GdkDevice        *device);
 GdkPointerWindowInfo * _gdk_display_get_pointer_info  (GdkDisplay       *display,



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