From 2acbb7b01d47f67ab054683a933aa7813333cd35 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 25 Oct 2017 13:23:41 +0200 Subject: [PATCH] gdk: Turn GdkEvent into a GObject Two warts remain. gdk_event_copy() should be unnecessary as events should be considered static after delivery, so g_object_ref() should be just as good. There's a few exceptional cases that the event is copied and then modifier for later processing, those cases should be reconsidered individually. And gdk_event_free() could be likewise turned into g_object_unref(), many callers remain though. --- gdk/gdkevents.c | 93 +++++++++++++++++++++++------------------- gdk/gdkevents.h | 5 ++- gdk/gdkeventsprivate.h | 12 ++++++ gdk/gdkinternals.h | 6 --- 4 files changed, 67 insertions(+), 49 deletions(-) diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index 2fb9cc8da7..80f92ec6a6 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -65,6 +65,30 @@ static GdkEventFunc _gdk_event_func = NULL; /* Callback for events */ static gpointer _gdk_event_data = NULL; static GDestroyNotify _gdk_event_notify = NULL; +static GQuark quark_event_user_data = 0; + +static void gdk_event_finalize (GObject *object); + +G_DEFINE_TYPE (GdkEvent, gdk_event, G_TYPE_OBJECT) + +#define EVENT_PAYLOAD(ev) (&(ev)->any.type) +#define EVENT_PAYLOAD_SIZE (sizeof (GdkEvent) - sizeof (GObject)) + +static void +gdk_event_init (GdkEvent *event) +{ +} + +static void +gdk_event_class_init (GdkEventClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_event_finalize; + + quark_event_user_data = g_quark_from_static_string ("gdk-event-user-data"); +} + void _gdk_event_emit (GdkEvent *event) { @@ -368,17 +392,14 @@ static GHashTable *event_hash = NULL; GdkEvent* gdk_event_new (GdkEventType type) { - GdkEventPrivate *new_private; GdkEvent *new_event; if (!event_hash) event_hash = g_hash_table_new (g_direct_hash, NULL); - new_private = g_slice_new0 (GdkEventPrivate); + new_event = g_object_new (GDK_TYPE_EVENT, NULL); - g_hash_table_insert (event_hash, new_private, GUINT_TO_POINTER (1)); - - new_event = (GdkEvent *) new_private; + g_hash_table_insert (event_hash, new_event, GUINT_TO_POINTER (1)); new_event->any.type = type; @@ -502,15 +523,16 @@ gdk_event_get_pointer_emulated (GdkEvent *event) GdkEvent* gdk_event_copy (const GdkEvent *event) { - GdkEventPrivate *new_private; GdkEvent *new_event; g_return_val_if_fail (event != NULL, NULL); new_event = gdk_event_new (GDK_NOTHING); - new_private = (GdkEventPrivate *)new_event; - *new_event = *event; + memcpy (EVENT_PAYLOAD (new_event), + EVENT_PAYLOAD (event), + EVENT_PAYLOAD_SIZE); + if (new_event->any.window) g_object_ref (new_event->any.window); if (new_event->any.device) @@ -518,12 +540,7 @@ gdk_event_copy (const GdkEvent *event) if (new_event->any.source_device) g_object_ref (new_event->any.source_device); - if (gdk_event_is_allocated (event)) - { - GdkEventPrivate *private = (GdkEventPrivate *)event; - - g_set_object (&new_private->user_data, private->user_data); - } + gdk_event_set_user_data (new_event, gdk_event_get_user_data (event)); switch ((guint) event->any.type) { @@ -597,17 +614,15 @@ gdk_event_copy (const GdkEvent *event) void gdk_event_free (GdkEvent *event) { - GdkEventPrivate *private; + g_object_unref (event); +} + +void +gdk_event_finalize (GObject *object) +{ + GdkEvent *event = GDK_EVENT (object); GdkDisplay *display; - g_return_if_fail (event != NULL); - - if (gdk_event_is_allocated (event)) - { - private = (GdkEventPrivate *) event; - g_clear_object (&private->user_data); - } - switch ((guint) event->any.type) { case GDK_KEY_PRESS: @@ -669,7 +684,8 @@ gdk_event_free (GdkEvent *event) g_clear_object (&event->any.source_device); g_hash_table_remove (event_hash, event); - g_slice_free (GdkEventPrivate, (GdkEventPrivate*) event); + + G_OBJECT_CLASS (gdk_event_parent_class)->finalize (object); } /** @@ -1926,10 +1942,6 @@ gdk_synthesize_window_state (GdkWindow *window, _gdk_set_window_state (window, (window->state | set_flags) & ~unset_flags); } -G_DEFINE_BOXED_TYPE (GdkEvent, gdk_event, - gdk_event_copy, - gdk_event_free) - static GdkEventSequence * gdk_event_sequence_copy (GdkEventSequence *sequence) { @@ -2070,25 +2082,22 @@ void gdk_event_set_user_data (GdkEvent *event, GObject *user_data) { - GdkEventPrivate *private; - - if (!gdk_event_is_allocated (event)) - return; - - private = (GdkEventPrivate *) event; - g_set_object (&private->user_data, user_data); + if (user_data) + { + g_object_set_qdata_full (G_OBJECT (event), quark_event_user_data, + g_object_ref (user_data), + g_object_unref); + } + else + { + g_object_steal_qdata (G_OBJECT (event), quark_event_user_data); + } } GObject * gdk_event_get_user_data (const GdkEvent *event) { - GdkEventPrivate *private; - - if (!gdk_event_is_allocated (event)) - return NULL; - - private = (GdkEventPrivate *) event; - return private->user_data; + return g_object_get_qdata (G_OBJECT (event), quark_event_user_data); } gboolean diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index 88e19809da..db4b779e34 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -53,6 +53,10 @@ G_BEGIN_DECLS #define GDK_TYPE_EVENT (gdk_event_get_type ()) #define GDK_TYPE_EVENT_SEQUENCE (gdk_event_sequence_get_type ()) +#define GDK_EVENT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_EVENT, GdkEvent)) +#define GDK_IS_EVENT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_EVENT)) + + /** * GDK_PRIORITY_EVENTS: * @@ -145,7 +149,6 @@ typedef struct _GdkEventPadAxis GdkEventPadAxis; typedef struct _GdkEventPadGroupMode GdkEventPadGroupMode; typedef struct _GdkEventSequence GdkEventSequence; - typedef union _GdkEvent GdkEvent; /** diff --git a/gdk/gdkeventsprivate.h b/gdk/gdkeventsprivate.h index 4a8762df00..bb3bb473be 100644 --- a/gdk/gdkeventsprivate.h +++ b/gdk/gdkeventsprivate.h @@ -30,6 +30,17 @@ #include #include +#define GDK_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_EVENT, GdkEventClass)) +#define GDK_IS_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_EVENT)) +#define GDK_EVENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_EVENT, GdkEventClass)) + +typedef struct _GdkEventClass GdkEventClass; + +struct _GdkEventClass +{ + GObjectClass object_class; +}; + /** * GdkEventAny: * @type: the type of the event. @@ -42,6 +53,7 @@ */ struct _GdkEventAny { + GObject parent_instance; GdkEventType type; GdkWindow *window; guint16 flags; diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index 8484114353..8e96d203ed 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -143,12 +143,6 @@ typedef enum GDK_EVENT_FLUSHED = 1 << 2 } GdkEventFlags; -struct _GdkEventPrivate -{ - GdkEvent event; - GObject *user_data; -}; - typedef struct _GdkWindowPaint GdkWindowPaint; typedef enum