From d634917c2681ff193b7f636bb6f31e1a4c94c2ba Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 10:45:21 +1000 Subject: [PATCH 01/14] test: add test for default button tap map (on non-tapping devices) Signed-off-by: Peter Hutterer --- test/test-touchpad-tap.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c index abbcb7f0..cdc9b3a0 100644 --- a/test/test-touchpad-tap.c +++ b/test/test-touchpad-tap.c @@ -1862,6 +1862,20 @@ START_TEST(touchpad_tap_set_map_no_tapping) } END_TEST +START_TEST(touchpad_tap_get_map_no_tapping) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + enum libinput_config_tap_button_map map; + + map = libinput_device_config_tap_get_button_map(device); + ck_assert_int_eq(map, LIBINPUT_CONFIG_TAP_MAP_LRM); + + map = libinput_device_config_tap_get_default_button_map(device); + ck_assert_int_eq(map, LIBINPUT_CONFIG_TAP_MAP_LRM); +} +END_TEST + START_TEST(touchpad_tap_map_delayed) { struct litest_device *dev = litest_current_device(); @@ -2216,6 +2230,7 @@ litest_setup_tests_touchpad_tap(void) litest_add("tap:config", touchpad_tap_map_unsupported, LITEST_ANY, LITEST_TOUCHPAD); litest_add("tap:config", touchpad_tap_set_map, LITEST_TOUCHPAD, LITEST_ANY); litest_add("tap:config", touchpad_tap_set_map_no_tapping, LITEST_ANY, LITEST_TOUCHPAD); + litest_add("tap:config", touchpad_tap_get_map_no_tapping, LITEST_ANY, LITEST_TOUCHPAD); litest_add("tap:config", touchpad_tap_map_delayed, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); litest_add("tap-1fg:1fg", clickpad_1fg_tap_click, LITEST_CLICKPAD, LITEST_ANY); From a7720d362509e638e23972e2f66ad0a1aea889d0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 10:48:13 +1000 Subject: [PATCH 02/14] test: add test for natural scroll defaults on no-scroll devices Signed-off-by: Peter Hutterer --- test/test-pointer.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test-pointer.c b/test/test-pointer.c index 2689e4e4..6abb7acf 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -657,6 +657,18 @@ START_TEST(pointer_scroll_natural_defaults) } END_TEST +START_TEST(pointer_scroll_natural_defaults_noscroll) +{ + struct litest_device *dev = litest_current_device(); + + if (libinput_device_config_scroll_has_natural_scroll(dev->libinput_device)) + return; + + ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 0); + ck_assert_int_eq(libinput_device_config_scroll_get_default_natural_scroll_enabled(dev->libinput_device), 0); +} +END_TEST + START_TEST(pointer_scroll_natural_enable_config) { struct litest_device *dev = litest_current_device(); @@ -1852,6 +1864,7 @@ litest_setup_tests_pointer(void) litest_add("pointer:scroll", pointer_scroll_button_middle_emulation, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add("pointer:scroll", pointer_scroll_nowheel_defaults, LITEST_RELATIVE|LITEST_BUTTON, LITEST_WHEEL); litest_add("pointer:scroll", pointer_scroll_natural_defaults, LITEST_WHEEL, LITEST_TABLET); + litest_add("pointer:scroll", pointer_scroll_natural_defaults_noscroll, LITEST_ANY, LITEST_WHEEL); litest_add("pointer:scroll", pointer_scroll_natural_enable_config, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:scroll", pointer_scroll_natural_wheel, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:scroll", pointer_scroll_has_axis_invalid, LITEST_WHEEL, LITEST_TABLET); From e5f8ac757952296ce467cf4dc47cd5522afb9dc8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 10:51:25 +1000 Subject: [PATCH 03/14] test: add missing checks for tap enabled/disabled by default Signed-off-by: Peter Hutterer --- test/test-touchpad-tap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c index cdc9b3a0..fcc1662d 100644 --- a/test/test-touchpad-tap.c +++ b/test/test-touchpad-tap.c @@ -1748,6 +1748,8 @@ START_TEST(touchpad_tap_default_disabled) /* this test is only run on specific devices */ + ck_assert_int_eq(libinput_device_config_tap_get_enabled(dev->libinput_device), + LIBINPUT_CONFIG_TAP_DISABLED); ck_assert_int_eq(libinput_device_config_tap_get_default_enabled(dev->libinput_device), LIBINPUT_CONFIG_TAP_DISABLED); } @@ -1759,6 +1761,8 @@ START_TEST(touchpad_tap_default_enabled) /* this test is only run on specific devices */ + ck_assert_int_eq(libinput_device_config_tap_get_enabled(dev->libinput_device), + LIBINPUT_CONFIG_TAP_ENABLED); ck_assert_int_eq(libinput_device_config_tap_get_default_enabled(dev->libinput_device), LIBINPUT_CONFIG_TAP_ENABLED); } From f954b8f8530a9288b6ccb5151f6f44480a71158a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 11:00:43 +1000 Subject: [PATCH 04/14] test: add test for pad event mode groups Not much we can do here, our virtual devices don't have the sysfs files required, so they have 0 modes. Signed-off-by: Peter Hutterer --- test/test-pad.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/test/test-pad.c b/test/test-pad.c index 7048570e..5bce7e06 100644 --- a/test/test-pad.c +++ b/test/test-pad.c @@ -189,6 +189,68 @@ START_TEST(pad_button) } END_TEST +START_TEST(pad_button_mode_groups) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + unsigned int code; + unsigned int expected_number = 0; + struct libinput_event *ev; + struct libinput_event_tablet_pad *pev; + + litest_drain_events(li); + + for (code = BTN_0; code < KEY_MAX; code++) { + unsigned int mode, index; + struct libinput_tablet_pad_mode_group *group; + + if (!libevdev_has_event_code(dev->evdev, EV_KEY, code)) + continue; + + litest_button_click(dev, code, 1); + litest_button_click(dev, code, 0); + libinput_dispatch(li); + + switch (code) { + case BTN_STYLUS: + litest_assert_empty_queue(li); + continue; + default: + break; + } + + ev = libinput_get_event(li); + pev = litest_is_pad_button_event(ev, + expected_number, + LIBINPUT_BUTTON_STATE_PRESSED); + + /* litest virtual devices don't have modes */ + mode = libinput_event_tablet_pad_get_mode(pev); + ck_assert_int_eq(mode, 0); + group = libinput_event_tablet_pad_get_mode_group(pev); + index = libinput_tablet_pad_mode_group_get_index(group); + ck_assert_int_eq(index, 0); + + libinput_event_destroy(ev); + + ev = libinput_get_event(li); + pev = litest_is_pad_button_event(ev, + expected_number, + LIBINPUT_BUTTON_STATE_RELEASED); + mode = libinput_event_tablet_pad_get_mode(pev); + ck_assert_int_eq(mode, 0); + group = libinput_event_tablet_pad_get_mode_group(pev); + index = libinput_tablet_pad_mode_group_get_index(group); + ck_assert_int_eq(index, 0); + libinput_event_destroy(ev); + + expected_number++; + } + + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(pad_has_ring) { struct litest_device *dev = litest_current_device(); @@ -707,6 +769,7 @@ litest_setup_tests_pad(void) litest_add("pad:button", pad_num_buttons, LITEST_TABLET_PAD, LITEST_ANY); litest_add("pad:button", pad_button, LITEST_TABLET_PAD, LITEST_ANY); + litest_add("pad:button", pad_button_mode_groups, LITEST_TABLET_PAD, LITEST_ANY); litest_add("pad:ring", pad_has_ring, LITEST_RING, LITEST_ANY); litest_add("pad:ring", pad_ring, LITEST_RING, LITEST_ANY); From 6fded79d4bcaa28bc875419de0845e119216c74c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 11:03:43 +1000 Subject: [PATCH 05/14] test: test click method setting on non-touchpads Signed-off-by: Peter Hutterer --- test/test-touchpad-buttons.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test-touchpad-buttons.c b/test/test-touchpad-buttons.c index 2beb637f..48e7b4af 100644 --- a/test/test-touchpad-buttons.c +++ b/test/test-touchpad-buttons.c @@ -93,7 +93,7 @@ START_TEST(touchpad_click_defaults_none) uint32_t methods, method; enum libinput_config_status status; - /* call this test for non-clickpads */ + /* call this test for non-clickpads and non-touchpads */ methods = libinput_device_config_click_get_methods(device); ck_assert_int_eq(methods, 0); @@ -1833,6 +1833,7 @@ litest_setup_tests_touchpad_buttons(void) litest_add("touchpad:click", touchpad_click_defaults_clickfinger, LITEST_APPLE_CLICKPAD, LITEST_ANY); litest_add("touchpad:click", touchpad_click_defaults_btnarea, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD); litest_add("touchpad:click", touchpad_click_defaults_none, LITEST_TOUCHPAD, LITEST_CLICKPAD); + litest_add("touchpad:click", touchpad_click_defaults_none, LITEST_ANY, LITEST_TOUCHPAD); litest_add("touchpad:click", touchpad_btn_left, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD); litest_add("touchpad:click", clickpad_btn_left, LITEST_CLICKPAD, LITEST_ANY); From 7735f3aa4e2c3053e9664939602dd2899c7e3e79 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 11:06:48 +1000 Subject: [PATCH 06/14] test: add test for setting pointer accel profiles on no-accel devices Signed-off-by: Peter Hutterer --- test/test-pointer.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/test-pointer.c b/test/test-pointer.c index 6abb7acf..f28b5076 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -1348,6 +1348,35 @@ START_TEST(pointer_accel_profile_invalid) } END_TEST +START_TEST(pointer_accel_profile_noaccel) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + enum libinput_config_status status; + enum libinput_config_accel_profile profile; + + ck_assert(!libinput_device_config_accel_is_available(device)); + + profile = libinput_device_config_accel_get_default_profile(device); + ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); + + profile = libinput_device_config_accel_get_profile(device); + ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); + + status = libinput_device_config_accel_set_profile(device, + LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID); + + status = libinput_device_config_accel_set_profile(device, + LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE + 1); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID); + + status = libinput_device_config_accel_set_profile(device, + LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE |LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID); +} +END_TEST + START_TEST(pointer_accel_profile_flat_motion_relative) { struct litest_device *dev = litest_current_device(); @@ -1885,6 +1914,7 @@ litest_setup_tests_pointer(void) litest_add("pointer:accel", pointer_accel_profile_defaults, LITEST_RELATIVE, LITEST_TOUCHPAD); litest_add("pointer:accel", pointer_accel_profile_defaults_noprofile, LITEST_TOUCHPAD, LITEST_ANY); litest_add("pointer:accel", pointer_accel_profile_invalid, LITEST_RELATIVE, LITEST_ANY); + litest_add("pointer:accel", pointer_accel_profile_noaccel, LITEST_ANY, LITEST_TOUCHPAD|LITEST_RELATIVE|LITEST_TABLET); litest_add("pointer:accel", pointer_accel_profile_flat_motion_relative, LITEST_RELATIVE, LITEST_TOUCHPAD); litest_add("pointer:middlebutton", middlebutton, LITEST_BUTTON, LITEST_CLICKPAD); From 6d8a256bd4ffdee5a65ff81720b7ed91fd640637 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 11:23:18 +1000 Subject: [PATCH 07/14] Swap the return values for unsupported scroll button configs Usually we reply INVALID before we reply UNSUPPORTED but that's only for those values where the value is a programming error. But in this case it's a bit more complicated. INVALID is only for the cases where the button doesn't exist on the device, if we don't have button scrolling at all then we have UNSUPPORTED for all. Signed-off-by: Peter Hutterer --- src/libinput.c | 6 +++--- test/test-pointer.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/libinput.c b/src/libinput.c index 84e329de..514a6119 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -3954,13 +3954,13 @@ LIBINPUT_EXPORT enum libinput_config_status libinput_device_config_scroll_set_button(struct libinput_device *device, uint32_t button) { - if (button && !libinput_device_pointer_has_button(device, button)) - return LIBINPUT_CONFIG_STATUS_INVALID; - if ((libinput_device_config_scroll_get_methods(device) & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + if (button && !libinput_device_pointer_has_button(device, button)) + return LIBINPUT_CONFIG_STATUS_INVALID; + return device->config.scroll_method->set_button(device, button); } diff --git a/test/test-pointer.c b/test/test-pointer.c index f28b5076..57e7fd14 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -1014,6 +1014,28 @@ START_TEST(pointer_scroll_button) } END_TEST +START_TEST(pointer_scroll_button_noscroll) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + uint32_t methods, button; + enum libinput_config_status status; + + methods = libinput_device_config_scroll_get_method(device); + ck_assert_int_eq((methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN), 0); + button = libinput_device_config_scroll_get_button(device); + ck_assert_int_eq(button, 0); + button = libinput_device_config_scroll_get_default_button(device); + ck_assert_int_eq(button, 0); + + status = libinput_device_config_scroll_set_method(device, + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + status = libinput_device_config_scroll_set_button(device, BTN_LEFT); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); +} +END_TEST + START_TEST(pointer_scroll_button_no_event_before_timeout) { struct litest_device *device = litest_current_device(); @@ -1889,6 +1911,7 @@ litest_setup_tests_pointer(void) litest_add_for_device("pointer:button", pointer_button_has_no_button, LITEST_KEYBOARD); litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:scroll", pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); + litest_add("pointer:scroll", pointer_scroll_button_noscroll, LITEST_ANY, LITEST_RELATIVE|LITEST_BUTTON); litest_add("pointer:scroll", pointer_scroll_button_no_event_before_timeout, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add("pointer:scroll", pointer_scroll_button_middle_emulation, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add("pointer:scroll", pointer_scroll_nowheel_defaults, LITEST_RELATIVE|LITEST_BUTTON, LITEST_WHEEL); From 2908ba98cd6608724b00272f5c8c21e41af7e32c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 6 Feb 2017 11:47:56 +1000 Subject: [PATCH 08/14] test: add test for touch seat slots Signed-off-by: Peter Hutterer --- test/test-touch.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/test/test-touch.c b/test/test-touch.c index 0e091aa3..2bd1947e 100644 --- a/test/test-touch.c +++ b/test/test-touch.c @@ -114,6 +114,75 @@ START_TEST(touch_abs_transform) } END_TEST +static inline void +touch_assert_seat_slot(struct libinput *li, + enum libinput_event_type type, + unsigned int slot, + unsigned int seat_slot) +{ + struct libinput_event *ev; + struct libinput_event_touch *tev; + + libinput_dispatch(li); + ev = libinput_get_event(li); + tev = litest_is_touch_event(ev, type); + slot = libinput_event_touch_get_slot(tev); + ck_assert_int_eq(slot, slot); + slot = libinput_event_touch_get_seat_slot(tev); + ck_assert_int_eq(slot, seat_slot); + libinput_event_destroy(ev); + + ev = libinput_get_event(li); + litest_assert_event_type(ev, LIBINPUT_EVENT_TOUCH_FRAME); + libinput_event_destroy(ev); +} + +START_TEST(touch_seat_slot) +{ + struct litest_device *dev1 = litest_current_device(); + struct litest_device *dev2; + struct libinput *li = dev1->libinput; + + dev2 = litest_add_device(li, LITEST_WACOM_TOUCH); + + litest_drain_events(li); + + litest_touch_down(dev1, 0, 50, 50); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 0, 0); + + litest_touch_down(dev2, 0, 50, 50); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 0, 1); + + litest_touch_down(dev2, 1, 60, 50); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 1, 2); + + litest_touch_down(dev1, 1, 60, 50); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_DOWN, 1, 3); + + litest_touch_move_to(dev1, 0, 50, 50, 60, 70, 10, 0); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_MOTION, 0, 0); + litest_drain_events(li); + + litest_touch_move_to(dev2, 1, 50, 50, 60, 70, 10, 0); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_MOTION, 1, 2); + litest_drain_events(li); + + litest_touch_up(dev1, 0); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 0, 0); + + litest_touch_up(dev2, 0); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 0, 1); + + litest_touch_up(dev2, 1); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 1, 2); + + litest_touch_up(dev1, 1); + touch_assert_seat_slot(li, LIBINPUT_EVENT_TOUCH_UP, 1, 3); + + litest_delete_device(dev2); +} +END_TEST + START_TEST(touch_many_slots) { struct libinput *libinput; @@ -825,7 +894,8 @@ litest_setup_tests_touch(void) 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); + litest_add("touch:slots", touch_seat_slot, LITEST_TOUCH, LITEST_TOUCHPAD); + litest_add_no_device("touch:slots", touch_many_slots); litest_add("touch:double-touch-down-up", touch_double_touch_down_up, LITEST_TOUCH, LITEST_ANY); litest_add("touch:calibration", touch_calibration_scale, LITEST_TOUCH, LITEST_TOUCHPAD); litest_add("touch:calibration", touch_calibration_scale, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD); From d8b5957dc75ce0503472c76eb1c6ccbd8ce1d6c2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 9 Feb 2017 11:53:44 +1000 Subject: [PATCH 09/14] evdev: free the output name on evdev_destroy() Signed-off-by: Peter Hutterer --- src/evdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/evdev.c b/src/evdev.c index afee5906..b8d8b75a 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -3444,6 +3444,7 @@ evdev_device_destroy(struct evdev_device *device) if (device->base.group) libinput_device_group_unref(device->base.group); + free(device->output_name); filter_destroy(device->pointer.filter); libinput_seat_unref(device->base.seat); libevdev_free(device->evdev); From 07860e5db680cf570c4bdb2985d8e210841bb9e2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 9 Feb 2017 09:43:54 +1000 Subject: [PATCH 10/14] path: parse the WL_OUTPUT property for patch devices too Signed-off-by: Peter Hutterer --- src/path-seat.c | 5 +++- test/litest-device-calibrated-touchscreen.c | 3 ++- test/test-device.c | 26 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/path-seat.c b/src/path-seat.c index 9102d306..274f3a6b 100644 --- a/src/path-seat.c +++ b/src/path-seat.c @@ -116,7 +116,7 @@ path_device_enable(struct path_input *input, struct path_seat *seat; struct evdev_device *device = NULL; char *seat_name = NULL, *seat_logical_name = NULL; - const char *seat_prop; + const char *seat_prop, *output_name; const char *devnode; devnode = udev_device_get_devnode(udev_device); @@ -169,6 +169,9 @@ path_device_enable(struct path_input *input, } evdev_read_calibration_prop(device); + output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT"); + if (output_name) + device->output_name = strdup(output_name); out: free(seat_name); diff --git a/test/litest-device-calibrated-touchscreen.c b/test/litest-device-calibrated-touchscreen.c index db62d8b9..c750e86d 100644 --- a/test/litest-device-calibrated-touchscreen.c +++ b/test/litest-device-calibrated-touchscreen.c @@ -82,7 +82,8 @@ static const char udev_rule[] = "KERNEL!=\"event*\", GOTO=\"calibrated_touchscreen_end\"\n" "\n" "ATTRS{name}==\"litest Calibrated Touchscreen*\",\\\n" -" ENV{LIBINPUT_CALIBRATION_MATRIX}=\"1.2 3.4 5.6 7.8 9.10 11.12\"\n" +" ENV{LIBINPUT_CALIBRATION_MATRIX}=\"1.2 3.4 5.6 7.8 9.10 11.12\",\\\n" +" ENV{WL_OUTPUT}=\"myOutput\"\n" "\n" "LABEL=\"calibrated_touchscreen_end\""; diff --git a/test/test-device.c b/test/test-device.c index 8f06f7e4..d17dd37e 100644 --- a/test/test-device.c +++ b/test/test-device.c @@ -1549,6 +1549,28 @@ START_TEST(device_has_no_size) } END_TEST +START_TEST(device_get_output) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + const char *output_name; + + output_name = libinput_device_get_output_name(device); + ck_assert_str_eq(output_name, "myOutput"); +} +END_TEST + +START_TEST(device_no_output) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + const char *output_name; + + output_name = libinput_device_get_output_name(device); + ck_assert(output_name == NULL); +} +END_TEST + void litest_setup_tests_device(void) { @@ -1622,4 +1644,8 @@ litest_setup_tests_device(void) litest_add("device:size", device_has_size, LITEST_TABLET, LITEST_ANY); litest_add("device:size", device_has_no_size, LITEST_ANY, LITEST_TOUCHPAD|LITEST_TABLET|LITEST_TOUCH|LITEST_ABSOLUTE|LITEST_SINGLE_TOUCH); + + litest_add_for_device("device:output", device_get_output, LITEST_CALIBRATED_TOUCHSCREEN); + litest_add("device:output", device_no_output, LITEST_RELATIVE, LITEST_ANY); + litest_add("device:output", device_no_output, LITEST_KEYS, LITEST_ANY); } From 784241427ba66eabc23996db2e07c18f225cb6d6 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 9 Feb 2017 10:25:50 +1000 Subject: [PATCH 11/14] evdev: split calibration property parsing into a helper So we can test it externally. Signed-off-by: Peter Hutterer --- src/evdev.c | 26 +++++---------------- src/libinput-util.c | 38 +++++++++++++++++++++++++++++++ src/libinput-util.h | 1 + test/test-misc.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 21 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index b8d8b75a..d5b36ab8 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -3052,37 +3052,21 @@ evdev_device_calibrate(struct evdev_device *device, void evdev_read_calibration_prop(struct evdev_device *device) { - const char *calibration_values; + const char *prop; float calibration[6]; - int idx; - char **strv; - calibration_values = - udev_device_get_property_value(device->udev_device, - "LIBINPUT_CALIBRATION_MATRIX"); + prop = udev_device_get_property_value(device->udev_device, + "LIBINPUT_CALIBRATION_MATRIX"); - if (calibration_values == NULL) + if (prop == NULL) return; if (!device->abs.absinfo_x || !device->abs.absinfo_y) return; - strv = strv_from_string(calibration_values, " "); - if (!strv) + if (!parse_calibration_property(prop, calibration)) return; - for (idx = 0; idx < 6; idx++) { - double v; - if (strv[idx] == NULL || !safe_atod(strv[idx], &v)) { - strv_free(strv); - return; - } - - calibration[idx] = v; - } - - strv_free(strv); - evdev_device_set_default_calibration(device, calibration); log_info(evdev_libinput_context(device), "Applying calibration: %f %f %f %f %f %f\n", diff --git a/src/libinput-util.c b/src/libinput-util.c index aa69a37b..d75955cf 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -278,6 +278,44 @@ parse_dimension_property(const char *prop, size_t *w, size_t *h) return true; } +/** + * Parses a set of 6 space-separated floats. + * + * @param prop The string value of the property + * @param calibration Returns the six components + * @return true on success, false otherwise + */ +bool +parse_calibration_property(const char *prop, float calibration_out[6]) +{ + int idx; + char **strv; + float calibration[6]; + + if (!prop) + return false; + + strv = strv_from_string(prop, " "); + if (!strv) + return false; + + for (idx = 0; idx < 6; idx++) { + double v; + if (strv[idx] == NULL || !safe_atod(strv[idx], &v)) { + strv_free(strv); + return false; + } + + calibration[idx] = v; + } + + strv_free(strv); + + memcpy(calibration_out, calibration, sizeof(calibration)); + + return true; +} + bool parse_switch_reliability_property(const char *prop, enum switch_reliability *reliability) diff --git a/src/libinput-util.h b/src/libinput-util.h index 1d03ce13..459c6c4c 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -376,6 +376,7 @@ int parse_mouse_wheel_click_angle_property(const char *prop); int parse_mouse_wheel_click_count_property(const char *prop); double parse_trackpoint_accel_property(const char *prop); bool parse_dimension_property(const char *prop, size_t *width, size_t *height); +bool parse_calibration_property(const char *prop, float calibration[6]); enum switch_reliability { RELIABILITY_UNKNOWN, diff --git a/test/test-misc.c b/test/test-misc.c index 36cabdcf..3f4b2290 100644 --- a/test/test-misc.c +++ b/test/test-misc.c @@ -947,6 +947,60 @@ START_TEST(reliability_prop_parser) } END_TEST +struct parser_test_calibration { + char *prop; + bool success; + float values[6]; +}; + +START_TEST(calibration_prop_parser) +{ +#define DEFAULT_VALUES { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 } + const float untouched[6] = DEFAULT_VALUES; + struct parser_test_calibration tests[] = { + { "", false, DEFAULT_VALUES }, + { "banana", false, DEFAULT_VALUES }, + { "1 2 3 a 5 6", false, DEFAULT_VALUES }, + { "2", false, DEFAULT_VALUES }, + { "2 3 4 5 6", false, DEFAULT_VALUES }, + { "1 2 3 4 5 6", true, DEFAULT_VALUES }, + { "6.00012 3.244 4.238 5.2421 6.0134 8.860", true, + { 6.00012, 3.244, 4.238, 5.2421, 6.0134, 8.860 }}, + { "0xff 2 3 4 5 6", true, + { 255, 2, 3, 4, 5, 6 }}, + { NULL, false, DEFAULT_VALUES } + }; + bool success; + float calibration[6]; + int rc; + int i; + + for (i = 0; tests[i].prop != NULL; i++) { + memcpy(calibration, untouched, sizeof(calibration)); + + success = parse_calibration_property(tests[i].prop, + calibration); + ck_assert_int_eq(success, tests[i].success); + if (success) + rc = memcmp(tests[i].values, + calibration, + sizeof(calibration)); + else + rc = memcmp(untouched, + calibration, + sizeof(calibration)); + ck_assert_int_eq(rc, 0); + } + + memcpy(calibration, untouched, sizeof(calibration)); + + success = parse_calibration_property(NULL, calibration); + ck_assert(success == false); + rc = memcmp(untouched, calibration, sizeof(calibration)); + ck_assert_int_eq(rc, 0); +} +END_TEST + START_TEST(time_conversion) { ck_assert_int_eq(us(10), 10); @@ -1220,6 +1274,7 @@ litest_setup_tests_misc(void) litest_add_no_device("misc:parser", trackpoint_accel_parser); litest_add_no_device("misc:parser", dimension_prop_parser); litest_add_no_device("misc:parser", reliability_prop_parser); + litest_add_no_device("misc:parser", calibration_prop_parser); litest_add_no_device("misc:parser", safe_atoi_test); litest_add_no_device("misc:parser", safe_atod_test); litest_add_no_device("misc:parser", strsplit_test); From 47fbd8f98fdf7021ea2c340e662c150e01bb63d0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 9 Feb 2017 10:32:02 +1000 Subject: [PATCH 12/14] test: add basic test for getting the physical seat name Signed-off-by: Peter Hutterer --- test/test-device.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/test-device.c b/test/test-device.c index d17dd37e..48ba55db 100644 --- a/test/test-device.c +++ b/test/test-device.c @@ -1571,6 +1571,18 @@ START_TEST(device_no_output) } END_TEST +START_TEST(device_seat_phys_name) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + struct libinput_seat *seat = libinput_device_get_seat(device); + const char *seat_name; + + seat_name = libinput_seat_get_physical_name(seat); + ck_assert(streq(seat_name, "seat0")); +} +END_TEST + void litest_setup_tests_device(void) { @@ -1648,4 +1660,6 @@ litest_setup_tests_device(void) litest_add_for_device("device:output", device_get_output, LITEST_CALIBRATED_TOUCHSCREEN); litest_add("device:output", device_no_output, LITEST_RELATIVE, LITEST_ANY); litest_add("device:output", device_no_output, LITEST_KEYS, LITEST_ANY); + + litest_add("device:seat", device_seat_phys_name, LITEST_ANY, LITEST_ANY); } From 2dd9b77c9d4dc678719fd1775adc1d4c50d44ea3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 9 Feb 2017 11:06:01 +1000 Subject: [PATCH 13/14] test: add helper functions to filter an event Simplest implementation for what we need right now, it turns off an event on the evdev device and turns it back on again. This allows us to change bits in the 'normal' event stream, such as changing the tool type without triggering proximity events for the BTN_TOOL_PEN that all test devices send by default. This won't work for absolute devices because we need to re-enable with a struct input_absinfo. But we don't need that ability for now anyway. Signed-off-by: Peter Hutterer --- test/litest.c | 20 ++++++++++++++++++++ test/litest.h | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/test/litest.c b/test/litest.c index 78ef5dfc..00336a74 100644 --- a/test/litest.c +++ b/test/litest.c @@ -3248,6 +3248,26 @@ litest_pop_event_frame(struct litest_device *dev) litest_event(dev, EV_SYN, SYN_REPORT, 0); } +void +litest_filter_event(struct litest_device *dev, + unsigned int type, + unsigned int code) +{ + libevdev_disable_event_code(dev->evdev, type, code); +} + +void +litest_unfilter_event(struct litest_device *dev, + unsigned int type, + unsigned int code) +{ + /* would need an non-NULL argument for re-enabling, so simply abort + * until we need to be more sophisticated */ + litest_assert(type != EV_ABS); + + libevdev_enable_event_code(dev->evdev, type, code, NULL); +} + static void send_abs_xy(struct litest_device *d, double x, double y) { diff --git a/test/litest.h b/test/litest.h index d6b0ef0e..f5d91b91 100644 --- a/test/litest.h +++ b/test/litest.h @@ -707,6 +707,15 @@ litest_push_event_frame(struct litest_device *dev); void litest_pop_event_frame(struct litest_device *dev); +void +litest_filter_event(struct litest_device *dev, + unsigned int type, + unsigned int code); + +void +litest_unfilter_event(struct litest_device *dev, + unsigned int type, + unsigned int code); void litest_semi_mt_touch_down(struct litest_device *d, struct litest_semi_mt *semi_mt, From 02b18d112cc786df690c03af565a098c00428eda Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 9 Feb 2017 11:09:11 +1000 Subject: [PATCH 14/14] test: add tests for tablet tool types Signed-off-by: Peter Hutterer --- test/test-tablet.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/test/test-tablet.c b/test/test-tablet.c index 6bfffa05..268d8e94 100644 --- a/test/test-tablet.c +++ b/test/test-tablet.c @@ -2334,6 +2334,74 @@ START_TEST(tool_capabilities) } END_TEST +START_TEST(tool_type) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_tablet_tool *t; + struct libinput_tablet_tool *tool; + struct axis_replacement axes[] = { + { ABS_DISTANCE, 10 }, + { ABS_PRESSURE, 0 }, + { ABS_TILT_X, 0 }, + { ABS_TILT_Y, 0 }, + { -1, -1 } + }; + struct tool_type_match { + int code; + enum libinput_tablet_tool_type type; + } types[] = { + { BTN_TOOL_PEN, LIBINPUT_TABLET_TOOL_TYPE_PEN }, + { BTN_TOOL_RUBBER, LIBINPUT_TABLET_TOOL_TYPE_ERASER }, + { BTN_TOOL_BRUSH, LIBINPUT_TABLET_TOOL_TYPE_BRUSH }, + { BTN_TOOL_BRUSH, LIBINPUT_TABLET_TOOL_TYPE_BRUSH }, + { BTN_TOOL_PENCIL, LIBINPUT_TABLET_TOOL_TYPE_PENCIL }, + { BTN_TOOL_AIRBRUSH, LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH }, + { BTN_TOOL_MOUSE, LIBINPUT_TABLET_TOOL_TYPE_MOUSE }, + { BTN_TOOL_LENS, LIBINPUT_TABLET_TOOL_TYPE_LENS }, + { -1, -1 } + }; + struct tool_type_match *tt; + + litest_drain_events(li); + + for (tt = types; tt->code != -1; tt++) { + if (!libevdev_has_event_code(dev->evdev, + EV_KEY, + tt->code)) + continue; + + litest_push_event_frame(dev); + litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN); + litest_tablet_proximity_in(dev, 50, 50, axes); + litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN); + litest_event(dev, EV_KEY, tt->code, 1); + litest_pop_event_frame(dev); + libinput_dispatch(li); + + event = libinput_get_event(li); + t = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + tool = libinput_event_tablet_tool_get_tool(t); + + ck_assert_int_eq(libinput_tablet_tool_get_type(tool), + tt->type); + + libinput_event_destroy(event); + litest_assert_empty_queue(li); + + litest_push_event_frame(dev); + litest_filter_event(dev, EV_KEY, BTN_TOOL_PEN); + litest_tablet_proximity_out(dev); + litest_unfilter_event(dev, EV_KEY, BTN_TOOL_PEN); + litest_event(dev, EV_KEY, tt->code, 0); + litest_pop_event_frame(dev); + litest_drain_events(li); + } +} +END_TEST + START_TEST(tool_in_prox_before_start) { struct libinput *li; @@ -4192,6 +4260,7 @@ litest_setup_tests_tablet(void) litest_add("tablet:tool", tool_user_data, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); litest_add("tablet:tool", tool_capability, LITEST_TABLET, LITEST_ANY); litest_add_no_device("tablet:tool", tool_capabilities); + litest_add("tablet:tool", tool_type, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tool", tool_in_prox_before_start, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tool_serial", tool_unique, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); litest_add("tablet:tool_serial", tool_serial, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);