GdkEvent: Save history in a GArray

Instead of a less efficient GList.
This commit is contained in:
Timm Bäder 2020-04-25 17:50:11 +02:00
parent 14b27446a3
commit d80c130d7f
4 changed files with 43 additions and 20 deletions

View File

@ -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
@ -2727,7 +2729,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);
}
@ -2819,6 +2822,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.
@ -2826,15 +2830,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);
return g_list_reverse (g_list_copy (self->history));
if (self->history &&
self->history->len > 0)
{
GdkTimeCoord *result;
*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;
}
/* }}} */

View File

@ -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;

View File

@ -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,

View File

@ -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;
}