@@ -99,6 +99,15 @@ typedef struct _PickClipRecord
9999 graphene_point_t vertex [4 ];
100100} PickClipRecord ;
101101
102+ typedef struct _PointerDeviceEntry
103+ {
104+ ClutterStage * stage ;
105+ ClutterInputDevice * device ;
106+ ClutterEventSequence * sequence ;
107+ graphene_point_t coords ;
108+ ClutterActor * current_actor ;
109+ } PointerDeviceEntry ;
110+
102111struct _ClutterStagePrivate
103112{
104113 /* the stage implementation */
@@ -147,6 +156,9 @@ struct _ClutterStagePrivate
147156
148157 gboolean needs_update ;
149158
159+ GHashTable * pointer_devices ;
160+ GHashTable * touch_sequences ;
161+
150162 guint redraw_pending : 1 ;
151163 guint is_cursor_visible : 1 ;
152164 guint throttle_motion_events : 1 ;
@@ -195,6 +207,7 @@ static const ClutterColor default_stage_color = { 255, 255, 255, 255 };
195207
196208static void clutter_stage_maybe_finish_queue_redraws (ClutterStage * stage );
197209static void free_queue_redraw_entry (ClutterStageQueueRedrawEntry * entry );
210+ static void free_pointer_device_entry (PointerDeviceEntry * entry );
198211static void capture_view_into (ClutterStage * stage ,
199212 gboolean paint ,
200213 ClutterStageView * view ,
@@ -2010,6 +2023,9 @@ clutter_stage_finalize (GObject *object)
20102023 g_queue_foreach (priv -> event_queue , (GFunc ) clutter_event_free , NULL );
20112024 g_queue_free (priv -> event_queue );
20122025
2026+ g_hash_table_destroy (priv -> pointer_devices );
2027+ g_hash_table_destroy (priv -> touch_sequences );
2028+
20132029 g_free (priv -> title );
20142030
20152031 g_array_free (priv -> paint_volume_stack , TRUE);
@@ -2387,6 +2403,13 @@ clutter_stage_init (ClutterStage *self)
23872403 priv -> sync_delay = -1 ;
23882404 priv -> motion_events_enabled = TRUE;
23892405
2406+ priv -> pointer_devices =
2407+ g_hash_table_new_full (NULL , NULL ,
2408+ NULL , (GDestroyNotify ) free_pointer_device_entry );
2409+ priv -> touch_sequences =
2410+ g_hash_table_new_full (NULL , NULL ,
2411+ NULL , (GDestroyNotify ) free_pointer_device_entry );
2412+
23902413 clutter_actor_set_background_color (CLUTTER_ACTOR (self ),
23912414 & default_stage_color );
23922415
@@ -4796,3 +4819,69 @@ _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
47964819 * view_scale = scale ;
47974820 return TRUE;
47984821}
4822+
4823+ static void
4824+ on_device_actor_reactive_changed (ClutterActor * actor ,
4825+ GParamSpec * pspec ,
4826+ PointerDeviceEntry * entry )
4827+ {
4828+ }
4829+
4830+ static void
4831+ on_device_actor_destroyed (ClutterActor * actor ,
4832+ PointerDeviceEntry * entry )
4833+ {
4834+ /* Simply unset the current_actor pointer here, there's no need to
4835+ * unset has_pointer or to disconnect any signals because the actor
4836+ * is gone anyway.
4837+ * Also, as soon as the next repaint happens, a repick should be triggered
4838+ * and the PointerDeviceEntry will get updated again, so no need to
4839+ * trigger a repick here.
4840+ */
4841+ entry -> current_actor = NULL ;
4842+ }
4843+
4844+
4845+ static void
4846+ free_pointer_device_entry (PointerDeviceEntry * entry )
4847+ {
4848+ if (entry -> current_actor )
4849+ {
4850+ ClutterActor * actor = entry -> current_actor ;
4851+
4852+ g_signal_handlers_disconnect_by_func (actor ,
4853+ G_CALLBACK (on_device_actor_reactive_changed ),
4854+ entry );
4855+ g_signal_handlers_disconnect_by_func (actor ,
4856+ G_CALLBACK (on_device_actor_destroyed ),
4857+ entry );
4858+
4859+ _clutter_actor_set_has_pointer (actor , FALSE);
4860+ }
4861+
4862+ g_free (entry );
4863+ }
4864+
4865+ /**
4866+ * clutter_stage_get_device_coords: (skip):
4867+ */
4868+ void
4869+ clutter_stage_get_device_coords (ClutterStage * stage ,
4870+ ClutterInputDevice * device ,
4871+ ClutterEventSequence * sequence ,
4872+ graphene_point_t * coords )
4873+ {
4874+ ClutterStagePrivate * priv = stage -> priv ;
4875+ PointerDeviceEntry * entry = NULL ;
4876+
4877+ g_return_if_fail (CLUTTER_IS_STAGE (stage ));
4878+ g_return_if_fail (device != NULL );
4879+
4880+ if (sequence != NULL )
4881+ entry = g_hash_table_lookup (priv -> touch_sequences , sequence );
4882+ else
4883+ entry = g_hash_table_lookup (priv -> pointer_devices , device );
4884+
4885+ if (entry && coords )
4886+ * coords = entry -> coords ;
4887+ }
0 commit comments