Blob Blame History Raw
From 1a5275cdb099e3b15f82cabdd55d2eb6c5196c39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Thu, 11 Jul 2019 13:32:01 +0200
Subject: [PATCH 08/28] clutter/event: Use all-events Hash table as a Set with
 auto deletion

Avoid allocating memory for the value, since we don't use it, just add the key
to the table, and check for its presence.

Use a custom free function to free the event data and unref the GOBjects, so
that in clutter_event_free we don't have to both check for the event presence
in the set, clear the data and eventually remove it from the table, but we
can just rely on a single g_hash_table_remove() call.

This required to change the event data free/copy functions signatures so that
we can pass to them the platform data directly, otherwise we might try to call
get_platform_data on an even that has already been removed from the table, and
thus that is not considered allocated anymore, causing a leak.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/682
---
 clutter/clutter/clutter-backend-private.h     | 16 +++----
 clutter/clutter/clutter-backend.c             | 21 ++++-----
 .../clutter/clutter-device-manager-private.h  |  7 ++-
 clutter/clutter/clutter-event.c               | 45 +++++++++++--------
 .../evdev/clutter-device-manager-evdev.c      | 15 +++----
 .../clutter/x11/clutter-device-manager-xi2.c  | 17 +++----
 6 files changed, 60 insertions(+), 61 deletions(-)

diff --git a/clutter/clutter/clutter-backend-private.h b/clutter/clutter/clutter-backend-private.h
index 864d896a3..2438f83e1 100644
--- a/clutter/clutter/clutter-backend-private.h
+++ b/clutter/clutter/clutter-backend-private.h
@@ -63,100 +63,98 @@ struct _ClutterBackend
 };
 
 struct _ClutterBackendClass
 {
   /*< private >*/
   GObjectClass parent_class;
 
   /* vfuncs */
   gboolean              (* pre_parse)          (ClutterBackend  *backend,
                                                 GError         **error);
   gboolean              (* post_parse)         (ClutterBackend  *backend,
                                                 GError         **error);
   ClutterStageWindow *  (* create_stage)       (ClutterBackend  *backend,
                                                 ClutterStage    *wrapper,
                                                 GError         **error);
   void                  (* init_events)        (ClutterBackend  *backend);
   void                  (* init_features)      (ClutterBackend  *backend);
   void                  (* add_options)        (ClutterBackend  *backend,
                                                 GOptionGroup    *group);
   ClutterFeatureFlags   (* get_features)       (ClutterBackend  *backend);
   CoglRenderer *        (* get_renderer)       (ClutterBackend  *backend,
                                                 GError         **error);
   CoglDisplay *         (* get_display)        (ClutterBackend  *backend,
                                                 CoglRenderer    *renderer,
                                                 CoglSwapChain   *swap_chain,
                                                 GError         **error);
   gboolean              (* create_context)     (ClutterBackend  *backend,
                                                 GError         **error);
   ClutterDeviceManager *(* get_device_manager) (ClutterBackend  *backend);
 
-  void                  (* copy_event_data)    (ClutterBackend     *backend,
-                                                const ClutterEvent *src,
-                                                ClutterEvent       *dest);
-  void                  (* free_event_data)    (ClutterBackend     *backend,
-                                                ClutterEvent       *event);
+  gpointer              (* copy_event_data)    (ClutterBackend *backend,
+                                                gpointer        data);
+  void                  (* free_event_data)    (ClutterBackend *backend,
+                                                gpointer        data);
 
   gboolean              (* translate_event)    (ClutterBackend     *backend,
                                                 gpointer            native,
                                                 ClutterEvent       *event);
 
   PangoDirection        (* get_keymap_direction) (ClutterBackend   *backend);
 
   void                  (* bell_notify)          (ClutterBackend   *backend);
 
   /* signals */
   void (* resolution_changed) (ClutterBackend *backend);
   void (* font_changed)       (ClutterBackend *backend);
   void (* settings_changed)   (ClutterBackend *backend);
 };
 
 ClutterBackend *        _clutter_create_backend                         (void);
 
 ClutterStageWindow *    _clutter_backend_create_stage                   (ClutterBackend         *backend,
                                                                          ClutterStage           *wrapper,
                                                                          GError                **error);
 gboolean                _clutter_backend_create_context                 (ClutterBackend         *backend,
                                                                          GError                **error);
 
 void                    _clutter_backend_add_options                    (ClutterBackend         *backend,
                                                                          GOptionGroup           *group);
 gboolean                _clutter_backend_pre_parse                      (ClutterBackend         *backend,
                                                                          GError                **error);
 gboolean                _clutter_backend_post_parse                     (ClutterBackend         *backend,
                                                                          GError                **error);
 
 void                    _clutter_backend_init_events                    (ClutterBackend         *backend);
-void                    _clutter_backend_copy_event_data                (ClutterBackend         *backend,
-                                                                         const ClutterEvent     *src,
-                                                                         ClutterEvent           *dest);
+gpointer                _clutter_backend_copy_event_data                (ClutterBackend         *backend,
+                                                                         const gpointer          data);
 void                    _clutter_backend_free_event_data                (ClutterBackend         *backend,
-                                                                         ClutterEvent           *event);
+                                                                         gpointer                data);
 gboolean                _clutter_backend_translate_event                (ClutterBackend         *backend,
                                                                          gpointer                native,
                                                                          ClutterEvent           *event);
 
 CLUTTER_AVAILABLE_IN_MUTTER
 void                    _clutter_backend_add_event_translator           (ClutterBackend         *backend,
                                                                          ClutterEventTranslator *translator);
 
 void                    _clutter_backend_remove_event_translator        (ClutterBackend         *backend,
                                                                          ClutterEventTranslator *translator);
 
 ClutterFeatureFlags     _clutter_backend_get_features                   (ClutterBackend         *backend);
 
 gfloat                  _clutter_backend_get_units_per_em               (ClutterBackend         *backend,
                                                                          PangoFontDescription   *font_desc);
 gint32                  _clutter_backend_get_units_serial               (ClutterBackend         *backend);
 
 PangoDirection          _clutter_backend_get_keymap_direction           (ClutterBackend         *backend);
 
 CLUTTER_AVAILABLE_IN_MUTTER
 void                    _clutter_backend_reset_cogl_framebuffer         (ClutterBackend         *backend);
 
 void                    clutter_set_allowed_drivers                     (const char             *drivers);
 
 void                    clutter_try_set_windowing_backend               (const char             *drivers);
 
 G_END_DECLS
 
 #endif /* __CLUTTER_BACKEND_PRIVATE_H__ */
diff --git a/clutter/clutter/clutter-backend.c b/clutter/clutter/clutter-backend.c
index 69aeec5eb..41ea3daed 100644
--- a/clutter/clutter/clutter-backend.c
+++ b/clutter/clutter/clutter-backend.c
@@ -804,96 +804,97 @@ _clutter_backend_get_features (ClutterBackend *backend)
     return klass->get_features (backend);
   
   return 0;
 }
 
 void
 _clutter_backend_init_events (ClutterBackend *backend)
 {
   ClutterBackendClass *klass;
 
   g_assert (CLUTTER_IS_BACKEND (backend));
 
   klass = CLUTTER_BACKEND_GET_CLASS (backend);
   klass->init_events (backend);
 }
 
 gfloat
 _clutter_backend_get_units_per_em (ClutterBackend       *backend,
                                    PangoFontDescription *font_desc)
 {
   /* recompute for the font description, but do not cache the result */
   if (font_desc != NULL)
     return get_units_per_em (backend, font_desc);
 
   if (backend->units_per_em < 0)
     backend->units_per_em = get_units_per_em (backend, NULL);
 
   return backend->units_per_em;
 }
 
-void
-_clutter_backend_copy_event_data (ClutterBackend     *backend,
-                                  const ClutterEvent *src,
-                                  ClutterEvent       *dest)
+gpointer
+_clutter_backend_copy_event_data (ClutterBackend *backend,
+                                  gpointer        data)
 {
   ClutterEventExtenderInterface *iface;
   ClutterBackendClass *klass;
 
   klass = CLUTTER_BACKEND_GET_CLASS (backend);
   if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager))
     {
       iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager);
-      iface->copy_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager),
-                              src, dest);
+      return iface->copy_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager),
+                                     data);
     }
   else if (klass->copy_event_data != NULL)
-    klass->copy_event_data (backend, src, dest);
+    return klass->copy_event_data (backend, data);
+
+  return NULL;
 }
 
 void
 _clutter_backend_free_event_data (ClutterBackend *backend,
-                                  ClutterEvent   *event)
+                                  gpointer        data)
 {
   ClutterEventExtenderInterface *iface;
   ClutterBackendClass *klass;
 
   klass = CLUTTER_BACKEND_GET_CLASS (backend);
 
   if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager))
     {
       iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager);
       iface->free_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager),
-                              event);
+                              data);
     }
   else if (klass->free_event_data != NULL)
-    klass->free_event_data (backend, event);
+    klass->free_event_data (backend, data);
 }
 
 /**
  * clutter_get_default_backend:
  *
  * Retrieves the default #ClutterBackend used by Clutter. The
  * #ClutterBackend holds backend-specific configuration options.
  *
  * Return value: (transfer none): the default backend. You should
  *   not ref or unref the returned object. Applications should rarely
  *   need to use this.
  *
  * Since: 0.4
  */
 ClutterBackend *
 clutter_get_default_backend (void)
 {
   ClutterMainContext *clutter_context;
 
   clutter_context = _clutter_context_get_default ();
 
   return clutter_context->backend;
 }
 
 /**
  * clutter_backend_set_double_click_time:
  * @backend: a #ClutterBackend
  * @msec: milliseconds between two button press events
  *
  * Sets the maximum time between two button press events, used to
diff --git a/clutter/clutter/clutter-device-manager-private.h b/clutter/clutter/clutter-device-manager-private.h
index 2364fd27c..6b2c20c72 100644
--- a/clutter/clutter/clutter-device-manager-private.h
+++ b/clutter/clutter/clutter-device-manager-private.h
@@ -159,65 +159,64 @@ struct _ClutterInputDeviceClass
                              ClutterInputDeviceTool *tool);
 
   gboolean (* is_mode_switch_button) (ClutterInputDevice *device,
                                       guint               group,
                                       guint               button);
   gint (* get_group_n_modes) (ClutterInputDevice *device,
                               gint                group);
 
   gboolean (* is_grouped) (ClutterInputDevice *device,
                            ClutterInputDevice *other_device);
 
   /* Keyboard accessbility */
   void (* process_kbd_a11y_event) (ClutterEvent               *event,
                                    ClutterInputDevice         *device,
                                    ClutterEmitInputDeviceEvent emit_event_func);
 };
 
 /* Platform-dependent interface */
 typedef struct _ClutterEventExtender ClutterEventExtender;
 typedef struct _ClutterEventExtenderInterface ClutterEventExtenderInterface;
 
 #define CLUTTER_TYPE_EVENT_EXTENDER         (clutter_event_extender_get_type ())
 #define CLUTTER_EVENT_EXTENDER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtender))
 #define CLUTTER_IS_EVENT_EXTENDER(o)	     (G_TYPE_CHECK_INSTANCE_TYPE ((o), CLUTTER_TYPE_EVENT_EXTENDER))
 #define CLUTTER_EVENT_EXTENDER_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtenderInterface))
 
 struct _ClutterEventExtenderInterface
 {
   GTypeInterface g_iface;
 
-  void (* copy_event_data) (ClutterEventExtender *event_extender,
-                            const ClutterEvent   *src,
-                            ClutterEvent         *dest);
+  gpointer (* copy_event_data) (ClutterEventExtender *event_extender,
+                                gpointer              data);
   void (* free_event_data) (ClutterEventExtender *event_extender,
-                            ClutterEvent         *event);
+                            gpointer              data);
 };
 
 GType           clutter_event_extender_get_type        (void) G_GNUC_CONST;
 
 /* device manager */
 void            _clutter_device_manager_add_device              (ClutterDeviceManager *device_manager,
                                                                  ClutterInputDevice   *device);
 void            _clutter_device_manager_remove_device           (ClutterDeviceManager *device_manager,
                                                                  ClutterInputDevice   *device);
 void            _clutter_device_manager_update_devices          (ClutterDeviceManager *device_manager);
 void            _clutter_device_manager_select_stage_events     (ClutterDeviceManager *device_manager,
                                                                  ClutterStage         *stage);
 ClutterBackend *_clutter_device_manager_get_backend             (ClutterDeviceManager *device_manager);
 
 void            _clutter_device_manager_compress_motion         (ClutterDeviceManager *device_manger,
                                                                  ClutterEvent         *event,
                                                                  const ClutterEvent   *to_discard);
 
 /* input device */
 gboolean        _clutter_input_device_has_sequence              (ClutterInputDevice   *device,
                                                                  ClutterEventSequence *sequence);
 void            _clutter_input_device_add_event_sequence        (ClutterInputDevice   *device,
                                                                  ClutterEvent         *event);
 void            _clutter_input_device_remove_event_sequence     (ClutterInputDevice   *device,
                                                                  ClutterEvent         *event);
 void            _clutter_input_device_set_coords                (ClutterInputDevice   *device,
                                                                  ClutterEventSequence *sequence,
                                                                  gfloat                x,
                                                                  gfloat                y,
                                                                  ClutterStage         *stage);
diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c
index 1b21b6a97..60bdd325c 100644
--- a/clutter/clutter/clutter-event.c
+++ b/clutter/clutter/clutter-event.c
@@ -77,61 +77,73 @@ typedef struct _ClutterEventFilter {
 
 static GHashTable *all_events = NULL;
 
 G_DEFINE_BOXED_TYPE (ClutterEvent, clutter_event,
                      clutter_event_copy,
                      clutter_event_free);
 
 static ClutterEventSequence *
 clutter_event_sequence_copy (ClutterEventSequence *sequence)
 {
   /* Nothing to copy here */
   return sequence;
 }
 
 static void
 clutter_event_sequence_free (ClutterEventSequence *sequence)
 {
   /* Nothing to free here */
 }
 
 G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence,
                      clutter_event_sequence_copy,
                      clutter_event_sequence_free);
 
 static gboolean
 is_event_allocated (const ClutterEvent *event)
 {
   if (all_events == NULL)
     return FALSE;
 
-  return g_hash_table_lookup (all_events, event) != NULL;
+  return g_hash_table_contains (all_events, event);
+}
+
+static void
+clutter_event_private_data_free (ClutterEvent *event)
+{
+  ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
+
+  _clutter_backend_free_event_data (clutter_get_default_backend (),
+                                    real_event->platform_data);
+
+  g_clear_object (&real_event->device);
+  g_clear_object (&real_event->source_device);
 }
 
 /*
  * _clutter_event_get_platform_data:
  * @event: a #ClutterEvent
  *
  * Retrieves the pointer to platform-specific data inside an event
  *
  * Return value: a pointer to platform-specific data
  *
  * Since: 1.4
  */
 gpointer
 _clutter_event_get_platform_data (const ClutterEvent *event)
 {
   if (!is_event_allocated (event))
     return NULL;
 
   return ((ClutterEventPrivate *) event)->platform_data;
 }
 
 /*< private >
  * _clutter_event_set_platform_data:
  * @event: a #ClutterEvent
  * @data: a pointer to platform-specific data
  *
  * Sets the pointer to platform-specific data inside an event
  *
  * Since: 1.4
  */
@@ -1303,200 +1315,195 @@ clutter_event_get_device_tool (const ClutterEvent *event)
   if (is_event_allocated (event))
     {
       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
 
       return real_event->tool;
     }
 
   return NULL;
 }
 
 /**
  * clutter_event_new:
  * @type: The type of event.
  *
  * Creates a new #ClutterEvent of the specified type.
  *
  * Return value: (transfer full): A newly allocated #ClutterEvent.
  */
 ClutterEvent *
 clutter_event_new (ClutterEventType type)
 {
   ClutterEvent *new_event;
   ClutterEventPrivate *priv;
 
   priv = g_slice_new0 (ClutterEventPrivate);
 
   new_event = (ClutterEvent *) priv;
   new_event->type = new_event->any.type = type;
 
   if (G_UNLIKELY (all_events == NULL))
-    all_events = g_hash_table_new (NULL, NULL);
+    {
+      all_events =
+        g_hash_table_new_full (NULL, NULL,
+                               (GDestroyNotify) clutter_event_private_data_free,
+                               NULL);
+    }
 
-  g_hash_table_replace (all_events, priv, GUINT_TO_POINTER (1));
+  g_hash_table_add (all_events, priv);
 
   return new_event;
 }
 
 /**
  * clutter_event_copy:
  * @event: A #ClutterEvent.
  *
  * Copies @event.
  *
  * Return value: (transfer full): A newly allocated #ClutterEvent
  */
 ClutterEvent *
 clutter_event_copy (const ClutterEvent *event)
 {
   ClutterEvent *new_event;
   ClutterEventPrivate *new_real_event;
   ClutterInputDevice *device;
   gint n_axes = 0;
 
   g_return_val_if_fail (event != NULL, NULL);
 
   new_event = clutter_event_new (CLUTTER_NOTHING);
   new_real_event = (ClutterEventPrivate *) new_event;
 
   *new_event = *event;
 
   if (is_event_allocated (event))
     {
       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
 
       g_set_object (&new_real_event->device, real_event->device);
       g_set_object (&new_real_event->source_device, real_event->source_device);
       new_real_event->delta_x = real_event->delta_x;
       new_real_event->delta_y = real_event->delta_y;
       new_real_event->is_pointer_emulated = real_event->is_pointer_emulated;
       new_real_event->base_state = real_event->base_state;
       new_real_event->button_state = real_event->button_state;
       new_real_event->latched_state = real_event->latched_state;
       new_real_event->locked_state = real_event->locked_state;
       new_real_event->tool = real_event->tool;
+      new_real_event->platform_data =
+        _clutter_backend_copy_event_data (clutter_get_default_backend (),
+                                          real_event->platform_data);
     }
 
   device = clutter_event_get_device (event);
   if (device != NULL)
     n_axes = clutter_input_device_get_n_axes (device);
 
   switch (event->type)
     {
     case CLUTTER_BUTTON_PRESS:
     case CLUTTER_BUTTON_RELEASE:
       if (event->button.axes != NULL)
         new_event->button.axes = g_memdup (event->button.axes,
                                            sizeof (gdouble) * n_axes);
       break;
 
     case CLUTTER_SCROLL:
       if (event->scroll.axes != NULL)
         new_event->scroll.axes = g_memdup (event->scroll.axes,
                                            sizeof (gdouble) * n_axes);
       break;
 
     case CLUTTER_MOTION:
       if (event->motion.axes != NULL)
         new_event->motion.axes = g_memdup (event->motion.axes,
                                            sizeof (gdouble) * n_axes);
       break;
 
     case CLUTTER_TOUCH_BEGIN:
     case CLUTTER_TOUCH_UPDATE:
     case CLUTTER_TOUCH_END:
     case CLUTTER_TOUCH_CANCEL:
       if (event->touch.axes != NULL)
         new_event->touch.axes = g_memdup (event->touch.axes,
                                           sizeof (gdouble) * n_axes);
       break;
 
     default:
       break;
     }
 
-  if (is_event_allocated (event))
-    _clutter_backend_copy_event_data (clutter_get_default_backend (),
-                                      event,
-                                      new_event);
-
   return new_event;
 }
 
 /**
  * clutter_event_free:
  * @event: A #ClutterEvent.
  *
  * Frees all resources used by @event.
  */
 void
 clutter_event_free (ClutterEvent *event)
 {
   if (G_LIKELY (event != NULL))
     {
-      _clutter_backend_free_event_data (clutter_get_default_backend (), event);
-
-      if (is_event_allocated (event))
-        {
-          ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
-
-          g_clear_object (&real_event->device);
-          g_clear_object (&real_event->source_device);
-        }
-
       switch (event->type)
         {
         case CLUTTER_BUTTON_PRESS:
         case CLUTTER_BUTTON_RELEASE:
           g_free (event->button.axes);
           break;
 
         case CLUTTER_MOTION:
           g_free (event->motion.axes);
           break;
 
         case CLUTTER_SCROLL:
           g_free (event->scroll.axes);
           break;
 
         case CLUTTER_TOUCH_BEGIN:
         case CLUTTER_TOUCH_UPDATE:
         case CLUTTER_TOUCH_END:
         case CLUTTER_TOUCH_CANCEL:
           g_free (event->touch.axes);
           break;
 
         default:
           break;
         }
 
-      g_hash_table_remove (all_events, event);
+      if (G_LIKELY (all_events))
+        g_hash_table_remove (all_events, event);
+
       g_slice_free (ClutterEventPrivate, (ClutterEventPrivate *) event);
     }
 }
 
 /**
  * clutter_event_get:
  *
  * Pops an event off the event queue. Applications should not need to call 
  * this.
  *
  * Return value: A #ClutterEvent or NULL if queue empty
  *
  * Since: 0.4
  */
 ClutterEvent *
 clutter_event_get (void)
 {
   ClutterMainContext *context = _clutter_context_get_default ();
 
   if (context->events_queue == NULL)
     return NULL;
 
   if (g_queue_is_empty (context->events_queue))
     return NULL;
 
   return g_queue_pop_tail (context->events_queue);
 }
 
 /**
  * clutter_event_peek:
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index f2aeda696..11cb4781a 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -128,77 +128,76 @@ static gchar *                    evdev_seat_id;
 
 #ifdef CLUTTER_ENABLE_DEBUG
 static const char *device_type_str[] = {
   "pointer",            /* CLUTTER_POINTER_DEVICE */
   "keyboard",           /* CLUTTER_KEYBOARD_DEVICE */
   "extension",          /* CLUTTER_EXTENSION_DEVICE */
   "joystick",           /* CLUTTER_JOYSTICK_DEVICE */
   "tablet",             /* CLUTTER_TABLET_DEVICE */
   "touchpad",           /* CLUTTER_TOUCHPAD_DEVICE */
   "touchscreen",        /* CLUTTER_TOUCHSCREEN_DEVICE */
   "pen",                /* CLUTTER_PEN_DEVICE */
   "eraser",             /* CLUTTER_ERASER_DEVICE */
   "cursor",             /* CLUTTER_CURSOR_DEVICE */
   "pad",                /* CLUTTER_PAD_DEVICE */
 };
 #endif /* CLUTTER_ENABLE_DEBUG */
 
 /*
  * ClutterEventSource management
  *
  * The device manager is responsible for managing the GSource when devices
  * appear and disappear from the system.
  */
 
 static const char *option_xkb_layout = "us";
 static const char *option_xkb_variant = "";
 static const char *option_xkb_options = "";
 
 static void
 clutter_device_manager_evdev_copy_event_data (ClutterEventExtender *event_extender,
-                                              const ClutterEvent   *src,
-                                              ClutterEvent         *dest)
+                                              gpointer              data)
 {
-  ClutterEventEvdev *event_evdev;
+  ClutterEventEvdev *event_evdev = data;
 
-  event_evdev = _clutter_event_get_platform_data (src);
   if (event_evdev != NULL)
-    _clutter_event_set_platform_data (dest, _clutter_event_evdev_copy (event_evdev));
+    return _clutter_event_evdev_copy (event_evdev);
+
+  return NULL;
 }
 
 static void
 clutter_device_manager_evdev_free_event_data (ClutterEventExtender *event_extender,
-                                              ClutterEvent         *event)
+                                              gpointer              data)
 {
-  ClutterEventEvdev *event_evdev;
+  ClutterEventEvdev *event_evdev = data;
 
-  event_evdev = _clutter_event_get_platform_data (event);
   if (event_evdev != NULL)
     _clutter_event_evdev_free (event_evdev);
 }
 
 static void
 clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface)
 {
   iface->copy_event_data = clutter_device_manager_evdev_copy_event_data;
   iface->free_event_data = clutter_device_manager_evdev_free_event_data;
 }
 
 /*
  * ClutterEventSource for reading input devices
  */
 
 struct _ClutterEventSource
 {
   GSource source;
 
   ClutterDeviceManagerEvdev *manager_evdev;
   GPollFD event_poll_fd;
 };
 
 static void
 process_events (ClutterDeviceManagerEvdev *manager_evdev);
 
 static gboolean
 clutter_event_prepare (GSource *source,
                        gint    *timeout)
 {
diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c
index 0718cd975..35e3808e7 100644
--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
@@ -63,79 +63,74 @@ static const char *clutter_input_axis_atom_names[] = {
   "Abs Tilt Y",         /* CLUTTER_INPUT_AXIS_YTILT */
   "Abs Wheel",          /* CLUTTER_INPUT_AXIS_WHEEL */
   "Abs Distance",       /* CLUTTER_INPUT_AXIS_DISTANCE */
 };
 
 #define N_AXIS_ATOMS    G_N_ELEMENTS (clutter_input_axis_atom_names)
 
 enum {
   PAD_AXIS_FIRST  = 3, /* First axes are always x/y/pressure, ignored in pads */
   PAD_AXIS_STRIP1 = PAD_AXIS_FIRST,
   PAD_AXIS_STRIP2,
   PAD_AXIS_RING1,
   PAD_AXIS_RING2,
 };
 
 static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, };
 
 static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
 static void clutter_event_extender_iface_init   (ClutterEventExtenderInterface *iface);
 
 #define clutter_device_manager_xi2_get_type     _clutter_device_manager_xi2_get_type
 
 G_DEFINE_TYPE_WITH_CODE (ClutterDeviceManagerXI2,
                          clutter_device_manager_xi2,
                          CLUTTER_TYPE_DEVICE_MANAGER,
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR,
                                                 clutter_event_translator_iface_init)
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_EXTENDER,
                                                 clutter_event_extender_iface_init))
 
-static void
+static gpointer
 clutter_device_manager_x11_copy_event_data (ClutterEventExtender *event_extender,
-                                            const ClutterEvent   *src,
-                                            ClutterEvent         *dest)
+                                            gpointer              event_x11)
 {
-  gpointer event_x11;
-
-  event_x11 = _clutter_event_get_platform_data (src);
   if (event_x11 != NULL)
-    _clutter_event_set_platform_data (dest, _clutter_event_x11_copy (event_x11));
+    return _clutter_event_x11_copy (event_x11);
+
+  return NULL;
 }
 
 static void
 clutter_device_manager_x11_free_event_data (ClutterEventExtender *event_extender,
-                                            ClutterEvent         *event)
+                                            gpointer              event_x11)
 {
-  gpointer event_x11;
-
-  event_x11 = _clutter_event_get_platform_data (event);
   if (event_x11 != NULL)
     _clutter_event_x11_free (event_x11);
 }
 
 static void
 clutter_event_extender_iface_init (ClutterEventExtenderInterface *iface)
 {
   iface->copy_event_data = clutter_device_manager_x11_copy_event_data;
   iface->free_event_data = clutter_device_manager_x11_free_event_data;
 }
 
 static void
 translate_valuator_class (Display             *xdisplay,
                           ClutterInputDevice  *device,
                           XIValuatorClassInfo *class)
 {
   static gboolean atoms_initialized = FALSE;
   ClutterInputAxis i, axis = CLUTTER_INPUT_AXIS_IGNORE;
 
   if (G_UNLIKELY (!atoms_initialized))
     {
       XInternAtoms (xdisplay,
                     (char **) clutter_input_axis_atom_names, N_AXIS_ATOMS,
                     False,
                     clutter_input_axis_atoms);
 
       atoms_initialized = TRUE;
     }
 
   for (i = 0;
-- 
2.26.2