[gtk/wip/baedert/for-master: 49/56] GdkEvent: Save history in a GArray



commit 895803f592f6ed6c5752e948dfe0b3a6c9b4af4f
Author: Timm Bäder <mail baedert org>
Date:   Sat Apr 25 17:50:11 2020 +0200

    GdkEvent: Save history in a GArray
    
    Instead of a less efficient GList.

 gdk/gdkevents.c        | 38 +++++++++++++++++++++++++++++---------
 gdk/gdkevents.h        |  3 ++-
 gdk/gdkeventsprivate.h | 10 +++++-----
 gtk/gtkgesturestylus.c | 12 +++++++-----
 4 files changed, 43 insertions(+), 20 deletions(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 41706885af..afc8f9c9a0 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -671,22 +671,24 @@ gdk_motion_event_push_history (GdkEvent *event,
                                GdkEvent *history_event)
 {
   GdkMotionEvent *self = (GdkMotionEvent *) event;
-  GdkTimeCoord *hist;
+  GdkTimeCoord hist;
   GdkDevice *device;
   gint i, n_axes;
 
   g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY));
   g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY));
 
-  hist = g_new0 (GdkTimeCoord, 1);
-
   device = gdk_event_get_device (history_event);
   n_axes = gdk_device_get_n_axes (device);
 
   for (i = 0; i <= MIN (n_axes, GDK_MAX_TIMECOORD_AXES); i++)
-    gdk_event_get_axis (history_event, i, &hist->axes[i]);
+    gdk_event_get_axis (history_event, i, &hist.axes[i]);
+
+  if (G_UNLIKELY (!self->history))
+    self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
+
+  g_array_append_val (self->history, hist);
 
-  self->history = g_list_prepend (self->history, hist);
 }
 
 void
@@ -2730,7 +2732,8 @@ gdk_motion_event_finalize (GdkEvent *event)
 
   g_clear_object (&self->tool);
   g_clear_pointer (&self->axes, g_free);
-  g_list_free_full (self->history, g_free);
+  if (self->history)
+    g_array_free (self->history, TRUE);
 
   GDK_EVENT_SUPER (event)->finalize (event);
 }
@@ -2822,6 +2825,7 @@ gdk_motion_event_new (GdkSurface      *surface,
 /**
  * gdk_motion_event_get_history:
  * @event: (type GdkMotionEvent): a motion #GdkEvent
+ * @out_n_coords: (out): Return location for the length of the returned array
  *
  * Retrieves the history of the @event motion, as a list of time and
  * coordinates.
@@ -2829,15 +2833,31 @@ gdk_motion_event_new (GdkSurface      *surface,
  * Returns: (transfer container) (element-type GdkTimeCoord) (nullable): a list
  *   of time and coordinates
  */
-GList *
-gdk_motion_event_get_history (GdkEvent *event)
+GdkTimeCoord *
+gdk_motion_event_get_history (GdkEvent *event,
+                              guint    *out_n_coords)
 {
   GdkMotionEvent *self = (GdkMotionEvent *) event;
 
   g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
   g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY), NULL);
+  g_return_val_if_fail (out_n_coords != NULL, NULL);
+
+  if (self->history &&
+      self->history->len > 0)
+    {
+      GdkTimeCoord *result;
 
-  return g_list_reverse (g_list_copy (self->history));
+      *out_n_coords = self->history->len;
+
+      result = g_malloc (sizeof (GdkTimeCoord) * self->history->len);
+      memcpy (result, self->history->data, sizeof (GdkTimeCoord) * self->history->len);
+
+      return result;
+    }
+
+  *out_n_coords = 0;
+  return NULL;
 }
 
 /* }}} */
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index cd4a46d4d2..e702717541 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -471,7 +471,8 @@ gboolean                gdk_grab_broken_event_get_implicit     (GdkEvent *event)
 GDK_AVAILABLE_IN_ALL
 GType                   gdk_motion_event_get_type       (void) G_GNUC_CONST;
 GDK_AVAILABLE_IN_ALL
-GList *                 gdk_motion_event_get_history    (GdkEvent *event);
+GdkTimeCoord *          gdk_motion_event_get_history    (GdkEvent *event,
+                                                         guint    *out_n_coords);
 
 GDK_AVAILABLE_IN_ALL
 GType                   gdk_delete_event_get_type       (void) G_GNUC_CONST;
diff --git a/gdk/gdkeventsprivate.h b/gdk/gdkeventsprivate.h
index c45df7cc61..0a7b1300cd 100644
--- a/gdk/gdkeventsprivate.h
+++ b/gdk/gdkeventsprivate.h
@@ -127,7 +127,7 @@ struct _GdkMotionEvent
   double y;
   double *axes;
   GdkDeviceTool *tool;
-  GList *history;
+  GArray *history; /* <GdkTimeCoord> */
 };
 
 /*
@@ -343,7 +343,7 @@ struct _GdkConfigureEvent
 
 /*
  * GdkProximityEvent:
- * @tool: the #GdkDeviceTool associated to the event 
+ * @tool: the #GdkDeviceTool associated to the event
  *
  * A proximity event indicates that a tool of a graphic tablet, or similar
  * devices that report proximity, has moved in or out of contact with the
@@ -456,7 +456,7 @@ GdkEvent * gdk_button_event_new         (GdkEventType     type,
                                          double           x,
                                          double           y,
                                          double          *axes);
-                             
+
 GdkEvent * gdk_motion_event_new         (GdkSurface      *surface,
                                          GdkDevice       *device,
                                          GdkDevice       *source_device,
@@ -477,7 +477,7 @@ GdkEvent * gdk_crossing_event_new       (GdkEventType     type,
                                          double           y,
                                          GdkCrossingMode  mode,
                                          GdkNotifyType    notify);
-                                          
+
 GdkEvent * gdk_proximity_event_new      (GdkEventType     type,
                                          GdkSurface      *surface,
                                          GdkDevice       *device,
@@ -537,7 +537,7 @@ GdkEvent * gdk_touch_event_new          (GdkEventType      type,
                                          double            y,
                                          double           *axes,
                                          gboolean          emulating);
- 
+
 GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface      *surface,
                                          GdkDevice       *device,
                                          GdkDevice       *source_device,
diff --git a/gtk/gtkgesturestylus.c b/gtk/gtkgesturestylus.c
index 5944f0252e..974d83f0a9 100644
--- a/gtk/gtkgesturestylus.c
+++ b/gtk/gtkgesturestylus.c
@@ -283,7 +283,8 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus  *gesture,
 {
   GdkEvent *event;
   GArray *backlog_array;
-  GList *history = NULL, *l;
+  GdkTimeCoord *history = NULL;
+  guint n_coords = 0, i;
 
   g_return_val_if_fail (GTK_IS_GESTURE_STYLUS (gesture), FALSE);
   g_return_val_if_fail (backlog != NULL && n_elems != NULL, FALSE);
@@ -291,14 +292,15 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus  *gesture,
   event = gesture_get_current_event (gesture);
 
   if (event && GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY))
-    history = gdk_motion_event_get_history (event);
+    history = gdk_motion_event_get_history (event, &n_coords);
+
   if (!history)
     return FALSE;
 
   backlog_array = g_array_new (FALSE, FALSE, sizeof (GdkTimeCoord));
-  for (l = history; l; l = l->next)
+  for (i = 0; i < n_coords; i++)
     {
-      GdkTimeCoord *time_coord = l->data;
+      GdkTimeCoord *time_coord = &history[i];
       graphene_point_t p;
 
       g_array_append_val (backlog_array, *time_coord);
@@ -320,7 +322,7 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus  *gesture,
 
   *n_elems = backlog_array->len;
   *backlog = (GdkTimeCoord *) g_array_free (backlog_array, FALSE);
-  g_list_free (history);
+  g_free (history);
 
   return TRUE;
 }


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