input-device: add APIs to grab sequences of touch events

https://bugzilla.gnome.org/show_bug.cgi?id=678279
This commit is contained in:
Lionel Landwerlin 2012-06-17 00:44:44 +01:00
parent 132e4b98d1
commit 927624d92c
8 changed files with 195 additions and 19 deletions

View File

@ -86,6 +86,8 @@ struct _ClutterInputDevice
/* the actor that has a grab in place for the device */
ClutterActor *pointer_grab_actor;
ClutterActor *keyboard_grab_actor;
GHashTable *sequence_grab_actors;
GHashTable *inv_sequence_grab_actors;
/* the current click count */
gint click_count;

View File

@ -115,16 +115,6 @@ typedef struct _ClutterStageStateEvent ClutterStageStateEvent;
typedef struct _ClutterCrossingEvent ClutterCrossingEvent;
typedef struct _ClutterTouchEvent ClutterTouchEvent;
/**
* ClutterEventSequence:
*
* The <structname>ClutterEventSequence</structname> structure is an opaque
* type used to denote the event sequence of a touch event.
*
* Since: 1.12
*/
typedef struct _ClutterEventSequence ClutterEventSequence;
/**
* ClutterAnyEvent:
* @type: event type

View File

@ -1540,3 +1540,139 @@ _clutter_input_device_reset_scroll_info (ClutterInputDevice *device)
info->last_value_valid = FALSE;
}
}
static void
on_grab_sequence_actor_destroy (ClutterActor *actor,
ClutterInputDevice *device)
{
ClutterEventSequence *sequence =
g_hash_table_lookup (device->inv_sequence_grab_actors, actor);
if (sequence != NULL)
{
g_hash_table_remove (device->sequence_grab_actors, sequence);
g_hash_table_remove (device->inv_sequence_grab_actors, actor);
}
}
/**
* clutter_input_device_sequence_grab:
* @device: a #ClutterInputDevice
* @sequence: a #ClutterEventSequence
* @actor: a #ClutterActor
*
* Acquires a grab on @actor for the given @device and the given touch
* @sequence.
*
* Any touch event coming from @device and from @sequence will be
* delivered to @actor, bypassing the usual event delivery mechanism,
* until the grab is released by calling
* clutter_input_device_sequence_ungrab().
*
* The grab is client-side: even if the windowing system used by the Clutter
* backend has the concept of "device grabs", Clutter will not use them.
*
* Since: 1.12
*/
void
clutter_input_device_sequence_grab (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterActor *actor)
{
ClutterActor *grab_actor;
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
if (device->sequence_grab_actors == NULL)
{
grab_actor = NULL;
device->sequence_grab_actors = g_hash_table_new (NULL, NULL);
device->inv_sequence_grab_actors = g_hash_table_new (NULL, NULL);
}
else
{
grab_actor = g_hash_table_lookup (device->sequence_grab_actors, sequence);
}
if (grab_actor != NULL)
{
g_signal_handlers_disconnect_by_func (grab_actor,
G_CALLBACK (on_grab_sequence_actor_destroy),
device);
g_hash_table_remove (device->sequence_grab_actors, sequence);
g_hash_table_remove (device->inv_sequence_grab_actors, grab_actor);
}
g_hash_table_insert (device->sequence_grab_actors, sequence, actor);
g_hash_table_insert (device->inv_sequence_grab_actors, actor, sequence);
g_signal_connect (grab_actor,
"destroy",
G_CALLBACK (on_grab_sequence_actor_destroy),
device);
}
/**
* clutter_input_device_sequence_ungrab:
* @device: a #ClutterInputDevice
* @sequence: a #ClutterEventSequence
*
* Releases the grab on the @device for the given @sequence, if one is
* in place.
*
* Since: 1.12
*/
void
clutter_input_device_sequence_ungrab (ClutterInputDevice *device,
ClutterEventSequence *sequence)
{
ClutterActor *grab_actor;
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
if (device->sequence_grab_actors == NULL)
return;
grab_actor = g_hash_table_lookup (device->sequence_grab_actors, sequence);
if (grab_actor == NULL)
return;
g_signal_handlers_disconnect_by_func (grab_actor,
G_CALLBACK (on_grab_sequence_actor_destroy),
device);
g_hash_table_remove (device->sequence_grab_actors, sequence);
g_hash_table_remove (device->inv_sequence_grab_actors, grab_actor);
if (g_hash_table_size (device->sequence_grab_actors) == 0)
{
g_hash_table_destroy (device->sequence_grab_actors);
device->sequence_grab_actors = NULL;
g_hash_table_destroy (device->inv_sequence_grab_actors);
device->inv_sequence_grab_actors = NULL;
}
}
/**
* clutter_input_device_sequence_get_grabbed_actor:
* @device: a #ClutterInputDevice
* @sequence: a #ClutterEventSequence
*
* Retrieves a pointer to the #ClutterActor currently grabbing the
* touch events coming from @device given the @sequence.
*
* Return value: (transfer none): a #ClutterActor, or %NULL
*
* Since: 1.12
*/
ClutterActor *
clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence)
{
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
if (device->sequence_grab_actors == NULL)
return NULL;
return g_hash_table_lookup (device->sequence_grab_actors, sequence);
}

View File

@ -45,7 +45,6 @@ G_BEGIN_DECLS
* Generic representation of an input device. The actual contents of this
* structure depend on the backend used.
*/
typedef struct _ClutterInputDevice ClutterInputDevice;
typedef struct _ClutterInputDeviceClass ClutterInputDeviceClass;
GType clutter_input_device_get_type (void) G_GNUC_CONST;
@ -97,6 +96,17 @@ void clutter_input_device_ungrab (ClutterInputDev
CLUTTER_AVAILABLE_IN_1_10
ClutterActor * clutter_input_device_get_grabbed_actor (ClutterInputDevice *device);
CLUTTER_AVAILABLE_IN_1_12
void clutter_input_device_sequence_grab (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterActor *actor);
CLUTTER_AVAILABLE_IN_1_12
void clutter_input_device_sequence_ungrab (ClutterInputDevice *device,
ClutterEventSequence *sequence);
CLUTTER_AVAILABLE_IN_1_12
ClutterActor * clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence);
gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device,
guint hardware_keycode,
guint *evdev_keycode);

View File

@ -2314,6 +2314,26 @@ emit_pointer_event (ClutterEvent *event,
}
}
static inline void
emit_touch_event (ClutterEvent *event,
ClutterInputDevice *device)
{
ClutterActor *grab_actor;
if ((device->sequence_grab_actors != NULL) &&
((grab_actor = g_hash_table_lookup (device->sequence_grab_actors,
event->touch.sequence)) != NULL))
{
/* sequence grab */
clutter_actor_event (grab_actor, event, FALSE);
}
else
{
/* no grab, time to capture and bubble */
emit_event (event, FALSE);
}
}
static inline void
emit_keyboard_event (ClutterEvent *event,
ClutterInputDevice *device)
@ -2644,7 +2664,7 @@ _clutter_process_event_details (ClutterActor *stage,
x, y,
actor);
emit_pointer_event (event, device);
emit_touch_event (event, device);
break;
}

View File

@ -90,8 +90,20 @@ typedef struct _ClutterAnimation ClutterAnimation;
typedef struct _ClutterAnimator ClutterAnimator;
typedef struct _ClutterState ClutterState;
typedef struct _ClutterInputDevice ClutterInputDevice;
typedef union _ClutterEvent ClutterEvent;
/**
* ClutterEventSequence:
*
* The <structname>ClutterEventSequence</structname> structure is an opaque
* type used to denote the event sequence of a touch event.
*
* Since: 1.12
*/
typedef struct _ClutterEventSequence ClutterEventSequence;
typedef struct _ClutterFog ClutterFog; /* deprecated */
typedef struct _ClutterBehaviour ClutterBehaviour; /* deprecated */
typedef struct _ClutterShader ClutterShader; /* deprecated */

View File

@ -358,7 +358,7 @@ clutter_backend_get_cogl_context
clutter_backend_get_double_click_distance
clutter_backend_get_double_click_time
clutter_backend_get_font_name
clutter_backend_get_font_options
clutter_backend_get_font_options
clutter_backend_get_resolution
clutter_backend_get_type
clutter_backend_set_double_click_distance
@ -432,7 +432,7 @@ clutter_binding_pool_get_for_class
clutter_binding_pool_get_type
clutter_binding_pool_install_action
clutter_binding_pool_install_closure
clutter_binding_pool_new
clutter_binding_pool_new
clutter_binding_pool_override_action
clutter_binding_pool_override_closure
clutter_binding_pool_remove_action
@ -509,7 +509,7 @@ clutter_cairo_set_source_color
clutter_cairo_texture_clear
clutter_cairo_texture_create
clutter_cairo_texture_create_region
clutter_cairo_texture_get_auto_resize
clutter_cairo_texture_get_auto_resize
clutter_cairo_texture_get_surface_size
clutter_cairo_texture_get_type
clutter_cairo_texture_invalidate
@ -827,6 +827,9 @@ clutter_input_device_get_slave_devices
clutter_input_device_get_type
clutter_input_device_grab
clutter_input_device_keycode_to_evdev
clutter_input_device_sequence_get_grabbed_actor
clutter_input_device_sequence_grab
clutter_input_device_sequence_ungrab
clutter_input_device_set_enabled
clutter_input_device_set_key
clutter_input_device_type_get_type
@ -1246,7 +1249,7 @@ clutter_stage_show_cursor
clutter_state_get_animator
clutter_state_get_duration
clutter_state_get_keys
clutter_stage_get_redraw_clip_bounds
clutter_stage_get_redraw_clip_bounds
clutter_state_get_state
clutter_state_get_states
clutter_state_get_timeline
@ -1254,7 +1257,7 @@ clutter_state_get_type
clutter_state_key_get_mode
clutter_state_key_get_object
clutter_state_key_get_post_delay
clutter_state_key_get_pre_delay
clutter_state_key_get_pre_delay
clutter_state_key_get_property_name
clutter_state_key_get_property_type
clutter_state_key_get_source_state_name
@ -1538,7 +1541,7 @@ clutter_win32_disable_event_retrieval
clutter_win32_get_stage_from_window
clutter_win32_get_stage_window
clutter_win32_set_stage_foreign
clutter_win32_handle_event
clutter_win32_handle_event
#endif
#ifdef CLUTTER_WINDOWING_X11
clutter_x11_add_filter
@ -1572,7 +1575,7 @@ clutter_x11_texture_pixmap_set_automatic
clutter_x11_texture_pixmap_set_pixmap
clutter_x11_texture_pixmap_set_window
clutter_x11_texture_pixmap_sync_window
clutter_x11_texture_pixmap_update_area
clutter_x11_texture_pixmap_update_area
clutter_x11_trap_x_errors
clutter_x11_untrap_x_errors
clutter_x11_xinput_event_types_get_type

View File

@ -1184,6 +1184,9 @@ clutter_input_device_get_pointer_stage
clutter_input_device_grab
clutter_input_device_ungrab
clutter_input_device_get_grabbed_actor
clutter_input_device_sequence_grab
clutter_input_device_sequence_ungrab
clutter_input_device_sequence_get_grabbed_actor
<SUBSECTION>
clutter_input_device_update_from_event