[PATCH libinput 5/7] evdev: sync the initial x/y position for touchscreens
Peter Hutterer
peter.hutterer at who-t.net
Tue May 19 15:52:36 PDT 2015
Unlikely, but there's the odd chance of the first touch coming in with the
same X or Y coordinate the kernel already has internally. This would generate
a x/0 or 0/y event in libinput.
Sync the slot state on init, at least for Protocol B devices. For Protocol A
devices and mtdev, don't bother.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev.c | 12 ++++++++--
test/touch.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index d45264b..48c969d 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1781,8 +1781,16 @@ evdev_configure_mt_device(struct evdev_device *device)
for (slot = 0; slot < num_slots; ++slot) {
slots[slot].seat_slot = -1;
- slots[slot].point.x = 0;
- slots[slot].point.y = 0;
+
+ if (evdev_need_mtdev(device))
+ continue;
+
+ slots[slot].point.x = libevdev_get_slot_value(evdev,
+ slot,
+ ABS_MT_POSITION_X);
+ slots[slot].point.y = libevdev_get_slot_value(evdev,
+ slot,
+ ABS_MT_POSITION_Y);
}
device->mt.slots = slots;
device->mt.slots_len = num_slots;
diff --git a/test/touch.c b/test/touch.c
index d78deed..828c6ed 100644
--- a/test/touch.c
+++ b/test/touch.c
@@ -582,9 +582,79 @@ START_TEST(touch_protocol_a_2fg_touch)
}
END_TEST
+START_TEST(touch_initial_state)
+{
+ struct litest_device *dev;
+ struct libinput *libinput1, *libinput2;
+ struct libinput_event *ev1, *ev2;
+ struct libinput_event_touch *t1, *t2;
+ struct libinput_device *device1, *device2;
+ int axis = _i; /* looped test */
+
+ dev = litest_current_device();
+ device1 = dev->libinput_device;
+ libinput_device_config_tap_set_enabled(device1,
+ LIBINPUT_CONFIG_TAP_DISABLED);
+
+ libinput1 = dev->libinput;
+ litest_touch_down(dev, 0, 40, 60);
+ litest_touch_up(dev, 0);
+
+ /* device is now on some x/y value */
+ litest_drain_events(libinput1);
+
+ libinput2 = litest_create_context();
+ device2 = libinput_path_add_device(libinput2,
+ libevdev_uinput_get_devnode(
+ dev->uinput));
+ libinput_device_config_tap_set_enabled(device2,
+ LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_drain_events(libinput2);
+
+ if (axis == ABS_X)
+ litest_touch_down(dev, 0, 40, 70);
+ else
+ litest_touch_down(dev, 0, 70, 60);
+ litest_touch_up(dev, 0);
+
+ litest_wait_for_event(libinput1);
+ litest_wait_for_event(libinput2);
+
+ while (libinput_next_event_type(libinput1)) {
+ ev1 = libinput_get_event(libinput1);
+ ev2 = libinput_get_event(libinput2);
+
+ t1 = litest_is_touch_event(ev1, 0);
+ t2 = litest_is_touch_event(ev2, 0);
+
+ ck_assert_int_eq(libinput_event_get_type(ev1),
+ libinput_event_get_type(ev2));
+
+ if (libinput_event_get_type(ev1) == LIBINPUT_EVENT_TOUCH_UP ||
+ libinput_event_get_type(ev1) == LIBINPUT_EVENT_TOUCH_FRAME)
+ break;
+
+ ck_assert_int_eq(libinput_event_touch_get_x(t1),
+ libinput_event_touch_get_x(t2));
+ ck_assert_int_eq(libinput_event_touch_get_y(t1),
+ libinput_event_touch_get_y(t2));
+
+ libinput_event_destroy(ev1);
+ libinput_event_destroy(ev2);
+ }
+
+ libinput_event_destroy(ev1);
+ libinput_event_destroy(ev2);
+
+ libinput_unref(libinput2);
+}
+END_TEST
+
int
main(int argc, char **argv)
{
+ struct range axes = { ABS_X, ABS_Y + 1};
+
litest_add("touch:frame", touch_frame_events, LITEST_TOUCH, LITEST_ANY);
litest_add_no_device("touch:abs-transform", touch_abs_transform);
litest_add_no_device("touch:many-slots", touch_many_slots);
@@ -605,5 +675,7 @@ main(int argc, char **argv)
litest_add("touch:protocol a", touch_protocol_a_touch, LITEST_PROTOCOL_A, LITEST_ANY);
litest_add("touch:protocol a", touch_protocol_a_2fg_touch, LITEST_PROTOCOL_A, LITEST_ANY);
+ litest_add_ranged("touch:state", touch_initial_state, LITEST_TOUCH, LITEST_PROTOCOL_A, &axes);
+
return litest_run(argc, argv);
}
--
2.3.5
More information about the wayland-devel
mailing list