From 8528385c80a3daac9f8b3f1a798c23df7db0466d Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 7 Feb 2012 00:21:19 +0100 Subject: [PATCH] touchcluster: use an array to store touch IDs A GList doesn't make much sense for storing guints, so now a GArray is used internally. gdk_touch_cluster_get_touches() has changed to return an allocated guint*, and gdk_touch_cluster_get_n_touches() has been added too. --- demos/gtk-demo/multitouch.c | 2 +- gdk/gdktouchcluster.c | 90 +++++++++++++++++++++++++------------ gdk/gdktouchcluster.h | 4 +- gdk/gdkwindow.c | 17 +++---- 4 files changed, 73 insertions(+), 40 deletions(-) diff --git a/demos/gtk-demo/multitouch.c b/demos/gtk-demo/multitouch.c index 0fcec64ca0..ef9d8af99b 100644 --- a/demos/gtk-demo/multitouch.c +++ b/demos/gtk-demo/multitouch.c @@ -412,7 +412,7 @@ button_press_cb (GtkWidget *widget, if (!shape->cluster) shape->cluster = gdk_window_create_touch_cluster (gtk_widget_get_window (widget), gdk_event_get_device (event)); - else if (!gdk_touch_cluster_get_touches (shape->cluster)) + else if (gdk_touch_cluster_get_n_touches (shape->cluster) == 0) { /* Only change cluster device if there were no touches */ gdk_touch_cluster_set_device (shape->cluster, diff --git a/gdk/gdktouchcluster.c b/gdk/gdktouchcluster.c index 8232fc20c5..6a3e9b9ef9 100644 --- a/gdk/gdktouchcluster.c +++ b/gdk/gdktouchcluster.c @@ -116,7 +116,7 @@ typedef struct GdkTouchClusterPrivate GdkTouchClusterPrivate; struct GdkTouchClusterPrivate { GdkDevice *device; - GList *touches; + GArray *touches; }; enum { @@ -186,9 +186,12 @@ gdk_touch_cluster_class_init (GdkTouchClusterClass *klass) static void gdk_touch_cluster_init (GdkTouchCluster *cluster) { - cluster->priv = G_TYPE_INSTANCE_GET_PRIVATE (cluster, - GDK_TYPE_TOUCH_CLUSTER, - GdkTouchClusterPrivate); + GdkTouchClusterPrivate *priv; + + priv = cluster->priv = G_TYPE_INSTANCE_GET_PRIVATE (cluster, + GDK_TYPE_TOUCH_CLUSTER, + GdkTouchClusterPrivate); + priv->touches = g_array_new (FALSE, FALSE, sizeof (guint)); } static void @@ -197,7 +200,7 @@ gdk_touch_cluster_finalize (GObject *object) GdkTouchClusterPrivate *priv; priv = GDK_TOUCH_CLUSTER (object)->priv; - g_list_free (priv->touches); + g_array_free (priv->touches, TRUE); G_OBJECT_CLASS (gdk_touch_cluster_parent_class)->finalize (object); } @@ -261,16 +264,20 @@ gdk_touch_cluster_add_touch (GdkTouchCluster *cluster, guint touch_id) { GdkTouchClusterPrivate *priv; + gint i; g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster)); priv = cluster->priv; - if (!g_list_find (priv->touches, GUINT_TO_POINTER (touch_id))) + for (i = 0; i < priv->touches->len; i++) { - priv->touches = g_list_prepend (priv->touches, GUINT_TO_POINTER (touch_id)); - g_signal_emit (cluster, signals [TOUCH_ADDED], 0, touch_id); + if (touch_id == g_array_index (priv->touches, guint, i)) + return; } + + g_array_append_val (priv->touches, touch_id); + g_signal_emit (cluster, signals [TOUCH_ADDED], 0, touch_id); } /** @@ -294,19 +301,20 @@ gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster, guint touch_id) { GdkTouchClusterPrivate *priv; - GList *link; + gint i; g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster)); priv = cluster->priv; - link = g_list_find (priv->touches, GUINT_TO_POINTER (touch_id)); - - if (link) + for (i = 0; i < priv->touches->len; i++) { - priv->touches = g_list_remove_link (priv->touches, link); - g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id); - g_list_free1 (link); + if (touch_id == g_array_index (priv->touches, guint, i)) + { + g_array_remove_index_fast (priv->touches, i); + g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id); + return; + } } } @@ -322,43 +330,69 @@ void gdk_touch_cluster_remove_all (GdkTouchCluster *cluster) { GdkTouchClusterPrivate *priv; - GList *link; + guint touch_id; + gint i; g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster)); priv = cluster->priv; - link = priv->touches; - while (link) + for (i = priv->touches->len - 1; i >= 0; i--) { - priv->touches = g_list_remove_link (priv->touches, link); - g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, link->data); + touch_id = g_array_index (priv->touches, guint, i); + g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id); + g_array_remove_index_fast (priv->touches, i); } - - g_list_free (priv->touches); - priv->touches = NULL; } /** * gdk_touch_cluster_get_touches: * @cluster: a #GdkTouchCluster + * @length: return location for the number of touches returned * - * Returns a const list of touch IDs as #guint. + * Returns the list of touches as an array of @guint. * - * Returns: (transfer none) (element-type uint): A list of touch IDs. + * Returns: (transfer full) (array zero-terminated=0 length=length) (element-type uint): A list of touch IDs. * * Since: 3.4 **/ -GList * -gdk_touch_cluster_get_touches (GdkTouchCluster *cluster) +guint * +gdk_touch_cluster_get_touches (GdkTouchCluster *cluster, + gint *len) { GdkTouchClusterPrivate *priv; g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), NULL); priv = cluster->priv; - return priv->touches; + + if (len) + *len = (gint) priv->touches->len; + + return g_memdup (priv->touches->data, + sizeof (guint) * priv->touches->len); +} + +/** + * gdk_touch_cluster_get_n_touches: + * @cluster: a #GdkTouchCluster + * + * Returns the number of touches contained in @cluster. + * + * Returns: The number of touches. + * + * Since: 3.4 + **/ +gint +gdk_touch_cluster_get_n_touches (GdkTouchCluster *cluster) +{ + GdkTouchClusterPrivate *priv; + + g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), 0); + + priv = cluster->priv; + return (gint) priv->touches->len; } /** diff --git a/gdk/gdktouchcluster.h b/gdk/gdktouchcluster.h index 0904df57dd..b71ec4cf02 100644 --- a/gdk/gdktouchcluster.h +++ b/gdk/gdktouchcluster.h @@ -58,7 +58,9 @@ void gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster, guint touch_id); void gdk_touch_cluster_remove_all (GdkTouchCluster *cluster); -GList * gdk_touch_cluster_get_touches (GdkTouchCluster *cluster); +guint * gdk_touch_cluster_get_touches (GdkTouchCluster *cluster, + gint *length); +gint gdk_touch_cluster_get_n_touches (GdkTouchCluster *cluster); void gdk_touch_cluster_set_device (GdkTouchCluster *cluster, GdkDevice *device); diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index ce340844dc..da63916fc3 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -8364,7 +8364,7 @@ gdk_make_multitouch_event (GdkWindow *window, GdkEventMotion **subevents; TouchEventInfo *info; GHashTable *by_touch; - GList *touches; + guint *touches; if (!window->touch_event_tracker) return NULL; @@ -8394,26 +8394,21 @@ gdk_make_multitouch_event (GdkWindow *window, mt_event->multitouch.group = cluster; /* Fill in individual motion sub-events */ - touches = gdk_touch_cluster_get_touches (cluster); - n_touches = g_list_length (touches); - i = 0; - + touches = gdk_touch_cluster_get_touches (cluster, &n_touches); subevents = g_new0 (GdkEventMotion *, n_touches); - while (touches) + for (i = 0; i < n_touches; i++) { TouchEventInfo *subevent_info; GdkEvent *subevent; - subevent_info = g_hash_table_lookup (by_touch, touches->data); + subevent_info = g_hash_table_lookup (by_touch, + GUINT_TO_POINTER (touches[i])); subevent = gdk_event_copy (subevent_info->event); subevents[i] = (GdkEventMotion *) subevent; if (subevent->motion.touch_id == touch_id) n_updated = i; - - touches = touches->next; - i++; } mt_event->multitouch.events = subevents; @@ -8421,6 +8416,8 @@ gdk_make_multitouch_event (GdkWindow *window, mt_event->multitouch.n_events = n_touches; mt_event->multitouch.updated_touch_id = touch_id; + g_free (touches); + return mt_event; }