diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 1a92267d0..7e32ac55f 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -518,6 +518,36 @@ _clutter_backend_get_units_per_em (ClutterBackend *backend, return priv->units_per_em; } +void +_clutter_backend_copy_event_data (ClutterBackend *backend, + ClutterEvent *src, + ClutterEvent *dest) +{ + ClutterBackendClass *klass; + + g_return_if_fail (CLUTTER_IS_BACKEND (backend)); + g_return_if_fail (src != NULL); + g_return_if_fail (dest != NULL); + + klass = CLUTTER_BACKEND_GET_CLASS (backend); + if (klass->copy_event_data != NULL) + klass->copy_event_data (backend, src, dest); +} + +void +_clutter_backend_free_event_data (ClutterBackend *backend, + ClutterEvent *event) +{ + ClutterBackendClass *klass; + + g_return_if_fail (CLUTTER_IS_BACKEND (backend)); + g_return_if_fail (event != NULL); + + klass = CLUTTER_BACKEND_GET_CLASS (backend); + if (klass->free_event_data != NULL) + klass->free_event_data (backend, event); +} + /** * clutter_get_default_backend: * diff --git a/clutter/clutter-backend.h b/clutter/clutter-backend.h index 1012664d1..21d2ac39f 100644 --- a/clutter/clutter-backend.h +++ b/clutter/clutter-backend.h @@ -85,6 +85,12 @@ struct _ClutterBackendClass ClutterStage *stage); ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend); + void (* copy_event_data) (ClutterBackend *backend, + ClutterEvent *src, + ClutterEvent *dest); + void (* free_event_data) (ClutterBackend *backend, + ClutterEvent *event); + /* signals */ void (* resolution_changed) (ClutterBackend *backend); void (* font_changed) (ClutterBackend *backend); diff --git a/clutter/clutter-event.c b/clutter/clutter-event.c index d6755cb22..f71b21312 100644 --- a/clutter/clutter-event.c +++ b/clutter/clutter-event.c @@ -43,6 +43,52 @@ * be synthesized by Clutter itself or by the application code. */ +typedef struct _ClutterEventPrivate { + ClutterEvent base; + + gpointer platform_data; +} ClutterEventPrivate; + +static GHashTable *all_events = NULL; + +static gboolean +is_event_allocated (const ClutterEvent *event) +{ + if (all_events == NULL) + return FALSE; + + return g_hash_table_lookup (all_events, event) != NULL; +} + +/* + * _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; +} + +void +_clutter_event_set_platform_data (ClutterEvent *event, + gpointer data) +{ + if (!is_event_allocated (event)) + return; + + ((ClutterEventPrivate *) event)->platform_data = data; +} + /** * clutter_event_type: * @event: a #ClutterEvent @@ -606,10 +652,18 @@ ClutterEvent * clutter_event_new (ClutterEventType type) { ClutterEvent *new_event; + ClutterEventPrivate *priv; - new_event = g_slice_new0 (ClutterEvent); + priv = g_slice_new0 (ClutterEventPrivate); + + new_event = (ClutterEvent *) priv; new_event->type = new_event->any.type = type; + if (all_events == NULL) + all_events = g_hash_table_new (NULL, NULL); + + g_hash_table_replace (all_events, priv, GUINT_TO_POINTER (1)); + return new_event; } @@ -631,6 +685,11 @@ clutter_event_copy (ClutterEvent *event) new_event = clutter_event_new (CLUTTER_NOTHING); *new_event = *event; + if (is_event_allocated (event)) + _clutter_backend_copy_event_data (clutter_get_default_backend (), + event, + new_event); + return new_event; } @@ -644,7 +703,12 @@ void clutter_event_free (ClutterEvent *event) { if (G_LIKELY (event != NULL)) - g_slice_free (ClutterEvent, event); + { + _clutter_backend_free_event_data (clutter_get_default_backend (), event); + + g_hash_table_remove (all_events, event); + g_slice_free (ClutterEventPrivate, (ClutterEventPrivate *) event); + } } /** diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 40d717c74..666428b4d 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -245,7 +245,6 @@ int _clutter_stage_get_pending_swaps (ClutterStage *stage); gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage); - /* vfuncs implemented by backend */ GType _clutter_backend_impl_get_type (void); @@ -270,6 +269,12 @@ gboolean _clutter_backend_post_parse (ClutterBackend *backend, GError **error); void _clutter_backend_init_events (ClutterBackend *backend); +void _clutter_backend_copy_event_data (ClutterBackend *backend, + ClutterEvent *src, + ClutterEvent *dest); +void _clutter_backend_free_event_data (ClutterBackend *backend, + ClutterEvent *event); + ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend); gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend, @@ -341,6 +346,10 @@ void _clutter_effect_post_paint (ClutterEffect *effect); GType _clutter_layout_manager_get_child_meta_type (ClutterLayoutManager *manager); +void _clutter_event_set_platform_data (ClutterEvent *event, + gpointer data); +gpointer _clutter_event_get_platform_data (const ClutterEvent *event); + G_END_DECLS #endif /* _HAVE_CLUTTER_PRIVATE_H */