input-device: add enter/leave events generation for touch events

This patch brings 'enter-event' and 'leave-event' generation for touch
based devices. This leads to adding a new API to retrieve coordinates
of a touch point.

https://bugzilla.gnome.org/show_bug.cgi?id=679797
This commit is contained in:
Lionel Landwerlin 2012-07-11 16:21:28 +01:00
parent 6eef8ea042
commit 9e02ef459e
12 changed files with 410 additions and 78 deletions

View File

@ -267,6 +267,7 @@ deprecated_h = \
$(srcdir)/deprecated/clutter-fixed.h \ $(srcdir)/deprecated/clutter-fixed.h \
$(srcdir)/deprecated/clutter-frame-source.h \ $(srcdir)/deprecated/clutter-frame-source.h \
$(srcdir)/deprecated/clutter-group.h \ $(srcdir)/deprecated/clutter-group.h \
$(srcdir)/deprecated/clutter-input-device.h \
$(srcdir)/deprecated/clutter-keysyms.h \ $(srcdir)/deprecated/clutter-keysyms.h \
$(srcdir)/deprecated/clutter-main.h \ $(srcdir)/deprecated/clutter-main.h \
$(srcdir)/deprecated/clutter-media.h \ $(srcdir)/deprecated/clutter-media.h \
@ -300,6 +301,7 @@ deprecated_c = \
$(srcdir)/deprecated/clutter-fixed.c \ $(srcdir)/deprecated/clutter-fixed.c \
$(srcdir)/deprecated/clutter-frame-source.c \ $(srcdir)/deprecated/clutter-frame-source.c \
$(srcdir)/deprecated/clutter-group.c \ $(srcdir)/deprecated/clutter-group.c \
$(srcdir)/deprecated/clutter-input-device-deprecated.c \
$(srcdir)/deprecated/clutter-media.c \ $(srcdir)/deprecated/clutter-media.c \
$(srcdir)/deprecated/clutter-rectangle.c \ $(srcdir)/deprecated/clutter-rectangle.c \
$(srcdir)/deprecated/clutter-score.c \ $(srcdir)/deprecated/clutter-score.c \

View File

@ -23,6 +23,7 @@
#include "deprecated/clutter-fixed.h" #include "deprecated/clutter-fixed.h"
#include "deprecated/clutter-frame-source.h" #include "deprecated/clutter-frame-source.h"
#include "deprecated/clutter-group.h" #include "deprecated/clutter-group.h"
#include "deprecated/clutter-input-device.h"
#include "deprecated/clutter-keysyms.h" #include "deprecated/clutter-keysyms.h"
#include "deprecated/clutter-main.h" #include "deprecated/clutter-main.h"
#include "deprecated/clutter-media.h" #include "deprecated/clutter-media.h"

View File

@ -60,6 +60,15 @@ typedef struct _ClutterScrollInfo
guint last_value_valid : 1; guint last_value_valid : 1;
} ClutterScrollInfo; } ClutterScrollInfo;
typedef struct _ClutterTouchInfo
{
ClutterEventSequence *sequence;
ClutterActor *actor;
gint current_x;
gint current_y;
} ClutterTouchInfo;
struct _ClutterInputDevice struct _ClutterInputDevice
{ {
GObject parent_instance; GObject parent_instance;
@ -82,6 +91,7 @@ struct _ClutterInputDevice
/* the actor underneath the pointer */ /* the actor underneath the pointer */
ClutterActor *cursor_actor; ClutterActor *cursor_actor;
GHashTable *inv_touch_sequence_actors;
/* the actor that has a grab in place for the device */ /* the actor that has a grab in place for the device */
ClutterActor *pointer_grab_actor; ClutterActor *pointer_grab_actor;
@ -102,6 +112,9 @@ struct _ClutterInputDevice
gint current_button_number; gint current_button_number;
ClutterModifierType current_state; ClutterModifierType current_state;
/* the current touch points states */
GHashTable *touch_sequences_info;
/* the previous state, used for click count generation */ /* the previous state, used for click count generation */
gint previous_x; gint previous_x;
gint previous_y; gint previous_y;
@ -144,7 +157,14 @@ void _clutter_device_manager_select_stage_events (ClutterDeviceMa
ClutterBackend *_clutter_device_manager_get_backend (ClutterDeviceManager *device_manager); ClutterBackend *_clutter_device_manager_get_backend (ClutterDeviceManager *device_manager);
/* input device */ /* input device */
gboolean _clutter_input_device_has_sequence (ClutterInputDevice *device,
ClutterEventSequence *sequence);
void _clutter_input_device_add_sequence (ClutterInputDevice *device,
ClutterEventSequence *sequence);
void _clutter_input_device_remove_sequence (ClutterInputDevice *device,
ClutterEventSequence *sequence);
void _clutter_input_device_set_coords (ClutterInputDevice *device, void _clutter_input_device_set_coords (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gint x, gint x,
gint y); gint y);
void _clutter_input_device_set_state (ClutterInputDevice *device, void _clutter_input_device_set_state (ClutterInputDevice *device,
@ -155,9 +175,11 @@ void _clutter_input_device_set_stage (ClutterInputDev
ClutterStage *stage); ClutterStage *stage);
ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device); ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device);
void _clutter_input_device_set_actor (ClutterInputDevice *device, void _clutter_input_device_set_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterActor *actor, ClutterActor *actor,
gboolean emit_crossing); gboolean emit_crossing);
ClutterActor * _clutter_input_device_update (ClutterInputDevice *device, ClutterActor * _clutter_input_device_update (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gboolean emit_crossing); gboolean emit_crossing);
void _clutter_input_device_set_n_keys (ClutterInputDevice *device, void _clutter_input_device_set_n_keys (ClutterInputDevice *device,
guint n_keys); guint n_keys);

View File

@ -423,7 +423,7 @@ _clutter_device_manager_update_devices (ClutterDeviceManager *device_manager)
if (!clutter_stage_get_motion_events_enabled (device->stage)) if (!clutter_stage_get_motion_events_enabled (device->stage))
continue; continue;
_clutter_input_device_update (device, TRUE); _clutter_input_device_update (device, NULL, TRUE);
} }
} }

View File

@ -67,6 +67,9 @@ enum
PROP_LAST PROP_LAST
}; };
static void _clutter_input_device_free_touch_info (gpointer data);
static GParamSpec *obj_props[PROP_LAST] = { NULL, }; static GParamSpec *obj_props[PROP_LAST] = { NULL, };
G_DEFINE_TYPE (ClutterInputDevice, clutter_input_device, G_TYPE_OBJECT); G_DEFINE_TYPE (ClutterInputDevice, clutter_input_device, G_TYPE_OBJECT);
@ -100,6 +103,25 @@ clutter_input_device_dispose (GObject *gobject)
device->keys = NULL; device->keys = NULL;
} }
if (device->touch_sequences_info)
{
g_hash_table_unref (device->touch_sequences_info);
device->touch_sequences_info = NULL;
}
if (device->inv_touch_sequence_actors)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, device->inv_touch_sequence_actors);
while (g_hash_table_iter_next (&iter, &key, &value))
g_list_free (value);
g_hash_table_unref (device->inv_touch_sequence_actors);
device->inv_touch_sequence_actors = NULL;
}
G_OBJECT_CLASS (clutter_input_device_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_input_device_parent_class)->dispose (gobject);
} }
@ -365,11 +387,17 @@ clutter_input_device_init (ClutterInputDevice *self)
self->current_y = self->previous_y = -1; self->current_y = self->previous_y = -1;
self->current_button_number = self->previous_button_number = -1; self->current_button_number = self->previous_button_number = -1;
self->current_state = self->previous_state = 0; self->current_state = self->previous_state = 0;
self->touch_sequences_info =
g_hash_table_new_full (NULL, NULL,
NULL, _clutter_input_device_free_touch_info);
self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL);
} }
/*< private > /*< private >
* clutter_input_device_set_coords: * clutter_input_device_set_coords:
* @device: a #ClutterInputDevice * @device: a #ClutterInputDevice
* @sequence: a #ClutterEventSequence or NULL
* @x: X coordinate of the device * @x: X coordinate of the device
* @y: Y coordinate of the device * @y: Y coordinate of the device
* *
@ -377,16 +405,35 @@ clutter_input_device_init (ClutterInputDevice *self)
*/ */
void void
_clutter_input_device_set_coords (ClutterInputDevice *device, _clutter_input_device_set_coords (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gint x, gint x,
gint y) gint y)
{ {
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
if (sequence == NULL)
{
if (device->current_x != x) if (device->current_x != x)
device->current_x = x; device->current_x = x;
if (device->current_y != y) if (device->current_y != y)
device->current_y = y; device->current_y = y;
}
else
{
ClutterTouchInfo *info =
g_hash_table_lookup (device->touch_sequences_info, sequence);
if (info == NULL)
{
info = g_slice_new0 (ClutterTouchInfo);
info->sequence = sequence;
g_hash_table_insert (device->touch_sequences_info, sequence, info);
}
info->current_x = x;
info->current_y = y;
}
} }
/*< private > /*< private >
@ -422,13 +469,6 @@ _clutter_input_device_set_time (ClutterInputDevice *device,
device->current_time = time_; device->current_time = time_;
} }
static void
on_cursor_actor_destroy (ClutterActor *actor,
ClutterInputDevice *device)
{
device->cursor_actor = NULL;
}
/*< private > /*< private >
* clutter_input_device_set_stage: * clutter_input_device_set_stage:
* @device: a #ClutterInputDevice * @device: a #ClutterInputDevice
@ -466,6 +506,104 @@ _clutter_input_device_get_stage (ClutterInputDevice *device)
return device->stage; return device->stage;
} }
static void
_clutter_input_device_free_touch_info (gpointer data)
{
g_slice_free (ClutterTouchInfo, data);
}
static ClutterActor *
_clutter_input_device_get_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence)
{
ClutterTouchInfo *info;
if (sequence == NULL)
return device->cursor_actor;
info = g_hash_table_lookup (device->touch_sequences_info, sequence);
return info->actor;
}
static void on_cursor_actor_destroy (ClutterActor *actor,
ClutterInputDevice *device);
static void
_clutter_input_device_associate_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterActor *actor)
{
if (sequence == NULL)
device->cursor_actor = actor;
else
{
ClutterTouchInfo *info =
g_hash_table_lookup (device->touch_sequences_info, sequence);
GList *sequences =
g_hash_table_lookup (device->inv_touch_sequence_actors, actor);
if (info == NULL)
{
info = g_new0 (ClutterTouchInfo, 1);
info->sequence = sequence;
g_hash_table_insert (device->touch_sequences_info, sequence, info);
}
info->actor = actor;
g_hash_table_insert (device->inv_touch_sequence_actors,
actor, g_list_prepend (sequences, sequence));
}
g_signal_connect (actor,
"destroy", G_CALLBACK (on_cursor_actor_destroy),
device);
_clutter_actor_set_has_pointer (actor, TRUE);
}
static void
_clutter_input_device_unassociate_actor (ClutterInputDevice *device,
ClutterActor *actor,
gboolean destroyed)
{
if (device->cursor_actor == actor)
device->cursor_actor = NULL;
else
{
GList *l, *sequences =
g_hash_table_lookup (device->inv_touch_sequence_actors,
actor);
for (l = sequences; l != NULL; l = l->next)
{
ClutterTouchInfo *info =
g_hash_table_lookup (device->touch_sequences_info, l->data);
if (info)
info->actor = NULL;
}
g_list_free (sequences);
g_hash_table_remove (device->inv_touch_sequence_actors, actor);
}
if (destroyed == FALSE)
{
g_signal_handlers_disconnect_by_func (actor,
G_CALLBACK (on_cursor_actor_destroy),
device);
_clutter_actor_set_has_pointer (actor, FALSE);
}
}
static void
on_cursor_actor_destroy (ClutterActor *actor,
ClutterInputDevice *device)
{
_clutter_input_device_unassociate_actor (device, actor, TRUE);
}
/*< private > /*< private >
* clutter_input_device_set_actor: * clutter_input_device_set_actor:
* @device: a #ClutterInputDevice * @device: a #ClutterInputDevice
@ -487,18 +625,19 @@ _clutter_input_device_get_stage (ClutterInputDevice *device)
*/ */
void void
_clutter_input_device_set_actor (ClutterInputDevice *device, _clutter_input_device_set_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterActor *actor, ClutterActor *actor,
gboolean emit_crossing) gboolean emit_crossing)
{ {
ClutterActor *old_actor; ClutterActor *old_actor = _clutter_input_device_get_actor (device, sequence);
if (device->cursor_actor == actor) if (old_actor == actor)
return; return;
old_actor = device->cursor_actor;
if (old_actor != NULL) if (old_actor != NULL)
{ {
ClutterActor *tmp_old_actor;
if (emit_crossing) if (emit_crossing)
{ {
ClutterEvent *event; ClutterEvent *event;
@ -507,7 +646,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
event->crossing.time = device->current_time; event->crossing.time = device->current_time;
event->crossing.flags = 0; event->crossing.flags = 0;
event->crossing.stage = device->stage; event->crossing.stage = device->stage;
event->crossing.source = device->cursor_actor; event->crossing.source = old_actor;
event->crossing.x = device->current_x; event->crossing.x = device->current_x;
event->crossing.y = device->current_y; event->crossing.y = device->current_y;
event->crossing.related = actor; event->crossing.related = actor;
@ -524,19 +663,17 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
} }
/* processing the event might have destroyed the actor */ /* processing the event might have destroyed the actor */
if (device->cursor_actor != NULL) tmp_old_actor = _clutter_input_device_get_actor (device, sequence);
{ _clutter_input_device_unassociate_actor (device,
_clutter_actor_set_has_pointer (device->cursor_actor, FALSE); old_actor,
g_signal_handlers_disconnect_by_func (device->cursor_actor, tmp_old_actor == NULL);
G_CALLBACK (on_cursor_actor_destroy), old_actor = tmp_old_actor;
device);
device->cursor_actor = NULL;
}
} }
if (actor != NULL) if (actor != NULL)
{ {
_clutter_input_device_associate_actor (device, sequence, actor);
if (emit_crossing) if (emit_crossing)
{ {
ClutterEvent *event; ClutterEvent *event;
@ -557,15 +694,6 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
clutter_event_free (event); clutter_event_free (event);
} }
} }
device->cursor_actor = actor;
if (device->cursor_actor != NULL)
{
g_signal_connect (device->cursor_actor,
"destroy", G_CALLBACK (on_cursor_actor_destroy),
device);
_clutter_actor_set_has_pointer (device->cursor_actor, TRUE);
}
} }
/** /**
@ -656,27 +784,45 @@ clutter_input_device_get_enabled (ClutterInputDevice *device)
} }
/** /**
* clutter_input_device_get_device_coords: * clutter_input_device_get_coords:
* @device: a #ClutterInputDevice of type %CLUTTER_POINTER_DEVICE * @device: a #ClutterInputDevice
* @x: (out): return location for the X coordinate * @sequence: a #ClutterEventSequence
* @y: (out): return location for the Y coordinate * @point: (out): return location for the pointer or touch point
* *
* Retrieves the latest coordinates of the pointer of @device * Retrieves the latest coordinates of a pointer or touch point of
* @device
* *
* Since: 1.2 * Return value: %FALSE if the device's sequence hasn't been found,
* %TRUE otherwise.
*
* Since: 1.12
*/ */
void gboolean
clutter_input_device_get_device_coords (ClutterInputDevice *device, clutter_input_device_get_coords (ClutterInputDevice *device,
gint *x, ClutterEventSequence *sequence,
gint *y) ClutterPoint *point)
{ {
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
g_return_val_if_fail (point != NULL, FALSE);
if (x) if (sequence == NULL)
*x = device->current_x; {
point->x = device->current_x;
point->y = device->current_y;
}
else
{
ClutterTouchInfo *info =
g_hash_table_lookup (device->touch_sequences_info, sequence);
if (y) if (info == NULL)
*y = device->current_y; return FALSE;
point->x = info->current_x;
point->y = info->current_y;
}
return TRUE;
} }
/* /*
@ -695,12 +841,13 @@ clutter_input_device_get_device_coords (ClutterInputDevice *device,
*/ */
ClutterActor * ClutterActor *
_clutter_input_device_update (ClutterInputDevice *device, _clutter_input_device_update (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gboolean emit_crossing) gboolean emit_crossing)
{ {
ClutterStage *stage; ClutterStage *stage;
ClutterActor *new_cursor_actor; ClutterActor *new_cursor_actor;
ClutterActor *old_cursor_actor; ClutterActor *old_cursor_actor;
gint x, y; ClutterPoint point = { -1, -1 };
if (device->device_type == CLUTTER_KEYBOARD_DEVICE) if (device->device_type == CLUTTER_KEYBOARD_DEVICE)
return NULL; return NULL;
@ -713,11 +860,11 @@ _clutter_input_device_update (ClutterInputDevice *device,
return NULL; return NULL;
} }
clutter_input_device_get_device_coords (device, &x, &y); clutter_input_device_get_coords (device, sequence, &point);
old_cursor_actor = device->cursor_actor; old_cursor_actor = _clutter_input_device_get_actor (device, sequence);
new_cursor_actor = new_cursor_actor =
_clutter_stage_do_pick (stage, x, y, CLUTTER_PICK_REACTIVE); _clutter_stage_do_pick (stage, point.x, point.y, CLUTTER_PICK_REACTIVE);
/* if the pick could not find an actor then we do not update the /* if the pick could not find an actor then we do not update the
* input device, to avoid ghost enter/leave events; the pick should * input device, to avoid ghost enter/leave events; the pick should
@ -730,7 +877,7 @@ _clutter_input_device_update (ClutterInputDevice *device,
CLUTTER_NOTE (EVENT, CLUTTER_NOTE (EVENT,
"Actor under cursor (device %d, at %d, %d): %s", "Actor under cursor (device %d, at %d, %d): %s",
clutter_input_device_get_device_id (device), clutter_input_device_get_device_id (device),
x, y, point.x, point.y,
clutter_actor_get_name (new_cursor_actor) != NULL clutter_actor_get_name (new_cursor_actor) != NULL
? clutter_actor_get_name (new_cursor_actor) ? clutter_actor_get_name (new_cursor_actor)
: G_OBJECT_TYPE_NAME (new_cursor_actor)); : G_OBJECT_TYPE_NAME (new_cursor_actor));
@ -739,9 +886,11 @@ _clutter_input_device_update (ClutterInputDevice *device,
if (new_cursor_actor == old_cursor_actor) if (new_cursor_actor == old_cursor_actor)
return old_cursor_actor; return old_cursor_actor;
_clutter_input_device_set_actor (device, new_cursor_actor, emit_crossing); _clutter_input_device_set_actor (device, sequence,
new_cursor_actor,
emit_crossing);
return device->cursor_actor; return new_cursor_actor;
} }
/** /**
@ -909,6 +1058,7 @@ clutter_input_device_update_from_event (ClutterInputDevice *device,
gboolean update_stage) gboolean update_stage)
{ {
ClutterModifierType event_state; ClutterModifierType event_state;
ClutterEventSequence *sequence;
ClutterStage *event_stage; ClutterStage *event_stage;
gfloat event_x, event_y; gfloat event_x, event_y;
guint32 event_time; guint32 event_time;
@ -919,9 +1069,10 @@ clutter_input_device_update_from_event (ClutterInputDevice *device,
event_state = clutter_event_get_state (event); event_state = clutter_event_get_state (event);
event_time = clutter_event_get_time (event); event_time = clutter_event_get_time (event);
event_stage = clutter_event_get_stage (event); event_stage = clutter_event_get_stage (event);
sequence = clutter_event_get_event_sequence (event);
clutter_event_get_coords (event, &event_x, &event_y); clutter_event_get_coords (event, &event_x, &event_y);
_clutter_input_device_set_coords (device, event_x, event_y); _clutter_input_device_set_coords (device, sequence, event_x, event_y);
_clutter_input_device_set_state (device, event_state); _clutter_input_device_set_state (device, event_state);
_clutter_input_device_set_time (device, event_time); _clutter_input_device_set_time (device, event_time);
@ -1306,6 +1457,65 @@ _clutter_input_device_remove_slave (ClutterInputDevice *master,
master->slaves = g_list_remove (master->slaves, slave); master->slaves = g_list_remove (master->slaves, slave);
} }
/*< private >
* clutter_input_device_add_sequence:
* @device: a #ClutterInputDevice
* @sequence: a #ClutterEventSequence
*
* Start tracking informations related to a touch point (position,
* actor underneath the touch point).
*/
void
_clutter_input_device_add_sequence (ClutterInputDevice *device,
ClutterEventSequence *sequence)
{
ClutterTouchInfo *info;
if (sequence == NULL)
return;
info =
g_hash_table_lookup (device->touch_sequences_info, sequence);
if (info != NULL)
return;
info = g_new0 (ClutterTouchInfo, 1);
info->sequence = sequence;
g_hash_table_insert (device->touch_sequences_info, sequence, info);
}
/*< private >
* clutter_input_device_remove_sequence:
* @device: a #ClutterInputDevice
* @sequence: a #ClutterEventSequence
*
* Stop tracking informations related to a touch point.
*/
void
_clutter_input_device_remove_sequence (ClutterInputDevice *device,
ClutterEventSequence *sequence)
{
ClutterTouchInfo *info =
g_hash_table_lookup (device->touch_sequences_info, sequence);
if (info == NULL)
return;
if (info->actor != NULL)
{
GList *sequences =
g_hash_table_lookup (device->inv_touch_sequence_actors, info->actor);
sequences = g_list_remove (sequences, sequence);
g_hash_table_replace (device->inv_touch_sequence_actors,
info->actor, sequences);
}
g_hash_table_remove (device->touch_sequences_info, sequence);
}
/** /**
* clutter_input_device_get_slave_devices: * clutter_input_device_get_slave_devices:
* @device: a #ClutterInputDevice * @device: a #ClutterInputDevice

View File

@ -51,9 +51,11 @@ GType clutter_input_device_get_type (void) G_GNUC_CONST;
ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device); ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device);
gint clutter_input_device_get_device_id (ClutterInputDevice *device); gint clutter_input_device_get_device_id (ClutterInputDevice *device);
void clutter_input_device_get_device_coords (ClutterInputDevice *device,
gint *x, CLUTTER_AVAILABLE_IN_1_12
gint *y); gboolean clutter_input_device_get_coords (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterPoint *point);
ClutterActor * clutter_input_device_get_pointer_actor (ClutterInputDevice *device); ClutterActor * clutter_input_device_get_pointer_actor (ClutterInputDevice *device);
ClutterStage * clutter_input_device_get_pointer_stage (ClutterInputDevice *device); ClutterStage * clutter_input_device_get_pointer_stage (ClutterInputDevice *device);
const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device); const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device);

View File

@ -2420,9 +2420,7 @@ _clutter_process_event_details (ClutterActor *stage,
ClutterMainContext *context, ClutterMainContext *context,
ClutterEvent *event) ClutterEvent *event)
{ {
ClutterInputDevice *device = NULL; ClutterInputDevice *device = clutter_event_get_device (event);
device = clutter_event_get_device (event);
switch (event->type) switch (event->type)
{ {
@ -2463,7 +2461,7 @@ _clutter_process_event_details (ClutterActor *stage,
emit_pointer_event (event, device); emit_pointer_event (event, device);
actor = _clutter_input_device_update (device, FALSE); actor = _clutter_input_device_update (device, NULL, FALSE);
if (actor != stage) if (actor != stage)
{ {
ClutterEvent *crossing; ClutterEvent *crossing;
@ -2597,7 +2595,7 @@ _clutter_process_event_details (ClutterActor *stage,
* get the actor underneath * get the actor underneath
*/ */
if (device != NULL) if (device != NULL)
actor = _clutter_input_device_update (device, TRUE); actor = _clutter_input_device_update (device, NULL, TRUE);
else else
{ {
CLUTTER_NOTE (EVENT, "No device found: picking"); CLUTTER_NOTE (EVENT, "No device found: picking");
@ -2640,8 +2638,15 @@ _clutter_process_event_details (ClutterActor *stage,
case CLUTTER_TOUCH_END: case CLUTTER_TOUCH_END:
{ {
ClutterActor *actor; ClutterActor *actor;
ClutterEventSequence *sequence;
gfloat x, y; gfloat x, y;
sequence =
clutter_event_get_event_sequence (event);
if (event->type == CLUTTER_TOUCH_BEGIN)
_clutter_input_device_add_sequence (device, sequence);
clutter_event_get_coords (event, &x, &y); clutter_event_get_coords (event, &x, &y);
/* Only do a pick to find the source if source is not already set /* Only do a pick to find the source if source is not already set
@ -2649,9 +2654,13 @@ _clutter_process_event_details (ClutterActor *stage,
*/ */
if (event->any.source == NULL) if (event->any.source == NULL)
{ {
if (device != NULL)
actor = _clutter_input_device_update (device, sequence, TRUE);
else
actor = _clutter_stage_do_pick (CLUTTER_STAGE (stage), actor = _clutter_stage_do_pick (CLUTTER_STAGE (stage),
x, y, x, y,
CLUTTER_PICK_REACTIVE); CLUTTER_PICK_REACTIVE);
if (actor == NULL) if (actor == NULL)
break; break;
@ -2669,6 +2678,10 @@ _clutter_process_event_details (ClutterActor *stage,
actor); actor);
emit_touch_event (event, device); emit_touch_event (event, device);
if (event->type == CLUTTER_TOUCH_END)
_clutter_input_device_remove_sequence (device, sequence);
break; break;
} }

View File

@ -938,12 +938,13 @@ _clutter_stage_queue_event (ClutterStage *stage,
if (device != NULL) if (device != NULL)
{ {
ClutterModifierType event_state = clutter_event_get_state (event); ClutterModifierType event_state = clutter_event_get_state (event);
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
guint32 event_time = clutter_event_get_time (event); guint32 event_time = clutter_event_get_time (event);
gfloat event_x, event_y; gfloat event_x, event_y;
clutter_event_get_coords (event, &event_x, &event_y); clutter_event_get_coords (event, &event_x, &event_y);
_clutter_input_device_set_coords (device, event_x, event_y); _clutter_input_device_set_coords (device, sequence, event_x, event_y);
_clutter_input_device_set_state (device, event_state); _clutter_input_device_set_state (device, event_state);
_clutter_input_device_set_time (device, event_time); _clutter_input_device_set_time (device, event_time);
} }

View File

@ -825,6 +825,7 @@ clutter_input_axis_get_type
clutter_input_device_get_associated_device clutter_input_device_get_associated_device
clutter_input_device_get_axis clutter_input_device_get_axis
clutter_input_device_get_axis_value clutter_input_device_get_axis_value
clutter_input_device_get_coords
clutter_input_device_get_device_coords clutter_input_device_get_device_coords
clutter_input_device_get_device_id clutter_input_device_get_device_id
clutter_input_device_get_device_name clutter_input_device_get_device_name

View File

@ -0,0 +1,38 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <glib-object.h>
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "clutter-device-manager-private.h"
#include "deprecated/clutter-input-device.h"
/**
* clutter_input_device_get_device_coords:
* @device: a #ClutterInputDevice of type %CLUTTER_POINTER_DEVICE
* @x: (out): return location for the X coordinate
* @y: (out): return location for the Y coordinate
*
* Retrieves the latest coordinates of the pointer of @device
*
* Since: 1.2
*
* Deprecated: 1.12: Use clutter_input_device_get_coords() instead.
*/
void
clutter_input_device_get_device_coords (ClutterInputDevice *device,
gint *x,
gint *y)
{
ClutterPoint point;
clutter_input_device_get_coords (device, NULL, &point);
if (x)
*x = point.x;
if (y)
*y = point.y;
}

View File

@ -0,0 +1,41 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright © 2009, 2010, 2011 Intel Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_INPUT_DEVICE_DEPRECATED_H__
#define __CLUTTER_INPUT_DEVICE_DEPRECATED_H__
#include <clutter/clutter-input-device.h>
G_BEGIN_DECLS
CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_input_device_get_coords)
void clutter_input_device_get_device_coords (ClutterInputDevice *device,
gint *x,
gint *y);
G_END_DECLS
#endif /* __CLUTTER_INPUT_DEVICE_DEPRECATED_H__ */

View File

@ -1189,6 +1189,7 @@ clutter_input_device_get_axis
clutter_input_device_get_axis_value clutter_input_device_get_axis_value
<SUBSECTION> <SUBSECTION>
clutter_input_device_get_coords
clutter_input_device_get_device_coords clutter_input_device_get_device_coords
clutter_input_device_get_pointer_actor clutter_input_device_get_pointer_actor
clutter_input_device_get_pointer_stage clutter_input_device_get_pointer_stage