events: Add platform-data to allocated Events

Events allocated by Clutter should have a pointer to platform-specific
data; this would allow backends to add separate structures for holding
ancillary data, whilst retaining the ClutterEvent structure for use on
the stack.

In theory, for Clutter 2.x we might just want to drop Event and use an
opaque structure, or a typed data structure inheriting from
GTypeInstance instead.
This commit is contained in:
Emmanuele Bassi 2010-06-14 18:01:17 +01:00
parent fd65138589
commit f44ccba42e
4 changed files with 112 additions and 3 deletions

View File

@ -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:
*

View File

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

View File

@ -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);
}
}
/**

View File

@ -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 */