summaryrefslogtreecommitdiff
path: root/gdk/gdkdisplay.c
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2011-12-28 02:14:18 +0100
committerMatthias Clasen <mclasen@redhat.com>2012-03-01 16:25:25 -0500
commitb5cfdf2db4c4e1bd92d18943fa7471c4fbd85bd3 (patch)
tree6634e2760a0c2510b20d2d34dfc4ca4d1a08fee1 /gdk/gdkdisplay.c
parentb5de12debddabdefafa69091b7df3415d7563046 (diff)
downloadgtk+-b5cfdf2db4c4e1bd92d18943fa7471c4fbd85bd3.tar.gz
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.
Diffstat (limited to 'gdk/gdkdisplay.c')
-rw-r--r--gdk/gdkdisplay.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index bb4be5f6b2..5684247ca0 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 */