[gtk+] gdk: Turn GdkEvent into a GObject



commit 2acbb7b01d47f67ab054683a933aa7813333cd35
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Oct 25 13:23:41 2017 +0200

    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 2fb9cc8..80f92ec 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,16 +614,14 @@ gdk_event_copy (const GdkEvent *event)
 void
 gdk_event_free (GdkEvent *event)
 {
-  GdkEventPrivate *private;
-  GdkDisplay *display;
-
-  g_return_if_fail (event != NULL);
+  g_object_unref (event);
+}
 
-  if (gdk_event_is_allocated (event))
-    {
-      private = (GdkEventPrivate *) event;
-      g_clear_object (&private->user_data);
-    }
+void
+gdk_event_finalize (GObject *object)
+{
+  GdkEvent *event = GDK_EVENT (object);
+  GdkDisplay *display;
 
   switch ((guint) event->any.type)
     {
@@ -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 88e1980..db4b779 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 4a8762d..bb3bb47 100644
--- a/gdk/gdkeventsprivate.h
+++ b/gdk/gdkeventsprivate.h
@@ -30,6 +30,17 @@
 #include <gdk/gdkdevice.h>
 #include <gdk/gdkdevicetool.h>
 
+#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 8484114..8e96d20 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


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