libinput/test/test-touchpad-buttons.c
satrmb 6f9a54c573 test: convert most ranged tests to parametrized ones
The two remaining ranged tests (abs_device_no_range, abs_mt_device_no_range)
are better served staying with ranges because parametrized tests need to
explicitly list all members of the range, which for these tests is not only
pretty big, but also contains abs axes reserved for future use. Those axes
have no names yet, making a future-proof conversion pretty much impossible.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1142>
2025-02-20 09:34:14 +01:00

2323 lines
65 KiB
C

/*
* Copyright © 2014 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <config.h>
#include <errno.h>
#include <fcntl.h>
#include <libinput.h>
#include <unistd.h>
#include "libinput-util.h"
#include "litest.h"
START_TEST(touchpad_button)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_LEFT))
return LITEST_NOT_APPLICABLE;
litest_drain_events(li);
litest_button_click(dev, BTN_LEFT, true);
litest_dispatch(li);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_button_click(dev, BTN_LEFT, false);
litest_dispatch(li);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_click_defaults_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
uint32_t methods, method;
enum libinput_config_status status;
/* call this test for apple touchpads */
methods = libinput_device_config_click_get_methods(device);
litest_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
litest_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
method = libinput_device_config_click_get_method(device);
litest_assert_enum_eq(method, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
method = libinput_device_config_click_get_default_method(device);
litest_assert_enum_eq(method, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_NONE);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
}
END_TEST
START_TEST(touchpad_click_default_clickfinger_map)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
enum libinput_config_clickfinger_button_map map;
map = libinput_device_config_click_get_clickfinger_button_map(device);
litest_assert_enum_eq(map, LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM);
map = libinput_device_config_click_get_default_clickfinger_button_map(device);
litest_assert_enum_eq(map, LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM);
}
END_TEST
START_TEST(touchpad_click_set_clickfinger_map)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
enum libinput_config_clickfinger_button_map map;
enum libinput_config_status status;
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
status = libinput_device_config_click_set_clickfinger_button_map(device, map);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
map = libinput_device_config_click_get_clickfinger_button_map(dev->libinput_device);
litest_assert_enum_eq(map, LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM);
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR;
status = libinput_device_config_click_set_clickfinger_button_map(device, map);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
map = libinput_device_config_click_get_clickfinger_button_map(dev->libinput_device);
litest_assert_enum_eq(map, LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR);
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM - 1;
status = libinput_device_config_click_set_clickfinger_button_map(device, map);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR + 1;
status = libinput_device_config_click_set_clickfinger_button_map(device, map);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
}
END_TEST
START_TEST(touchpad_click_defaults_btnarea)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
uint32_t methods, method;
enum libinput_config_status status;
/* call this test for non-apple clickpads */
methods = libinput_device_config_click_get_methods(device);
litest_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
litest_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
method = libinput_device_config_click_get_method(device);
litest_assert_enum_eq(method, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
method = libinput_device_config_click_get_default_method(device);
litest_assert_enum_eq(method, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_NONE);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
}
END_TEST
START_TEST(touchpad_click_defaults_none)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
uint32_t methods, method;
enum libinput_config_status status;
if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_APPLE &&
libevdev_get_id_product(dev->evdev) == PRODUCT_ID_APPLE_APPLETOUCH)
return LITEST_NOT_APPLICABLE;
/* call this test for non-clickpads and non-touchpads */
methods = libinput_device_config_click_get_methods(device);
litest_assert_int_eq(methods, 0U);
method = libinput_device_config_click_get_method(device);
litest_assert_enum_eq(method, LIBINPUT_CONFIG_CLICK_METHOD_NONE);
method = libinput_device_config_click_get_default_method(device);
litest_assert_enum_eq(method, LIBINPUT_CONFIG_CLICK_METHOD_NONE);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
}
END_TEST
START_TEST(touchpad_1fg_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_1fg_clickfinger_no_touch)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (dev->which == LITEST_SYNAPTICS_PHANTOMCLICKS) {
/* The XPS 15 9500 touchpad has the ModelTouchpadPhantomClicks
* quirk enabled and doesn't generate events without touches. */
return LITEST_NOT_APPLICABLE;
}
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_1fg_clickfinger_no_touch_phantomclicks)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_2fg_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
unsigned int button = 0;
enum libinput_config_clickfinger_button_map map = litest_test_param_get_i32(test_env->params, "map");
litest_enable_clickfinger(dev);
litest_set_clickfinger_map(dev, map);
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
button = BTN_RIGHT;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
button = BTN_MIDDLE;
break;
default:
litest_abort_msg("Invalid map range %d", map);
}
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 70, 70);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_dispatch(li);
litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_3fg_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
unsigned int button = 0;
enum libinput_config_clickfinger_button_map map = litest_test_param_get_i32(test_env->params, "map");
if (litest_slot_count(dev) < 3)
return LITEST_NOT_APPLICABLE;
litest_enable_clickfinger(dev);
litest_set_clickfinger_map(dev, map);
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
button = BTN_MIDDLE;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
button = BTN_RIGHT;
break;
default:
litest_abort_msg("Invalid map range %d", map);
}
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 60, 70);
litest_touch_down(dev, 2, 70, 70);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
litest_dispatch(li);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_3fg_clickfinger_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
unsigned int button = 0;
enum libinput_config_clickfinger_button_map map = litest_test_param_get_i32(test_env->params, "map");
if (litest_slot_count(dev) >= 3 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return LITEST_NOT_APPLICABLE;
litest_enable_clickfinger(dev);
litest_set_clickfinger_map(dev, map);
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
button = BTN_MIDDLE;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
button = BTN_RIGHT;
break;
default:
litest_abort_msg("Invalid map range %d", map);
}
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 60, 70);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_dispatch(li);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_4fg_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (litest_slot_count(dev) < 4)
return LITEST_NOT_APPLICABLE;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 60, 70);
litest_touch_down(dev, 2, 70, 70);
litest_touch_down(dev, 3, 80, 70);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
litest_touch_up(dev, 3);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_4fg_clickfinger_btntool_2slots)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (litest_slot_count(dev) >= 3 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_QUADTAP))
return LITEST_NOT_APPLICABLE;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 60, 70);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_4fg_clickfinger_btntool_3slots)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (litest_slot_count(dev) != 3 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return LITEST_NOT_APPLICABLE;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 60, 70);
litest_touch_down(dev, 2, 70, 70);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_2fg_clickfinger_distance)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
double w, h;
bool small_touchpad = false;
unsigned int expected_button = 0;
enum libinput_config_clickfinger_button_map map = litest_test_param_get_i32(test_env->params, "map");
if (libinput_device_get_size(dev->libinput_device, &w, &h) == 0 &&
h < 50.0)
small_touchpad = true;
litest_enable_clickfinger(dev);
litest_set_clickfinger_map(dev, map);
litest_drain_events(li);
litest_touch_down(dev, 0, 90, 50);
litest_touch_down(dev, 1, 10, 50);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 50, 5);
litest_touch_down(dev, 1, 50, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
/* if the touchpad is small enough, we expect all fingers to count
* for clickfinger */
if (small_touchpad)
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
expected_button = BTN_RIGHT;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
expected_button = BTN_MIDDLE;
break;
}
else
expected_button = BTN_LEFT;
litest_assert_button_event(li,
expected_button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
expected_button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_3fg_clickfinger_distance)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
unsigned int button = 0;
enum libinput_config_clickfinger_button_map map = litest_test_param_get_i32(test_env->params, "map");
if (litest_slot_count(dev) < 3)
return LITEST_NOT_APPLICABLE;
litest_enable_clickfinger(dev);
litest_set_clickfinger_map(dev, map);
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
button = BTN_MIDDLE;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
button = BTN_RIGHT;
break;
default:
litest_abort_msg("Invalid map range %d", map);
}
litest_drain_events(li);
litest_touch_down(dev, 0, 90, 20);
litest_touch_down(dev, 1, 10, 15);
litest_touch_down(dev, 2, 10, 15);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_3fg_clickfinger_distance_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
unsigned int button = 0;
enum libinput_config_clickfinger_button_map map = litest_test_param_get_i32(test_env->params, "map");
if (litest_slot_count(dev) > 2)
return LITEST_NOT_APPLICABLE;
litest_enable_clickfinger(dev);
litest_set_clickfinger_map(dev, map);
switch (map) {
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
button = BTN_MIDDLE;
break;
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
button = BTN_RIGHT;
break;
default:
litest_abort_msg("Invalid map range %d", map);
}
litest_drain_events(li);
litest_touch_down(dev, 0, 90, 15);
litest_touch_down(dev, 1, 10, 15);
litest_dispatch(li);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_2fg_clickfinger_bottom)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
/* this test is run for the T440s touchpad only, makes getting the
* mm correct easier */
libinput_device_config_click_set_method(dev->libinput_device,
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
litest_drain_events(li);
/* one above, one below the magic line, vert spread ca 27mm */
litest_touch_down(dev, 0, 40, 60);
litest_touch_down(dev, 1, 60, 100);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
/* both below the magic line */
litest_touch_down(dev, 0, 40, 100);
litest_touch_down(dev, 1, 60, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
/* one above, one below the magic line, vert spread 17mm */
litest_touch_down(dev, 0, 50, 75);
litest_touch_down(dev, 1, 55, 100);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_to_area_method)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_enable_buttonareas(dev);
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_enable_clickfinger(dev);
litest_drain_events(li);
/* use bottom right corner to catch accidental softbutton right */
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_to_area_method_while_down)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_enable_buttonareas(dev);
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_enable_clickfinger(dev);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_drain_events(li);
/* use bottom right corner to catch accidental softbutton right */
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_area_to_clickfinger_method)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
/* use bottom right corner to catch accidental softbutton right */
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_enable_buttonareas(dev);
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_area_to_clickfinger_method_while_down)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
/* use bottom right corner to catch accidental softbutton right */
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_enable_buttonareas(dev);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_touch_down(dev, 0, 95, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_3fg_tool_position)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
/* one in thumb area, one in normal area + TRIPLETAP. spread is wide
* but any non-palm 3fg touch+click counts as middle */
litest_touch_down(dev, 0, 20, 99);
litest_touch_down(dev, 1, 90, 15);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_4fg_tool_position)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 5, 99);
litest_touch_down(dev, 1, 90, 15);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_appletouch_config)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
uint32_t methods, method;
enum libinput_config_status status;
methods = libinput_device_config_click_get_methods(device);
litest_assert(!(methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS));
litest_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
method = libinput_device_config_click_get_method(device);
litest_assert_enum_eq(method, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
status = libinput_device_config_click_set_method(device,
LIBINPUT_CONFIG_CLICK_METHOD_NONE);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
}
END_TEST
START_TEST(touchpad_clickfinger_appletouch_1fg)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_appletouch_2fg)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 50, 50);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_dispatch(li);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_appletouch_3fg)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 50, 50);
litest_touch_down(dev, 2, 50, 50);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
litest_dispatch(li);
litest_assert_button_event(li, BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_clickfinger_click_drag)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
int nfingers = litest_test_param_get_i32(test_env->params, "fingers");
unsigned int button;
int nslots = litest_slot_count(dev);
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 40, 50);
button = BTN_LEFT;
if (nfingers > 1) {
if (nslots > 1) {
litest_touch_down(dev, 1, 50, 50);
} else {
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
}
button = BTN_RIGHT;
}
if (nfingers > 2) {
if (nslots > 2) {
litest_touch_down(dev, 2, 60, 50);
} else {
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
}
button = BTN_MIDDLE;
}
litest_button_click(dev, BTN_LEFT, true);
litest_dispatch(li);
litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_PRESSED);
for (int i = 0; i < 20; i++) {
litest_push_event_frame(dev);
switch (nfingers) {
case 3:
if (nslots >= nfingers)
litest_touch_move(dev, 2, 60, 50 + i);
_fallthrough_;
case 2:
if (nslots >= nfingers)
litest_touch_move(dev, 1, 50, 50 + i);
_fallthrough_;
case 1:
litest_touch_move(dev, 0, 40, 50 + i);
break;
}
litest_pop_event_frame(dev);
litest_dispatch(li);
}
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_button_click(dev, BTN_LEFT, false);
litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_RELEASED);
if (nfingers > 3) {
if (nslots > 3) {
litest_touch_up(dev, 2);
} else {
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
}
}
if (nfingers > 2) {
if (nslots > 2) {
litest_touch_up(dev, 1);
} else {
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
}
}
litest_touch_up(dev, 0);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_btn_left)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(clickpad_btn_left)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_buttonareas(dev);
litest_drain_events(li);
/* A clickpad always needs a finger down to tell where the
click happens */
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_click_n_drag)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
/* now put a second finger down */
litest_touch_down(dev, 1, 70, 70);
litest_touch_move_to(dev, 1, 70, 70, 80, 50, 5);
litest_touch_up(dev, 1);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(clickpad_finger_pin)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libevdev *evdev = dev->evdev;
const struct input_absinfo *abs;
double w, h;
double dist;
abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
litest_assert_notnull(abs);
if (abs->resolution == 0)
return LITEST_NOT_APPLICABLE;
if (libinput_device_get_size(dev->libinput_device, &w, &h) != 0)
return LITEST_NOT_APPLICABLE;
dist = 100.0/max(w, h);
litest_drain_events(li);
/* make sure the movement generates pointer events when
not pinned */
litest_touch_down(dev, 0, 50, 50);
litest_touch_move_to(dev, 0, 50, 50, 54, 54, 10);
litest_touch_move_to(dev, 0, 54, 54, 46, 46, 10);
litest_touch_move_to(dev, 0, 46, 46, 50, 50, 10);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_button_click(dev, BTN_LEFT, true);
litest_drain_events(li);
litest_touch_move_to(dev, 0, 50, 50, 50 + dist, 50 + dist, 10);
litest_touch_move_to(dev, 0, 50 + dist, 50 + dist, 50, 50, 10);
litest_touch_move_to(dev, 0, 50, 50, 50 - dist, 50 - dist, 10);
litest_assert_empty_queue(li);
litest_button_click(dev, BTN_LEFT, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON);
/* still pinned after release */
litest_touch_move_to(dev, 0, 50, 50, 50 + dist, 50 + dist, 10);
litest_touch_move_to(dev, 0, 50 + dist, 50 + dist, 50, 50, 10);
litest_touch_move_to(dev, 0, 50, 50, 50 - dist, 50 - dist, 10);
litest_assert_empty_queue(li);
/* move to unpin */
litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
}
END_TEST
START_TEST(clickpad_softbutton_left)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_touch_down(dev, 0, 10, 90);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_middle)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 90);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_right)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_touch_down(dev, 0, 90, 90);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_left_tap_n_drag)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
/* Tap in left button area, then finger down, button click
-> expect left button press/release and left button press
Release button, finger up
-> expect right button release
*/
litest_touch_down(dev, 0, 20, 90);
litest_touch_up(dev, 0);
litest_touch_down(dev, 0, 20, 90);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_right_tap_n_drag)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
/* Tap in right button area, then finger down, button click
-> expect left button press/release and right button press
Release button, finger up
-> expect right button release
*/
litest_touch_down(dev, 0, 90, 90);
litest_touch_up(dev, 0);
litest_touch_down(dev, 0, 90, 90);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_left_1st_fg_move)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
double x = 0, y = 0;
int nevents = 0;
litest_drain_events(li);
/* One finger down in the left button area, button press
-> expect a button event
Move finger up out of the area, wait for timeout
Move finger around diagonally down left
-> expect motion events down left
Release finger
-> expect a button event */
/* finger down, press in left button */
litest_touch_down(dev, 0, 20, 90);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
/* move out of the area, then wait for softbutton timer */
litest_touch_move_to(dev, 0, 20, 90, 50, 50, 20);
litest_dispatch(li);
litest_timeout_softbuttons();
litest_dispatch(li);
litest_drain_events(li);
/* move down left, expect motion */
litest_touch_move_to(dev, 0, 50, 50, 20, 90, 20);
litest_dispatch(li);
event = libinput_get_event(li);
litest_assert_notnull(event);
while (event) {
struct libinput_event_pointer *p;
litest_assert_event_type(event, LIBINPUT_EVENT_POINTER_MOTION);
p = libinput_event_get_pointer_event(event);
/* we moved up/right, now down/left so the pointer accel
code may lag behind with the dx/dy vectors. Hence, add up
the x/y movements and expect that on average we moved
left and down */
x += libinput_event_pointer_get_dx(p);
y += libinput_event_pointer_get_dy(p);
nevents++;
libinput_event_destroy(event);
litest_dispatch(li);
event = libinput_get_event(li);
}
litest_assert(x/nevents < 0);
litest_assert(y/nevents > 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_left_2nd_fg_move)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
litest_drain_events(li);
/* One finger down in the left button area, button press
-> expect a button event
Put a second finger down in the area, move it right, release
-> expect motion events right
Put a second finger down in the area, move it down, release
-> expect motion events down
Release second finger, release first finger
-> expect a button event */
litest_touch_down(dev, 0, 20, 90);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_touch_down(dev, 1, 20, 20);
litest_touch_move_to(dev, 1, 20, 20, 80, 20, 25);
litest_dispatch(li);
event = libinput_get_event(li);
litest_assert_notnull(event);
while (event) {
struct libinput_event_pointer *p;
double x, y;
litest_assert_event_type(event, LIBINPUT_EVENT_POINTER_MOTION);
p = libinput_event_get_pointer_event(event);
x = libinput_event_pointer_get_dx(p);
y = libinput_event_pointer_get_dy(p);
/* Ignore events only containing an unaccelerated motion
* vector. */
if (x != 0 || y != 0) {
litest_assert(x > 0);
litest_assert(y == 0);
}
libinput_event_destroy(event);
litest_dispatch(li);
event = libinput_get_event(li);
}
litest_touch_up(dev, 1);
/* second finger down */
litest_touch_down(dev, 1, 20, 20);
litest_touch_move_to(dev, 1, 20, 20, 20, 80, 15);
litest_dispatch(li);
event = libinput_get_event(li);
litest_assert_notnull(event);
while (event) {
struct libinput_event_pointer *p;
double x, y;
litest_assert_event_type(event, LIBINPUT_EVENT_POINTER_MOTION);
p = libinput_event_get_pointer_event(event);
x = libinput_event_pointer_get_dx(p);
y = libinput_event_pointer_get_dy(p);
litest_assert(x == 0);
litest_assert(y > 0);
libinput_event_destroy(event);
litest_dispatch(li);
event = libinput_get_event(li);
}
litest_touch_up(dev, 1);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_left_to_right)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
/* One finger down in left software button area,
move to right button area immediately, click
-> expect right button event
*/
litest_touch_down(dev, 0, 30, 90);
litest_touch_move_to(dev, 0, 30, 90, 90, 90, 25);
litest_drain_events(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_right_to_left)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
/* One finger down in right software button area,
move to left button area immediately, click
-> expect left button event
*/
litest_touch_down(dev, 0, 80, 90);
litest_touch_move_to(dev, 0, 80, 90, 30, 90, 25);
litest_drain_events(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_softbutton_hover_into_buttons)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_hover_start(dev, 0, 50, 50);
litest_dispatch(li);
litest_hover_move_to(dev, 0, 50, 50, 90, 90, 20);
litest_dispatch(li);
litest_touch_move_to(dev, 0, 90, 90, 91, 91, 1);
litest_button_click(dev, BTN_LEFT, true);
litest_dispatch(li);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_button_click(dev, BTN_LEFT, false);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(clickpad_topsoftbuttons_left)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_touch_down(dev, 0, 10, 5);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_topsoftbuttons_right)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_touch_down(dev, 0, 90, 5);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_topsoftbuttons_middle)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 5);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_topsoftbuttons_move_out_leftclick_before_timeout)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
/* Finger down in top right button area, wait past enter timeout
Move into main area, wait past leave timeout
Click
-> expect left click
*/
litest_drain_events(li);
litest_touch_down(dev, 0, 80, 5);
litest_dispatch(li);
litest_timeout_softbuttons();
litest_dispatch(li);
litest_assert_empty_queue(li);
litest_touch_move_to(dev, 0, 80, 5, 80, 90, 20);
litest_dispatch(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(clickpad_topsoftbuttons_move_out_leftclick)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
/* Finger down in top right button area, wait past enter timeout
Move into main area, wait past leave timeout
Click
-> expect left click
*/
litest_drain_events(li);
litest_touch_down(dev, 0, 80, 5);
litest_dispatch(li);
litest_timeout_softbuttons();
litest_dispatch(li);
litest_assert_empty_queue(li);
litest_touch_move_to(dev, 0, 80, 5, 80, 90, 20);
litest_dispatch(li);
litest_timeout_softbuttons();
litest_dispatch(li);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(clickpad_topsoftbuttons_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 90, 5);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 90, 5);
litest_touch_down(dev, 1, 80, 5);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(clickpad_topsoftbuttons_clickfinger_dev_disabled)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct litest_device *trackpoint = litest_add_device(li,
LITEST_TRACKPOINT);
libinput_device_config_send_events_set_mode(dev->libinput_device,
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 90, 5);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 90, 5);
litest_touch_down(dev, 1, 10, 5);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_delete_device(trackpoint);
}
END_TEST
START_TEST(clickpad_middleemulation_config_delayed)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
struct libinput *li = dev->libinput;
enum libinput_config_status status;
int enabled;
enabled = libinput_device_config_middle_emulation_get_enabled(device);
litest_assert(!enabled);
litest_touch_down(dev, 0, 30, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_dispatch(li);
/* actual config is delayed, but status is immediate */
status = libinput_device_config_middle_emulation_set_enabled(device,
LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
enabled = libinput_device_config_middle_emulation_get_enabled(device);
litest_assert(enabled);
status = libinput_device_config_middle_emulation_set_enabled(device,
LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
enabled = libinput_device_config_middle_emulation_get_enabled(device);
litest_assert(!enabled);
}
END_TEST
START_TEST(clickpad_middleemulation_click)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_buttonareas(dev);
litest_enable_middleemu(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 30, 95);
litest_touch_down(dev, 1, 80, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_middleemulation_click_middle_left)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_buttonareas(dev);
litest_enable_middleemu(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 49, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_middleemulation_click_middle_right)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_buttonareas(dev);
litest_enable_middleemu(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 51, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(clickpad_middleemulation_click_enable_while_down)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_buttonareas(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 49, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_enable_middleemu(dev);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 49, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
}
END_TEST
START_TEST(clickpad_middleemulation_click_disable_while_down)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_enable_buttonareas(dev);
litest_enable_middleemu(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 30, 95);
litest_touch_down(dev, 1, 70, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_disable_middleemu(dev);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 49, 95);
litest_event(dev, EV_KEY, BTN_LEFT, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_event(dev, EV_KEY, BTN_LEFT, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
litest_dispatch(li);
}
END_TEST
START_TEST(touchpad_non_clickpad_detection)
{
struct libinput *li;
struct libinput_device *device;
struct libevdev_uinput *uinput;
static struct input_absinfo absinfo[] = {
{ ABS_X, 1472, 5472, 0, 0, 75 },
{ ABS_Y, 1408, 4448, 0, 0, 129 },
{ ABS_PRESSURE, 0, 255, 0, 0, 0 },
{ ABS_TOOL_WIDTH, 0, 15, 0, 0, 0 },
{ ABS_MT_SLOT, 0, 1, 0, 0, 0 },
{ ABS_MT_POSITION_X, 1472, 5472, 0, 0, 75 },
{ ABS_MT_POSITION_Y, 1408, 4448, 0, 0, 129 },
{ ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
{ ABS_MT_PRESSURE, 0, 255, 0, 0, 0 },
{ .value = -1 }
};
uint32_t methods;
/* Create a touchpad with only a left button but missing
* INPUT_PROP_BUTTONPAD. We should treat this as clickpad.
*/
uinput = litest_create_uinput_abs_device("litest NonClickpad",
NULL,
absinfo,
EV_KEY, BTN_LEFT,
EV_KEY, BTN_TOOL_FINGER,
EV_KEY, BTN_TOUCH,
-1);
li = litest_create_context();
device = libinput_path_add_device(li,
libevdev_uinput_get_devnode(uinput));
methods = libinput_device_config_click_get_methods(device);
litest_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
litest_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
libinput_path_remove_device(device);
libevdev_uinput_destroy(uinput);
litest_destroy_context(li);
}
END_TEST
TEST_COLLECTION(touchpad_buttons)
{
litest_add(touchpad_button, LITEST_TOUCHPAD, LITEST_CLICKPAD);
litest_add(touchpad_1fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_1fg_clickfinger_no_touch, LITEST_CLICKPAD, LITEST_ANY);
litest_with_parameters(params, "map", 'I', 2, litest_named_i32(LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM, "LRM"),
litest_named_i32(LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR, "LMR")) {
litest_add_parametrized(touchpad_2fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY, params);
litest_add_parametrized(touchpad_3fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY, params);
litest_add_parametrized(touchpad_3fg_clickfinger_btntool, LITEST_CLICKPAD, LITEST_ANY, params);
litest_add_parametrized(touchpad_2fg_clickfinger_distance, LITEST_CLICKPAD, LITEST_ANY, params);
litest_add_parametrized(touchpad_3fg_clickfinger_distance, LITEST_CLICKPAD, LITEST_ANY, params);
litest_add_parametrized(touchpad_3fg_clickfinger_distance_btntool, LITEST_CLICKPAD, LITEST_ANY, params);
}
litest_add_for_device(touchpad_2fg_clickfinger_bottom, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add(touchpad_4fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_4fg_clickfinger_btntool_2slots, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_4fg_clickfinger_btntool_3slots, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_clickfinger_to_area_method, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_clickfinger_to_area_method_while_down, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_area_to_clickfinger_method, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_area_to_clickfinger_method_while_down, LITEST_CLICKPAD, LITEST_ANY);
/* run those two for the T440 one only so we don't have to worry
* about small touchpads messing with thumb detection expectations */
litest_add_for_device(touchpad_clickfinger_3fg_tool_position, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add_for_device(touchpad_clickfinger_4fg_tool_position, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add_for_device(touchpad_clickfinger_appletouch_config, LITEST_APPLETOUCH);
litest_add_for_device(touchpad_clickfinger_appletouch_1fg, LITEST_APPLETOUCH);
litest_add_for_device(touchpad_clickfinger_appletouch_2fg, LITEST_APPLETOUCH);
litest_add_for_device(touchpad_clickfinger_appletouch_3fg, LITEST_APPLETOUCH);
litest_add_for_device(touchpad_1fg_clickfinger_no_touch_phantomclicks, LITEST_SYNAPTICS_PHANTOMCLICKS);
litest_with_parameters(params, "fingers", 'i', 3, 1, 2, 3) {
litest_add_parametrized(touchpad_clickfinger_click_drag, LITEST_CLICKPAD, LITEST_ANY, params);
}
litest_add(touchpad_click_defaults_clickfinger, LITEST_APPLE_CLICKPAD, LITEST_ANY);
litest_add(touchpad_click_default_clickfinger_map, LITEST_APPLE_CLICKPAD, LITEST_ANY);
litest_add(touchpad_click_set_clickfinger_map, LITEST_APPLE_CLICKPAD, LITEST_ANY);
litest_add(touchpad_click_defaults_btnarea, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(touchpad_click_defaults_none, LITEST_TOUCHPAD, LITEST_CLICKPAD);
litest_add(touchpad_click_defaults_none, LITEST_ANY, LITEST_TOUCHPAD);
litest_add(touchpad_btn_left, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD);
litest_add(clickpad_btn_left, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_click_n_drag, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
litest_add(clickpad_finger_pin, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_softbutton_left, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_middle, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_right, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_left_tap_n_drag, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_right_tap_n_drag, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_left_1st_fg_move, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_left_2nd_fg_move, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_left_to_right, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_right_to_left, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_softbutton_hover_into_buttons, LITEST_CLICKPAD|LITEST_HOVER, LITEST_APPLE_CLICKPAD);
litest_add(clickpad_topsoftbuttons_left, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(clickpad_topsoftbuttons_right, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(clickpad_topsoftbuttons_middle, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(clickpad_topsoftbuttons_move_out_leftclick, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(clickpad_topsoftbuttons_move_out_leftclick_before_timeout, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(clickpad_topsoftbuttons_clickfinger, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(clickpad_topsoftbuttons_clickfinger_dev_disabled, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_config_delayed, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_click, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_click_middle_left, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_click_middle_right, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_click_enable_while_down, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_click_disable_while_down, LITEST_CLICKPAD, LITEST_ANY);
litest_add_no_device(touchpad_non_clickpad_detection);
}