[gtk+/multitouch: 126/129] touchcluster: use an array to store touch IDs



commit 8528385c80a3daac9f8b3f1a798c23df7db0466d
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Feb 7 00:21:19 2012 +0100

    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 0fcec64..ef9d8af 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 8232fc2..6a3e9b9 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 0904df5..b71ec4c 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 ce34084..da63916 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;
 }
 



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