summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2018-01-27 00:25:56 +0800
committerJonas Ådahl <jadahl@gmail.com>2018-02-23 19:33:31 +0800
commitb6477a826d37cebc96ae41e86a555212ca4411ec (patch)
tree4431e6114739d9a8a624a0c31c003b77bdf78af2
parent95adc45b71d6f5d35841de0a54f58624f8ad6ac8 (diff)
downloadmutter-b6477a826d37cebc96ae41e86a555212ca4411ec.tar.gz
clutter/evdev: Don't treat device touch slots as seat slots
IF two touch devices have colliding touch point IDs they'd interfere on the seat. To avoid this, always allocate a seat wide slot for each device wide slot, but don't use device slots directly in the seat.
-rw-r--r--clutter/clutter/evdev/clutter-device-manager-evdev.c48
-rw-r--r--clutter/clutter/evdev/clutter-input-device-evdev.c65
-rw-r--r--clutter/clutter/evdev/clutter-input-device-evdev.h15
-rw-r--r--clutter/clutter/evdev/clutter-seat-evdev.c64
-rw-r--r--clutter/clutter/evdev/clutter-seat-evdev.h16
5 files changed, 155 insertions, 53 deletions
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index 6a9a1fc11..161c90524 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -1361,7 +1361,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
case LIBINPUT_EVENT_TOUCH_DOWN:
{
- gint32 slot;
+ int device_slot;
guint64 time_us;
double x, y;
gfloat stage_width, stage_height;
@@ -1382,21 +1382,23 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
- slot = libinput_event_touch_get_slot (touch_event);
+ device_slot = libinput_event_touch_get_slot (touch_event);
time_us = libinput_event_touch_get_time_usec (touch_event);
x = libinput_event_touch_get_x_transformed (touch_event,
stage_width);
y = libinput_event_touch_get_y_transformed (touch_event,
stage_height);
- touch_state = clutter_seat_evdev_add_touch (seat, slot);
+ touch_state =
+ clutter_input_device_evdev_acquire_touch_state (device_evdev,
+ device_slot);
touch_state->coords.x = x;
touch_state->coords.y = y;
clutter_seat_evdev_notify_touch_event (seat, device,
CLUTTER_TOUCH_BEGIN,
time_us,
- slot,
+ touch_state->seat_slot,
touch_state->coords.x,
touch_state->coords.y);
break;
@@ -1404,7 +1406,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
case LIBINPUT_EVENT_TOUCH_UP:
{
- gint32 slot;
+ int device_slot;
guint64 time_us;
ClutterSeatEvdev *seat;
ClutterTouchState *touch_state;
@@ -1415,24 +1417,27 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
seat = _clutter_input_device_evdev_get_seat (device_evdev);
- slot = libinput_event_touch_get_slot (touch_event);
+ device_slot = libinput_event_touch_get_slot (touch_event);
time_us = libinput_event_touch_get_time_usec (touch_event);
- touch_state = clutter_seat_evdev_get_touch (seat, slot);
+ touch_state =
+ clutter_input_device_evdev_lookup_touch_state (device_evdev,
+ device_slot);
if (!touch_state)
break;
clutter_seat_evdev_notify_touch_event (seat, device,
CLUTTER_TOUCH_END, time_us,
- slot,
+ touch_state->seat_slot,
touch_state->coords.x,
touch_state->coords.y);
- clutter_seat_evdev_remove_touch (seat, slot);
+ clutter_input_device_evdev_release_touch_state (device_evdev,
+ touch_state);
break;
}
case LIBINPUT_EVENT_TOUCH_MOTION:
{
- gint32 slot;
+ int device_slot;
guint64 time_us;
double x, y;
gfloat stage_width, stage_height;
@@ -1453,14 +1458,16 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
- slot = libinput_event_touch_get_slot (touch_event);
+ device_slot = libinput_event_touch_get_slot (touch_event);
time_us = libinput_event_touch_get_time_usec (touch_event);
x = libinput_event_touch_get_x_transformed (touch_event,
stage_width);
y = libinput_event_touch_get_y_transformed (touch_event,
stage_height);
- touch_state = clutter_seat_evdev_get_touch (seat, slot);
+ touch_state =
+ clutter_input_device_evdev_lookup_touch_state (device_evdev,
+ device_slot);
if (!touch_state)
break;
@@ -1470,33 +1477,22 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
clutter_seat_evdev_notify_touch_event (seat, device,
CLUTTER_TOUCH_UPDATE,
time_us,
- slot,
+ touch_state->seat_slot,
touch_state->coords.x,
touch_state->coords.y);
break;
}
case LIBINPUT_EVENT_TOUCH_CANCEL:
{
- ClutterTouchState *touch_state;
- GHashTableIter iter;
guint64 time_us;
struct libinput_event_touch *touch_event =
libinput_event_get_touch_event (event);
- ClutterSeatEvdev *seat;
device = libinput_device_get_user_data (libinput_device);
+ device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
time_us = libinput_event_touch_get_time_usec (touch_event);
- seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
- g_hash_table_iter_init (&iter, seat->touches);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_state))
- {
- clutter_seat_evdev_notify_touch_event (seat, device, CLUTTER_TOUCH_CANCEL,
- time_us, touch_state->id,
- touch_state->coords.x,
- touch_state->coords.y);
- g_hash_table_iter_remove (&iter);
- }
+ clutter_input_device_evdev_release_touch_slots (device_evdev, time_us);
break;
}
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.c b/clutter/clutter/evdev/clutter-input-device-evdev.c
index f275f1c42..322f5224e 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.c
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.c
@@ -81,6 +81,9 @@ clutter_input_device_evdev_finalize (GObject *object)
if (device_evdev->libinput_device)
libinput_device_unref (device_evdev->libinput_device);
+ clutter_input_device_evdev_release_touch_slots (device_evdev,
+ g_get_monotonic_time ());
+
_clutter_device_manager_evdev_release_device_id (manager_evdev, device);
clear_slow_keys (device_evdev);
@@ -1216,6 +1219,44 @@ clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *dev
}
static void
+release_device_touch_slot (gpointer value)
+{
+ ClutterTouchState *touch_state = value;
+
+ clutter_seat_evdev_release_touch_state (touch_state->seat, touch_state);
+}
+
+ClutterTouchState *
+clutter_input_device_evdev_acquire_touch_state (ClutterInputDeviceEvdev *device,
+ int device_slot)
+{
+ ClutterTouchState *touch_state;
+
+ touch_state = clutter_seat_evdev_acquire_touch_state (device->seat,
+ device_slot);
+ g_hash_table_insert (device->touches,
+ GINT_TO_POINTER (device_slot),
+ touch_state);
+
+ return touch_state;
+}
+
+ClutterTouchState *
+clutter_input_device_evdev_lookup_touch_state (ClutterInputDeviceEvdev *device,
+ int device_slot)
+{
+ return g_hash_table_lookup (device->touches, GINT_TO_POINTER (device_slot));
+}
+
+void
+clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device,
+ ClutterTouchState *touch_state)
+{
+ g_hash_table_remove (device->touches,
+ GINT_TO_POINTER (touch_state->device_slot));
+}
+
+static void
clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -1253,6 +1294,9 @@ clutter_input_device_evdev_init (ClutterInputDeviceEvdev *self)
cairo_matrix_init_identity (&self->device_matrix);
self->device_aspect_ratio = 0;
self->output_ratio = 0;
+
+ self->touches = g_hash_table_new_full (NULL, NULL,
+ NULL, release_device_touch_slot);
}
/*
@@ -1486,3 +1530,24 @@ clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device,
*x = CLAMP (x_d, MIN (min_x, max_x), MAX (min_x, max_x)) * stage_width;
*y = CLAMP (y_d, MIN (min_y, max_y), MAX (min_y, max_y)) * stage_height;
}
+
+void
+clutter_input_device_evdev_release_touch_slots (ClutterInputDeviceEvdev *device_evdev,
+ uint64_t time_us)
+{
+ GHashTableIter iter;
+ ClutterTouchState *touch_state;
+
+ g_hash_table_iter_init (&iter, device_evdev->touches);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch_state))
+ {
+ clutter_seat_evdev_notify_touch_event (touch_state->seat,
+ CLUTTER_INPUT_DEVICE (device_evdev),
+ CLUTTER_TOUCH_CANCEL,
+ time_us,
+ touch_state->seat_slot,
+ touch_state->coords.x,
+ touch_state->coords.y);
+ g_hash_table_iter_remove (&iter);
+ }
+}
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.h b/clutter/clutter/evdev/clutter-input-device-evdev.h
index 3c5b6e340..90463ee14 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.h
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.h
@@ -71,6 +71,8 @@ struct _ClutterInputDeviceEvdev
gdouble device_aspect_ratio; /* w:h */
gdouble output_ratio; /* w:h */
+ GHashTable *touches;
+
/* Keyboard a11y */
ClutterKeyboardA11yFlags a11y_flags;
GList *slow_keys_list;
@@ -137,6 +139,19 @@ void clutter_input_device_evdev_translate_coordinates (Clut
void clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *device,
ClutterKbdA11ySettings *settings);
+ClutterTouchState * clutter_input_device_evdev_acquire_touch_state (ClutterInputDeviceEvdev *device,
+ int device_slot);
+
+ClutterTouchState * clutter_input_device_evdev_lookup_touch_state (ClutterInputDeviceEvdev *device,
+ int device_slot);
+
+void clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device,
+ ClutterTouchState *touch_state);
+
+void clutter_input_device_evdev_release_touch_slots (ClutterInputDeviceEvdev *device_evdev,
+ uint64_t time_us);
+
+
G_END_DECLS
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */
diff --git a/clutter/clutter/evdev/clutter-seat-evdev.c b/clutter/clutter/evdev/clutter-seat-evdev.c
index 97648667b..e91f3673b 100644
--- a/clutter/clutter/evdev/clutter-seat-evdev.c
+++ b/clutter/clutter/evdev/clutter-seat-evdev.c
@@ -92,32 +92,57 @@ clutter_touch_state_free (ClutterTouchState *touch_state)
g_slice_free (ClutterTouchState, touch_state);
}
+static void
+ensure_seat_slot_allocated (ClutterSeatEvdev *seat,
+ int seat_slot)
+{
+ if (seat_slot >= seat->n_alloc_touch_states)
+ {
+ const int size_increase = 5;
+ int i;
+
+ seat->n_alloc_touch_states += size_increase;
+ seat->touch_states = g_realloc_n (seat->touch_states,
+ seat->n_alloc_touch_states,
+ sizeof (ClutterTouchState *));
+ for (i = 0; i < size_increase; i++)
+ seat->touch_states[seat->n_alloc_touch_states - (i + 1)] = NULL;
+ }
+}
+
ClutterTouchState *
-clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
- guint32 id)
+clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
+ int device_slot)
{
- ClutterTouchState *touch;
+ ClutterTouchState *touch_state;
+ int seat_slot;
- touch = g_slice_new0 (ClutterTouchState);
- touch->id = id;
+ for (seat_slot = 0; seat_slot < seat->n_alloc_touch_states; seat_slot++)
+ {
+ if (!seat->touch_states[seat_slot])
+ break;
+ }
- g_hash_table_insert (seat->touches, GUINT_TO_POINTER (id), touch);
+ ensure_seat_slot_allocated (seat, seat_slot);
- return touch;
-}
+ touch_state = g_slice_new0 (ClutterTouchState);
+ *touch_state = (ClutterTouchState) {
+ .seat = seat,
+ .seat_slot = seat_slot,
+ .device_slot = device_slot,
+ };
-void
-clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
- guint32 id)
-{
- g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
+ seat->touch_states[seat_slot] = touch_state;
+
+ return touch_state;
}
-ClutterTouchState *
-clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
- guint32 id)
+void
+clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat,
+ ClutterTouchState *touch_state)
{
- return g_hash_table_lookup (seat->touches, GUINT_TO_POINTER (id));
+ g_clear_pointer (&seat->touch_states[touch_state->seat_slot],
+ (GDestroyNotify) clutter_touch_state_free);
}
ClutterSeatEvdev *
@@ -154,9 +179,6 @@ clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
_clutter_device_manager_add_device (manager, device);
seat->core_keyboard = device;
- seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
- (GDestroyNotify) clutter_touch_state_free);
-
seat->repeat = TRUE;
seat->repeat_delay = 250; /* ms */
seat->repeat_interval = 33; /* ms */
@@ -824,7 +846,7 @@ clutter_seat_evdev_free (ClutterSeatEvdev *seat)
g_object_unref (device);
}
g_slist_free (seat->devices);
- g_hash_table_unref (seat->touches);
+ g_free (seat->touch_states);
xkb_state_unref (seat->xkb);
diff --git a/clutter/clutter/evdev/clutter-seat-evdev.h b/clutter/clutter/evdev/clutter-seat-evdev.h
index 3bced2da1..0fb89e33e 100644
--- a/clutter/clutter/evdev/clutter-seat-evdev.h
+++ b/clutter/clutter/evdev/clutter-seat-evdev.h
@@ -38,7 +38,10 @@ typedef struct _ClutterTouchState ClutterTouchState;
struct _ClutterTouchState
{
- guint32 id;
+ ClutterSeatEvdev *seat;
+
+ int device_slot;
+ int seat_slot;
ClutterPoint coords;
};
@@ -52,7 +55,8 @@ struct _ClutterSeatEvdev
ClutterInputDevice *core_pointer;
ClutterInputDevice *core_keyboard;
- GHashTable *touches;
+ ClutterTouchState **touch_states;
+ int n_alloc_touch_states;
struct xkb_state *xkb;
xkb_led_index_t caps_lock_led;
@@ -135,11 +139,11 @@ void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
-ClutterTouchState * clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
- guint32 id);
+ClutterTouchState * clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
+ int device_slot);
-void clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
- guint32 id);
+void clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat,
+ ClutterTouchState *touch_state);
ClutterTouchState * clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
guint32 id);