1a46c0ec8Sopenharmony_ci/* 2a46c0ec8Sopenharmony_ci * Copyright © 2014 Red Hat, Inc. 3a46c0ec8Sopenharmony_ci * 4a46c0ec8Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5a46c0ec8Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6a46c0ec8Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7a46c0ec8Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8a46c0ec8Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9a46c0ec8Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10a46c0ec8Sopenharmony_ci * 11a46c0ec8Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12a46c0ec8Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13a46c0ec8Sopenharmony_ci * Software. 14a46c0ec8Sopenharmony_ci * 15a46c0ec8Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16a46c0ec8Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17a46c0ec8Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18a46c0ec8Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19a46c0ec8Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20a46c0ec8Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21a46c0ec8Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22a46c0ec8Sopenharmony_ci */ 23a46c0ec8Sopenharmony_ci 24a46c0ec8Sopenharmony_ci#include <config.h> 25a46c0ec8Sopenharmony_ci 26a46c0ec8Sopenharmony_ci#include <check.h> 27a46c0ec8Sopenharmony_ci#include <errno.h> 28a46c0ec8Sopenharmony_ci#include <fcntl.h> 29a46c0ec8Sopenharmony_ci#include <libinput.h> 30a46c0ec8Sopenharmony_ci#include <libinput-util.h> 31a46c0ec8Sopenharmony_ci#include <unistd.h> 32a46c0ec8Sopenharmony_ci#include <stdarg.h> 33a46c0ec8Sopenharmony_ci 34a46c0ec8Sopenharmony_ci#include "litest.h" 35a46c0ec8Sopenharmony_ci#include "libinput-util.h" 36a46c0ec8Sopenharmony_ci 37a46c0ec8Sopenharmony_cistatic int open_restricted(const char *path, int flags, void *data) 38a46c0ec8Sopenharmony_ci{ 39a46c0ec8Sopenharmony_ci int fd = open(path, flags); 40a46c0ec8Sopenharmony_ci return fd < 0 ? -errno : fd; 41a46c0ec8Sopenharmony_ci} 42a46c0ec8Sopenharmony_cistatic void close_restricted(int fd, void *data) 43a46c0ec8Sopenharmony_ci{ 44a46c0ec8Sopenharmony_ci close(fd); 45a46c0ec8Sopenharmony_ci} 46a46c0ec8Sopenharmony_ci 47a46c0ec8Sopenharmony_cistatic const struct libinput_interface simple_interface = { 48a46c0ec8Sopenharmony_ci .open_restricted = open_restricted, 49a46c0ec8Sopenharmony_ci .close_restricted = close_restricted, 50a46c0ec8Sopenharmony_ci}; 51a46c0ec8Sopenharmony_ci 52a46c0ec8Sopenharmony_cistatic struct libevdev_uinput * 53a46c0ec8Sopenharmony_cicreate_simple_test_device(const char *name, ...) 54a46c0ec8Sopenharmony_ci{ 55a46c0ec8Sopenharmony_ci va_list args; 56a46c0ec8Sopenharmony_ci struct libevdev_uinput *uinput; 57a46c0ec8Sopenharmony_ci struct libevdev *evdev; 58a46c0ec8Sopenharmony_ci unsigned int type, code; 59a46c0ec8Sopenharmony_ci int rc; 60a46c0ec8Sopenharmony_ci struct input_absinfo abs = { 61a46c0ec8Sopenharmony_ci .value = -1, 62a46c0ec8Sopenharmony_ci .minimum = 0, 63a46c0ec8Sopenharmony_ci .maximum = 100, 64a46c0ec8Sopenharmony_ci .fuzz = 0, 65a46c0ec8Sopenharmony_ci .flat = 0, 66a46c0ec8Sopenharmony_ci .resolution = 100, 67a46c0ec8Sopenharmony_ci }; 68a46c0ec8Sopenharmony_ci 69a46c0ec8Sopenharmony_ci evdev = libevdev_new(); 70a46c0ec8Sopenharmony_ci litest_assert_notnull(evdev); 71a46c0ec8Sopenharmony_ci libevdev_set_name(evdev, name); 72a46c0ec8Sopenharmony_ci 73a46c0ec8Sopenharmony_ci va_start(args, name); 74a46c0ec8Sopenharmony_ci 75a46c0ec8Sopenharmony_ci while ((type = va_arg(args, unsigned int)) != (unsigned int)-1 && 76a46c0ec8Sopenharmony_ci (code = va_arg(args, unsigned int)) != (unsigned int)-1) { 77a46c0ec8Sopenharmony_ci const struct input_absinfo *a = NULL; 78a46c0ec8Sopenharmony_ci if (type == EV_ABS) 79a46c0ec8Sopenharmony_ci a = &abs; 80a46c0ec8Sopenharmony_ci libevdev_enable_event_code(evdev, type, code, a); 81a46c0ec8Sopenharmony_ci } 82a46c0ec8Sopenharmony_ci 83a46c0ec8Sopenharmony_ci va_end(args); 84a46c0ec8Sopenharmony_ci 85a46c0ec8Sopenharmony_ci rc = libevdev_uinput_create_from_device(evdev, 86a46c0ec8Sopenharmony_ci LIBEVDEV_UINPUT_OPEN_MANAGED, 87a46c0ec8Sopenharmony_ci &uinput); 88a46c0ec8Sopenharmony_ci litest_assert_int_eq(rc, 0); 89a46c0ec8Sopenharmony_ci libevdev_free(evdev); 90a46c0ec8Sopenharmony_ci 91a46c0ec8Sopenharmony_ci return uinput; 92a46c0ec8Sopenharmony_ci} 93a46c0ec8Sopenharmony_ci 94a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_device_notify) 95a46c0ec8Sopenharmony_ci{ 96a46c0ec8Sopenharmony_ci struct libevdev_uinput *uinput; 97a46c0ec8Sopenharmony_ci struct libinput *li; 98a46c0ec8Sopenharmony_ci struct libinput_event *event; 99a46c0ec8Sopenharmony_ci int device_added = 0, device_removed = 0; 100a46c0ec8Sopenharmony_ci 101a46c0ec8Sopenharmony_ci uinput = create_simple_test_device("litest test device", 102a46c0ec8Sopenharmony_ci EV_REL, REL_X, 103a46c0ec8Sopenharmony_ci EV_REL, REL_Y, 104a46c0ec8Sopenharmony_ci EV_KEY, BTN_LEFT, 105a46c0ec8Sopenharmony_ci EV_KEY, BTN_MIDDLE, 106a46c0ec8Sopenharmony_ci EV_KEY, BTN_LEFT, 107a46c0ec8Sopenharmony_ci -1, -1); 108a46c0ec8Sopenharmony_ci li = litest_create_context(); 109a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); /* use the default litest handler */ 110a46c0ec8Sopenharmony_ci libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput)); 111a46c0ec8Sopenharmony_ci 112a46c0ec8Sopenharmony_ci libinput_dispatch(li); 113a46c0ec8Sopenharmony_ci libinput_suspend(li); 114a46c0ec8Sopenharmony_ci libinput_resume(li); 115a46c0ec8Sopenharmony_ci 116a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 117a46c0ec8Sopenharmony_ci enum libinput_event_type type; 118a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 119a46c0ec8Sopenharmony_ci 120a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_DEVICE_ADDED || 121a46c0ec8Sopenharmony_ci type == LIBINPUT_EVENT_DEVICE_REMOVED) { 122a46c0ec8Sopenharmony_ci struct libinput_event_device_notify *dn; 123a46c0ec8Sopenharmony_ci struct libinput_event *base; 124a46c0ec8Sopenharmony_ci dn = libinput_event_get_device_notify_event(event); 125a46c0ec8Sopenharmony_ci base = libinput_event_device_notify_get_base_event(dn); 126a46c0ec8Sopenharmony_ci ck_assert(event == base); 127a46c0ec8Sopenharmony_ci 128a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_DEVICE_ADDED) 129a46c0ec8Sopenharmony_ci device_added++; 130a46c0ec8Sopenharmony_ci else if (type == LIBINPUT_EVENT_DEVICE_REMOVED) 131a46c0ec8Sopenharmony_ci device_removed++; 132a46c0ec8Sopenharmony_ci 133a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 134a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_pointer_event(event) == NULL); 135a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 136a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 137a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_gesture_event(event) == NULL); 138a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_tool_event(event) == NULL); 139a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 140a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 141a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 142a46c0ec8Sopenharmony_ci } 143a46c0ec8Sopenharmony_ci 144a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 145a46c0ec8Sopenharmony_ci } 146a46c0ec8Sopenharmony_ci 147a46c0ec8Sopenharmony_ci litest_destroy_context(li); 148a46c0ec8Sopenharmony_ci libevdev_uinput_destroy(uinput); 149a46c0ec8Sopenharmony_ci 150a46c0ec8Sopenharmony_ci ck_assert_int_gt(device_added, 0); 151a46c0ec8Sopenharmony_ci ck_assert_int_gt(device_removed, 0); 152a46c0ec8Sopenharmony_ci} 153a46c0ec8Sopenharmony_ciEND_TEST 154a46c0ec8Sopenharmony_ci 155a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_pointer) 156a46c0ec8Sopenharmony_ci{ 157a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 158a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 159a46c0ec8Sopenharmony_ci struct libinput_event *event; 160a46c0ec8Sopenharmony_ci int motion = 0, button = 0; 161a46c0ec8Sopenharmony_ci 162a46c0ec8Sopenharmony_ci /* Queue at least two relative motion events as the first one may 163a46c0ec8Sopenharmony_ci * be absorbed by the pointer acceleration filter. */ 164a46c0ec8Sopenharmony_ci litest_event(dev, EV_REL, REL_X, -1); 165a46c0ec8Sopenharmony_ci litest_event(dev, EV_REL, REL_Y, -1); 166a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 167a46c0ec8Sopenharmony_ci litest_event(dev, EV_REL, REL_X, -1); 168a46c0ec8Sopenharmony_ci litest_event(dev, EV_REL, REL_Y, -1); 169a46c0ec8Sopenharmony_ci litest_event(dev, EV_KEY, BTN_LEFT, 1); 170a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 171a46c0ec8Sopenharmony_ci 172a46c0ec8Sopenharmony_ci libinput_dispatch(li); 173a46c0ec8Sopenharmony_ci 174a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 175a46c0ec8Sopenharmony_ci enum libinput_event_type type; 176a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 177a46c0ec8Sopenharmony_ci 178a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_POINTER_MOTION || 179a46c0ec8Sopenharmony_ci type == LIBINPUT_EVENT_POINTER_BUTTON) { 180a46c0ec8Sopenharmony_ci struct libinput_event_pointer *p; 181a46c0ec8Sopenharmony_ci struct libinput_event *base; 182a46c0ec8Sopenharmony_ci p = libinput_event_get_pointer_event(event); 183a46c0ec8Sopenharmony_ci base = libinput_event_pointer_get_base_event(p); 184a46c0ec8Sopenharmony_ci ck_assert(event == base); 185a46c0ec8Sopenharmony_ci 186a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_POINTER_MOTION) 187a46c0ec8Sopenharmony_ci motion++; 188a46c0ec8Sopenharmony_ci else if (type == LIBINPUT_EVENT_POINTER_BUTTON) 189a46c0ec8Sopenharmony_ci button++; 190a46c0ec8Sopenharmony_ci 191a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 192a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 193a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 194a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 195a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_gesture_event(event) == NULL); 196a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_tool_event(event) == NULL); 197a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 198a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 199a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 200a46c0ec8Sopenharmony_ci } 201a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 202a46c0ec8Sopenharmony_ci } 203a46c0ec8Sopenharmony_ci 204a46c0ec8Sopenharmony_ci ck_assert_int_gt(motion, 0); 205a46c0ec8Sopenharmony_ci ck_assert_int_gt(button, 0); 206a46c0ec8Sopenharmony_ci} 207a46c0ec8Sopenharmony_ciEND_TEST 208a46c0ec8Sopenharmony_ci 209a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_pointer_abs) 210a46c0ec8Sopenharmony_ci{ 211a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 212a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 213a46c0ec8Sopenharmony_ci struct libinput_event *event; 214a46c0ec8Sopenharmony_ci int motion = 0, button = 0; 215a46c0ec8Sopenharmony_ci 216a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_X, 10); 217a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_Y, 50); 218a46c0ec8Sopenharmony_ci litest_event(dev, EV_KEY, BTN_LEFT, 1); 219a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 220a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_X, 30); 221a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_Y, 30); 222a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 223a46c0ec8Sopenharmony_ci 224a46c0ec8Sopenharmony_ci libinput_dispatch(li); 225a46c0ec8Sopenharmony_ci 226a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 227a46c0ec8Sopenharmony_ci enum libinput_event_type type; 228a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 229a46c0ec8Sopenharmony_ci 230a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE || 231a46c0ec8Sopenharmony_ci type == LIBINPUT_EVENT_POINTER_BUTTON) { 232a46c0ec8Sopenharmony_ci struct libinput_event_pointer *p; 233a46c0ec8Sopenharmony_ci struct libinput_event *base; 234a46c0ec8Sopenharmony_ci p = libinput_event_get_pointer_event(event); 235a46c0ec8Sopenharmony_ci base = libinput_event_pointer_get_base_event(p); 236a46c0ec8Sopenharmony_ci ck_assert(event == base); 237a46c0ec8Sopenharmony_ci 238a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE) 239a46c0ec8Sopenharmony_ci motion++; 240a46c0ec8Sopenharmony_ci else if (type == LIBINPUT_EVENT_POINTER_BUTTON) 241a46c0ec8Sopenharmony_ci button++; 242a46c0ec8Sopenharmony_ci 243a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 244a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 245a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 246a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 247a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_gesture_event(event) == NULL); 248a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_tool_event(event) == NULL); 249a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 250a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 251a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 252a46c0ec8Sopenharmony_ci } 253a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 254a46c0ec8Sopenharmony_ci } 255a46c0ec8Sopenharmony_ci 256a46c0ec8Sopenharmony_ci ck_assert_int_gt(motion, 0); 257a46c0ec8Sopenharmony_ci ck_assert_int_gt(button, 0); 258a46c0ec8Sopenharmony_ci} 259a46c0ec8Sopenharmony_ciEND_TEST 260a46c0ec8Sopenharmony_ci 261a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_key) 262a46c0ec8Sopenharmony_ci{ 263a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 264a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 265a46c0ec8Sopenharmony_ci struct libinput_event *event; 266a46c0ec8Sopenharmony_ci int key = 0; 267a46c0ec8Sopenharmony_ci 268a46c0ec8Sopenharmony_ci litest_event(dev, EV_KEY, KEY_A, 1); 269a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 270a46c0ec8Sopenharmony_ci litest_event(dev, EV_KEY, KEY_A, 0); 271a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 272a46c0ec8Sopenharmony_ci 273a46c0ec8Sopenharmony_ci libinput_dispatch(li); 274a46c0ec8Sopenharmony_ci 275a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 276a46c0ec8Sopenharmony_ci enum libinput_event_type type; 277a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 278a46c0ec8Sopenharmony_ci 279a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_KEYBOARD_KEY) { 280a46c0ec8Sopenharmony_ci struct libinput_event_keyboard *k; 281a46c0ec8Sopenharmony_ci struct libinput_event *base; 282a46c0ec8Sopenharmony_ci k = libinput_event_get_keyboard_event(event); 283a46c0ec8Sopenharmony_ci base = libinput_event_keyboard_get_base_event(k); 284a46c0ec8Sopenharmony_ci ck_assert(event == base); 285a46c0ec8Sopenharmony_ci 286a46c0ec8Sopenharmony_ci key++; 287a46c0ec8Sopenharmony_ci 288a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 289a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 290a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_pointer_event(event) == NULL); 291a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 292a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_gesture_event(event) == NULL); 293a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_tool_event(event) == NULL); 294a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 295a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 296a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 297a46c0ec8Sopenharmony_ci } 298a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 299a46c0ec8Sopenharmony_ci } 300a46c0ec8Sopenharmony_ci 301a46c0ec8Sopenharmony_ci ck_assert_int_gt(key, 0); 302a46c0ec8Sopenharmony_ci} 303a46c0ec8Sopenharmony_ciEND_TEST 304a46c0ec8Sopenharmony_ci 305a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_touch) 306a46c0ec8Sopenharmony_ci{ 307a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 308a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 309a46c0ec8Sopenharmony_ci struct libinput_event *event; 310a46c0ec8Sopenharmony_ci int touch = 0; 311a46c0ec8Sopenharmony_ci 312a46c0ec8Sopenharmony_ci libinput_dispatch(li); 313a46c0ec8Sopenharmony_ci 314a46c0ec8Sopenharmony_ci litest_event(dev, EV_KEY, BTN_TOOL_FINGER, 1); 315a46c0ec8Sopenharmony_ci litest_event(dev, EV_KEY, BTN_TOUCH, 1); 316a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_X, 10); 317a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_Y, 10); 318a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_MT_SLOT, 0); 319a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_MT_TRACKING_ID, 1); 320a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_MT_POSITION_X, 10); 321a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, ABS_MT_POSITION_Y, 10); 322a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 323a46c0ec8Sopenharmony_ci 324a46c0ec8Sopenharmony_ci libinput_dispatch(li); 325a46c0ec8Sopenharmony_ci 326a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 327a46c0ec8Sopenharmony_ci enum libinput_event_type type; 328a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 329a46c0ec8Sopenharmony_ci 330a46c0ec8Sopenharmony_ci if (type >= LIBINPUT_EVENT_TOUCH_DOWN && 331a46c0ec8Sopenharmony_ci type <= LIBINPUT_EVENT_TOUCH_FRAME) { 332a46c0ec8Sopenharmony_ci struct libinput_event_touch *t; 333a46c0ec8Sopenharmony_ci struct libinput_event *base; 334a46c0ec8Sopenharmony_ci t = libinput_event_get_touch_event(event); 335a46c0ec8Sopenharmony_ci base = libinput_event_touch_get_base_event(t); 336a46c0ec8Sopenharmony_ci ck_assert(event == base); 337a46c0ec8Sopenharmony_ci 338a46c0ec8Sopenharmony_ci touch++; 339a46c0ec8Sopenharmony_ci 340a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 341a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 342a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_pointer_event(event) == NULL); 343a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 344a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_gesture_event(event) == NULL); 345a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_tool_event(event) == NULL); 346a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 347a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 348a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 349a46c0ec8Sopenharmony_ci } 350a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 351a46c0ec8Sopenharmony_ci } 352a46c0ec8Sopenharmony_ci 353a46c0ec8Sopenharmony_ci ck_assert_int_gt(touch, 0); 354a46c0ec8Sopenharmony_ci} 355a46c0ec8Sopenharmony_ciEND_TEST 356a46c0ec8Sopenharmony_ci 357a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_gesture) 358a46c0ec8Sopenharmony_ci{ 359a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 360a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 361a46c0ec8Sopenharmony_ci struct libinput_event *event; 362a46c0ec8Sopenharmony_ci int gestures = 0; 363a46c0ec8Sopenharmony_ci int i; 364a46c0ec8Sopenharmony_ci 365a46c0ec8Sopenharmony_ci libinput_dispatch(li); 366a46c0ec8Sopenharmony_ci 367a46c0ec8Sopenharmony_ci litest_touch_down(dev, 0, 70, 30); 368a46c0ec8Sopenharmony_ci litest_touch_down(dev, 1, 30, 70); 369a46c0ec8Sopenharmony_ci libinput_dispatch(li); 370a46c0ec8Sopenharmony_ci litest_timeout_gesture_hold(); 371a46c0ec8Sopenharmony_ci 372a46c0ec8Sopenharmony_ci for (i = 0; i < 8; i++) { 373a46c0ec8Sopenharmony_ci litest_push_event_frame(dev); 374a46c0ec8Sopenharmony_ci litest_touch_move(dev, 0, 70 - i * 5, 30 + i * 5); 375a46c0ec8Sopenharmony_ci litest_touch_move(dev, 1, 30 + i * 5, 70 - i * 5); 376a46c0ec8Sopenharmony_ci litest_pop_event_frame(dev); 377a46c0ec8Sopenharmony_ci libinput_dispatch(li); 378a46c0ec8Sopenharmony_ci } 379a46c0ec8Sopenharmony_ci 380a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 381a46c0ec8Sopenharmony_ci enum libinput_event_type type; 382a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 383a46c0ec8Sopenharmony_ci 384a46c0ec8Sopenharmony_ci if (type >= LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN && 385a46c0ec8Sopenharmony_ci type <= LIBINPUT_EVENT_GESTURE_HOLD_END) { 386a46c0ec8Sopenharmony_ci struct libinput_event_gesture *g; 387a46c0ec8Sopenharmony_ci struct libinput_event *base; 388a46c0ec8Sopenharmony_ci g = libinput_event_get_gesture_event(event); 389a46c0ec8Sopenharmony_ci base = libinput_event_gesture_get_base_event(g); 390a46c0ec8Sopenharmony_ci ck_assert(event == base); 391a46c0ec8Sopenharmony_ci 392a46c0ec8Sopenharmony_ci gestures++; 393a46c0ec8Sopenharmony_ci 394a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 395a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 396a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_pointer_event(event) == NULL); 397a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 398a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 399a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 400a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 401a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 402a46c0ec8Sopenharmony_ci } 403a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 404a46c0ec8Sopenharmony_ci } 405a46c0ec8Sopenharmony_ci 406a46c0ec8Sopenharmony_ci ck_assert_int_gt(gestures, 0); 407a46c0ec8Sopenharmony_ci} 408a46c0ec8Sopenharmony_ciEND_TEST 409a46c0ec8Sopenharmony_ci 410a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_tablet) 411a46c0ec8Sopenharmony_ci{ 412a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 413a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 414a46c0ec8Sopenharmony_ci struct libinput_event *event; 415a46c0ec8Sopenharmony_ci int events = 0; 416a46c0ec8Sopenharmony_ci struct axis_replacement axes[] = { 417a46c0ec8Sopenharmony_ci { ABS_DISTANCE, 10 }, 418a46c0ec8Sopenharmony_ci { -1, -1 } 419a46c0ec8Sopenharmony_ci }; 420a46c0ec8Sopenharmony_ci 421a46c0ec8Sopenharmony_ci litest_tablet_proximity_in(dev, 50, 50, axes); 422a46c0ec8Sopenharmony_ci litest_tablet_motion(dev, 60, 50, axes); 423a46c0ec8Sopenharmony_ci litest_button_click(dev, BTN_STYLUS, true); 424a46c0ec8Sopenharmony_ci litest_button_click(dev, BTN_STYLUS, false); 425a46c0ec8Sopenharmony_ci 426a46c0ec8Sopenharmony_ci libinput_dispatch(li); 427a46c0ec8Sopenharmony_ci 428a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 429a46c0ec8Sopenharmony_ci enum libinput_event_type type; 430a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 431a46c0ec8Sopenharmony_ci 432a46c0ec8Sopenharmony_ci if (type >= LIBINPUT_EVENT_TABLET_TOOL_AXIS && 433a46c0ec8Sopenharmony_ci type <= LIBINPUT_EVENT_TABLET_TOOL_BUTTON) { 434a46c0ec8Sopenharmony_ci struct libinput_event_tablet_tool *t; 435a46c0ec8Sopenharmony_ci struct libinput_event *base; 436a46c0ec8Sopenharmony_ci t = libinput_event_get_tablet_tool_event(event); 437a46c0ec8Sopenharmony_ci base = libinput_event_tablet_tool_get_base_event(t); 438a46c0ec8Sopenharmony_ci ck_assert(event == base); 439a46c0ec8Sopenharmony_ci 440a46c0ec8Sopenharmony_ci events++; 441a46c0ec8Sopenharmony_ci 442a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 443a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 444a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_pointer_event(event) == NULL); 445a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 446a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 447a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 448a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 449a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 450a46c0ec8Sopenharmony_ci } 451a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 452a46c0ec8Sopenharmony_ci } 453a46c0ec8Sopenharmony_ci 454a46c0ec8Sopenharmony_ci ck_assert_int_gt(events, 0); 455a46c0ec8Sopenharmony_ci} 456a46c0ec8Sopenharmony_ciEND_TEST 457a46c0ec8Sopenharmony_ci 458a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_tablet_pad) 459a46c0ec8Sopenharmony_ci{ 460a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 461a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 462a46c0ec8Sopenharmony_ci struct libinput_event *event; 463a46c0ec8Sopenharmony_ci int events = 0; 464a46c0ec8Sopenharmony_ci 465a46c0ec8Sopenharmony_ci litest_button_click(dev, BTN_0, true); 466a46c0ec8Sopenharmony_ci litest_pad_ring_start(dev, 10); 467a46c0ec8Sopenharmony_ci litest_pad_ring_end(dev); 468a46c0ec8Sopenharmony_ci 469a46c0ec8Sopenharmony_ci libinput_dispatch(li); 470a46c0ec8Sopenharmony_ci 471a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 472a46c0ec8Sopenharmony_ci enum libinput_event_type type; 473a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 474a46c0ec8Sopenharmony_ci 475a46c0ec8Sopenharmony_ci if (type >= LIBINPUT_EVENT_TABLET_PAD_BUTTON && 476a46c0ec8Sopenharmony_ci type <= LIBINPUT_EVENT_TABLET_PAD_STRIP) { 477a46c0ec8Sopenharmony_ci struct libinput_event_tablet_pad *p; 478a46c0ec8Sopenharmony_ci struct libinput_event *base; 479a46c0ec8Sopenharmony_ci 480a46c0ec8Sopenharmony_ci p = libinput_event_get_tablet_pad_event(event); 481a46c0ec8Sopenharmony_ci base = libinput_event_tablet_pad_get_base_event(p); 482a46c0ec8Sopenharmony_ci ck_assert(event == base); 483a46c0ec8Sopenharmony_ci 484a46c0ec8Sopenharmony_ci events++; 485a46c0ec8Sopenharmony_ci 486a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 487a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 488a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_pointer_event(event) == NULL); 489a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 490a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 491a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_tool_event(event) == NULL); 492a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_switch_event(event) == NULL); 493a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 494a46c0ec8Sopenharmony_ci } 495a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 496a46c0ec8Sopenharmony_ci } 497a46c0ec8Sopenharmony_ci 498a46c0ec8Sopenharmony_ci ck_assert_int_gt(events, 0); 499a46c0ec8Sopenharmony_ci} 500a46c0ec8Sopenharmony_ciEND_TEST 501a46c0ec8Sopenharmony_ci 502a46c0ec8Sopenharmony_ciSTART_TEST(event_conversion_switch) 503a46c0ec8Sopenharmony_ci{ 504a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 505a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 506a46c0ec8Sopenharmony_ci struct libinput_event *event; 507a46c0ec8Sopenharmony_ci int sw = 0; 508a46c0ec8Sopenharmony_ci 509a46c0ec8Sopenharmony_ci litest_switch_action(dev, 510a46c0ec8Sopenharmony_ci LIBINPUT_SWITCH_LID, 511a46c0ec8Sopenharmony_ci LIBINPUT_SWITCH_STATE_ON); 512a46c0ec8Sopenharmony_ci litest_switch_action(dev, 513a46c0ec8Sopenharmony_ci LIBINPUT_SWITCH_LID, 514a46c0ec8Sopenharmony_ci LIBINPUT_SWITCH_STATE_OFF); 515a46c0ec8Sopenharmony_ci libinput_dispatch(li); 516a46c0ec8Sopenharmony_ci 517a46c0ec8Sopenharmony_ci while ((event = libinput_get_event(li))) { 518a46c0ec8Sopenharmony_ci enum libinput_event_type type; 519a46c0ec8Sopenharmony_ci type = libinput_event_get_type(event); 520a46c0ec8Sopenharmony_ci 521a46c0ec8Sopenharmony_ci if (type == LIBINPUT_EVENT_SWITCH_TOGGLE) { 522a46c0ec8Sopenharmony_ci struct libinput_event_switch *s; 523a46c0ec8Sopenharmony_ci struct libinput_event *base; 524a46c0ec8Sopenharmony_ci s = libinput_event_get_switch_event(event); 525a46c0ec8Sopenharmony_ci base = libinput_event_switch_get_base_event(s); 526a46c0ec8Sopenharmony_ci ck_assert(event == base); 527a46c0ec8Sopenharmony_ci 528a46c0ec8Sopenharmony_ci sw++; 529a46c0ec8Sopenharmony_ci 530a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 531a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_device_notify_event(event) == NULL); 532a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_keyboard_event(event) == NULL); 533a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_pointer_event(event) == NULL); 534a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_touch_event(event) == NULL); 535a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_gesture_event(event) == NULL); 536a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_tool_event(event) == NULL); 537a46c0ec8Sopenharmony_ci ck_assert(libinput_event_get_tablet_pad_event(event) == NULL); 538a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 539a46c0ec8Sopenharmony_ci } 540a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 541a46c0ec8Sopenharmony_ci } 542a46c0ec8Sopenharmony_ci 543a46c0ec8Sopenharmony_ci ck_assert_int_gt(sw, 0); 544a46c0ec8Sopenharmony_ci} 545a46c0ec8Sopenharmony_ciEND_TEST 546a46c0ec8Sopenharmony_ci 547a46c0ec8Sopenharmony_ciSTART_TEST(context_ref_counting) 548a46c0ec8Sopenharmony_ci{ 549a46c0ec8Sopenharmony_ci struct libinput *li; 550a46c0ec8Sopenharmony_ci 551a46c0ec8Sopenharmony_ci /* These tests rely on valgrind to detect memory leak and use after 552a46c0ec8Sopenharmony_ci * free errors. */ 553a46c0ec8Sopenharmony_ci 554a46c0ec8Sopenharmony_ci li = libinput_path_create_context(&simple_interface, NULL); 555a46c0ec8Sopenharmony_ci ck_assert_notnull(li); 556a46c0ec8Sopenharmony_ci ck_assert_ptr_eq(libinput_unref(li), NULL); 557a46c0ec8Sopenharmony_ci 558a46c0ec8Sopenharmony_ci li = libinput_path_create_context(&simple_interface, NULL); 559a46c0ec8Sopenharmony_ci ck_assert_notnull(li); 560a46c0ec8Sopenharmony_ci ck_assert_ptr_eq(libinput_ref(li), li); 561a46c0ec8Sopenharmony_ci ck_assert_ptr_eq(libinput_unref(li), li); 562a46c0ec8Sopenharmony_ci ck_assert_ptr_eq(libinput_unref(li), NULL); 563a46c0ec8Sopenharmony_ci} 564a46c0ec8Sopenharmony_ciEND_TEST 565a46c0ec8Sopenharmony_ci 566a46c0ec8Sopenharmony_ciSTART_TEST(config_status_string) 567a46c0ec8Sopenharmony_ci{ 568a46c0ec8Sopenharmony_ci const char *strs[3]; 569a46c0ec8Sopenharmony_ci const char *invalid; 570a46c0ec8Sopenharmony_ci size_t i, j; 571a46c0ec8Sopenharmony_ci 572a46c0ec8Sopenharmony_ci strs[0] = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_SUCCESS); 573a46c0ec8Sopenharmony_ci strs[1] = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_UNSUPPORTED); 574a46c0ec8Sopenharmony_ci strs[2] = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_INVALID); 575a46c0ec8Sopenharmony_ci 576a46c0ec8Sopenharmony_ci for (i = 0; i < ARRAY_LENGTH(strs) - 1; i++) 577a46c0ec8Sopenharmony_ci for (j = i + 1; j < ARRAY_LENGTH(strs); j++) 578a46c0ec8Sopenharmony_ci ck_assert_str_ne(strs[i], strs[j]); 579a46c0ec8Sopenharmony_ci 580a46c0ec8Sopenharmony_ci invalid = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_INVALID + 1); 581a46c0ec8Sopenharmony_ci ck_assert(invalid == NULL); 582a46c0ec8Sopenharmony_ci invalid = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_SUCCESS - 1); 583a46c0ec8Sopenharmony_ci ck_assert(invalid == NULL); 584a46c0ec8Sopenharmony_ci} 585a46c0ec8Sopenharmony_ciEND_TEST 586a46c0ec8Sopenharmony_ci 587a46c0ec8Sopenharmony_cistatic int open_restricted_leak(const char *path, int flags, void *data) 588a46c0ec8Sopenharmony_ci{ 589a46c0ec8Sopenharmony_ci return *(int*)data; 590a46c0ec8Sopenharmony_ci} 591a46c0ec8Sopenharmony_ci 592a46c0ec8Sopenharmony_cistatic void close_restricted_leak(int fd, void *data) 593a46c0ec8Sopenharmony_ci{ 594a46c0ec8Sopenharmony_ci /* noop */ 595a46c0ec8Sopenharmony_ci} 596a46c0ec8Sopenharmony_ci 597a46c0ec8Sopenharmony_ciconst struct libinput_interface leak_interface = { 598a46c0ec8Sopenharmony_ci .open_restricted = open_restricted_leak, 599a46c0ec8Sopenharmony_ci .close_restricted = close_restricted_leak, 600a46c0ec8Sopenharmony_ci}; 601a46c0ec8Sopenharmony_ci 602a46c0ec8Sopenharmony_ciSTART_TEST(fd_no_event_leak) 603a46c0ec8Sopenharmony_ci{ 604a46c0ec8Sopenharmony_ci struct libevdev_uinput *uinput; 605a46c0ec8Sopenharmony_ci struct libinput *li; 606a46c0ec8Sopenharmony_ci struct libinput_device *device; 607a46c0ec8Sopenharmony_ci int fd = -1; 608a46c0ec8Sopenharmony_ci const char *path; 609a46c0ec8Sopenharmony_ci struct libinput_event *event; 610a46c0ec8Sopenharmony_ci 611a46c0ec8Sopenharmony_ci uinput = create_simple_test_device("litest test device", 612a46c0ec8Sopenharmony_ci EV_REL, REL_X, 613a46c0ec8Sopenharmony_ci EV_REL, REL_Y, 614a46c0ec8Sopenharmony_ci EV_KEY, BTN_LEFT, 615a46c0ec8Sopenharmony_ci EV_KEY, BTN_MIDDLE, 616a46c0ec8Sopenharmony_ci EV_KEY, BTN_LEFT, 617a46c0ec8Sopenharmony_ci -1, -1); 618a46c0ec8Sopenharmony_ci path = libevdev_uinput_get_devnode(uinput); 619a46c0ec8Sopenharmony_ci 620a46c0ec8Sopenharmony_ci fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC); 621a46c0ec8Sopenharmony_ci ck_assert_int_gt(fd, -1); 622a46c0ec8Sopenharmony_ci 623a46c0ec8Sopenharmony_ci li = libinput_path_create_context(&leak_interface, &fd); 624a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); /* use the default litest handler */ 625a46c0ec8Sopenharmony_ci 626a46c0ec8Sopenharmony_ci /* Add the device, trigger an event, then remove it again. 627a46c0ec8Sopenharmony_ci * Without it, we get a SYN_DROPPED immediately and no events. 628a46c0ec8Sopenharmony_ci */ 629a46c0ec8Sopenharmony_ci device = libinput_path_add_device(li, path); 630a46c0ec8Sopenharmony_ci libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1); 631a46c0ec8Sopenharmony_ci libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0); 632a46c0ec8Sopenharmony_ci libinput_path_remove_device(device); 633a46c0ec8Sopenharmony_ci libinput_dispatch(li); 634a46c0ec8Sopenharmony_ci litest_drain_events(li); 635a46c0ec8Sopenharmony_ci 636a46c0ec8Sopenharmony_ci /* Device is removed, but fd is still open. Queue an event, add a 637a46c0ec8Sopenharmony_ci * new device with the same fd, the queued event must be discarded 638a46c0ec8Sopenharmony_ci * by libinput */ 639a46c0ec8Sopenharmony_ci libevdev_uinput_write_event(uinput, EV_REL, REL_Y, 1); 640a46c0ec8Sopenharmony_ci libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0); 641a46c0ec8Sopenharmony_ci libinput_dispatch(li); 642a46c0ec8Sopenharmony_ci 643a46c0ec8Sopenharmony_ci libinput_path_add_device(li, path); 644a46c0ec8Sopenharmony_ci libinput_dispatch(li); 645a46c0ec8Sopenharmony_ci event = libinput_get_event(li); 646a46c0ec8Sopenharmony_ci ck_assert_int_eq(libinput_event_get_type(event), 647a46c0ec8Sopenharmony_ci LIBINPUT_EVENT_DEVICE_ADDED); 648a46c0ec8Sopenharmony_ci libinput_event_destroy(event); 649a46c0ec8Sopenharmony_ci 650a46c0ec8Sopenharmony_ci litest_assert_empty_queue(li); 651a46c0ec8Sopenharmony_ci 652a46c0ec8Sopenharmony_ci close(fd); 653a46c0ec8Sopenharmony_ci libinput_unref(li); 654a46c0ec8Sopenharmony_ci libevdev_uinput_destroy(uinput); 655a46c0ec8Sopenharmony_ci} 656a46c0ec8Sopenharmony_ciEND_TEST 657a46c0ec8Sopenharmony_ci 658a46c0ec8Sopenharmony_cistatic void timer_offset_warning(struct libinput *libinput, 659a46c0ec8Sopenharmony_ci enum libinput_log_priority priority, 660a46c0ec8Sopenharmony_ci const char *format, 661a46c0ec8Sopenharmony_ci va_list args) 662a46c0ec8Sopenharmony_ci{ 663a46c0ec8Sopenharmony_ci struct litest_user_data *user_data = libinput_get_user_data(libinput); 664a46c0ec8Sopenharmony_ci int *warning_triggered = user_data->private; 665a46c0ec8Sopenharmony_ci 666a46c0ec8Sopenharmony_ci if (priority == LIBINPUT_LOG_PRIORITY_ERROR && 667a46c0ec8Sopenharmony_ci strstr(format, "scheduled expiry is in the past")) 668a46c0ec8Sopenharmony_ci (*warning_triggered)++; 669a46c0ec8Sopenharmony_ci} 670a46c0ec8Sopenharmony_ci 671a46c0ec8Sopenharmony_ciSTART_TEST(timer_offset_bug_warning) 672a46c0ec8Sopenharmony_ci{ 673a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 674a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 675a46c0ec8Sopenharmony_ci int warning_triggered = 0; 676a46c0ec8Sopenharmony_ci struct litest_user_data *user_data = libinput_get_user_data(li); 677a46c0ec8Sopenharmony_ci 678a46c0ec8Sopenharmony_ci litest_enable_tap(dev->libinput_device); 679a46c0ec8Sopenharmony_ci litest_drain_events(li); 680a46c0ec8Sopenharmony_ci 681a46c0ec8Sopenharmony_ci litest_touch_down(dev, 0, 50, 50); 682a46c0ec8Sopenharmony_ci litest_touch_up(dev, 0); 683a46c0ec8Sopenharmony_ci 684a46c0ec8Sopenharmony_ci litest_timeout_tap(); 685a46c0ec8Sopenharmony_ci 686a46c0ec8Sopenharmony_ci user_data->private = &warning_triggered; 687a46c0ec8Sopenharmony_ci libinput_log_set_handler(li, timer_offset_warning); 688a46c0ec8Sopenharmony_ci libinput_dispatch(li); 689a46c0ec8Sopenharmony_ci 690a46c0ec8Sopenharmony_ci /* triggered for touch down and touch up */ 691a46c0ec8Sopenharmony_ci ck_assert_int_eq(warning_triggered, 2); 692a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 693a46c0ec8Sopenharmony_ci} 694a46c0ec8Sopenharmony_ciEND_TEST 695a46c0ec8Sopenharmony_ci 696a46c0ec8Sopenharmony_cistatic void timer_delay_warning(struct libinput *libinput, 697a46c0ec8Sopenharmony_ci enum libinput_log_priority priority, 698a46c0ec8Sopenharmony_ci const char *format, 699a46c0ec8Sopenharmony_ci va_list args) 700a46c0ec8Sopenharmony_ci{ 701a46c0ec8Sopenharmony_ci struct litest_user_data *user_data = libinput_get_user_data(libinput); 702a46c0ec8Sopenharmony_ci int *warning_triggered = user_data->private; 703a46c0ec8Sopenharmony_ci 704a46c0ec8Sopenharmony_ci if (priority == LIBINPUT_LOG_PRIORITY_ERROR && 705a46c0ec8Sopenharmony_ci strstr(format, "event processing lagging behind by")) 706a46c0ec8Sopenharmony_ci (*warning_triggered)++; 707a46c0ec8Sopenharmony_ci} 708a46c0ec8Sopenharmony_ci 709a46c0ec8Sopenharmony_ciSTART_TEST(timer_delay_bug_warning) 710a46c0ec8Sopenharmony_ci{ 711a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 712a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 713a46c0ec8Sopenharmony_ci int warning_triggered = 0; 714a46c0ec8Sopenharmony_ci struct litest_user_data *user_data = libinput_get_user_data(li); 715a46c0ec8Sopenharmony_ci 716a46c0ec8Sopenharmony_ci litest_drain_events(li); 717a46c0ec8Sopenharmony_ci 718a46c0ec8Sopenharmony_ci user_data->private = &warning_triggered; 719a46c0ec8Sopenharmony_ci libinput_log_set_handler(li, timer_delay_warning); 720a46c0ec8Sopenharmony_ci 721a46c0ec8Sopenharmony_ci for (int i = 0; i < 20; i++) { 722a46c0ec8Sopenharmony_ci litest_event(dev, EV_REL, REL_X, -1); 723a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 724a46c0ec8Sopenharmony_ci msleep(21); 725a46c0ec8Sopenharmony_ci libinput_dispatch(li); 726a46c0ec8Sopenharmony_ci } 727a46c0ec8Sopenharmony_ci 728a46c0ec8Sopenharmony_ci ck_assert_int_ge(warning_triggered, 1); 729a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 730a46c0ec8Sopenharmony_ci} 731a46c0ec8Sopenharmony_ciEND_TEST 732a46c0ec8Sopenharmony_ci 733a46c0ec8Sopenharmony_ciSTART_TEST(timer_flush) 734a46c0ec8Sopenharmony_ci{ 735a46c0ec8Sopenharmony_ci struct libinput *li; 736a46c0ec8Sopenharmony_ci struct litest_device *keyboard, *touchpad; 737a46c0ec8Sopenharmony_ci 738a46c0ec8Sopenharmony_ci li = litest_create_context(); 739a46c0ec8Sopenharmony_ci 740a46c0ec8Sopenharmony_ci touchpad = litest_add_device(li, LITEST_SYNAPTICS_TOUCHPAD); 741a46c0ec8Sopenharmony_ci litest_enable_tap(touchpad->libinput_device); 742a46c0ec8Sopenharmony_ci libinput_dispatch(li); 743a46c0ec8Sopenharmony_ci keyboard = litest_add_device(li, LITEST_KEYBOARD); 744a46c0ec8Sopenharmony_ci libinput_dispatch(li); 745a46c0ec8Sopenharmony_ci litest_drain_events(li); 746a46c0ec8Sopenharmony_ci 747a46c0ec8Sopenharmony_ci /* make sure tapping works */ 748a46c0ec8Sopenharmony_ci litest_touch_down(touchpad, 0, 50, 50); 749a46c0ec8Sopenharmony_ci litest_touch_up(touchpad, 0); 750a46c0ec8Sopenharmony_ci libinput_dispatch(li); 751a46c0ec8Sopenharmony_ci litest_timeout_tap(); 752a46c0ec8Sopenharmony_ci libinput_dispatch(li); 753a46c0ec8Sopenharmony_ci 754a46c0ec8Sopenharmony_ci litest_assert_button_event(li, BTN_LEFT, 755a46c0ec8Sopenharmony_ci LIBINPUT_BUTTON_STATE_PRESSED); 756a46c0ec8Sopenharmony_ci litest_assert_button_event(li, BTN_LEFT, 757a46c0ec8Sopenharmony_ci LIBINPUT_BUTTON_STATE_RELEASED); 758a46c0ec8Sopenharmony_ci litest_assert_empty_queue(li); 759a46c0ec8Sopenharmony_ci 760a46c0ec8Sopenharmony_ci /* make sure dwt-tap is ignored */ 761a46c0ec8Sopenharmony_ci litest_keyboard_key(keyboard, KEY_A, true); 762a46c0ec8Sopenharmony_ci litest_keyboard_key(keyboard, KEY_A, false); 763a46c0ec8Sopenharmony_ci libinput_dispatch(li); 764a46c0ec8Sopenharmony_ci litest_touch_down(touchpad, 0, 50, 50); 765a46c0ec8Sopenharmony_ci litest_touch_up(touchpad, 0); 766a46c0ec8Sopenharmony_ci libinput_dispatch(li); 767a46c0ec8Sopenharmony_ci litest_timeout_tap(); 768a46c0ec8Sopenharmony_ci libinput_dispatch(li); 769a46c0ec8Sopenharmony_ci litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY); 770a46c0ec8Sopenharmony_ci 771a46c0ec8Sopenharmony_ci /* Ignore 'timer offset negative' warnings */ 772a46c0ec8Sopenharmony_ci litest_disable_log_handler(li); 773a46c0ec8Sopenharmony_ci 774a46c0ec8Sopenharmony_ci /* now mess with the timing 775a46c0ec8Sopenharmony_ci - send a key event 776a46c0ec8Sopenharmony_ci - expire dwt 777a46c0ec8Sopenharmony_ci - send a tap 778a46c0ec8Sopenharmony_ci and then call libinput_dispatch(). libinput should notice that 779a46c0ec8Sopenharmony_ci the tap event came in after the timeout and thus acknowledge the 780a46c0ec8Sopenharmony_ci tap. 781a46c0ec8Sopenharmony_ci */ 782a46c0ec8Sopenharmony_ci litest_keyboard_key(keyboard, KEY_A, true); 783a46c0ec8Sopenharmony_ci litest_keyboard_key(keyboard, KEY_A, false); 784a46c0ec8Sopenharmony_ci litest_timeout_dwt_long(); 785a46c0ec8Sopenharmony_ci litest_touch_down(touchpad, 0, 50, 50); 786a46c0ec8Sopenharmony_ci litest_touch_up(touchpad, 0); 787a46c0ec8Sopenharmony_ci libinput_dispatch(li); 788a46c0ec8Sopenharmony_ci litest_timeout_tap(); 789a46c0ec8Sopenharmony_ci libinput_dispatch(li); 790a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 791a46c0ec8Sopenharmony_ci 792a46c0ec8Sopenharmony_ci litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED); 793a46c0ec8Sopenharmony_ci litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED); 794a46c0ec8Sopenharmony_ci litest_assert_button_event(li, BTN_LEFT, 795a46c0ec8Sopenharmony_ci LIBINPUT_BUTTON_STATE_PRESSED); 796a46c0ec8Sopenharmony_ci litest_assert_button_event(li, BTN_LEFT, 797a46c0ec8Sopenharmony_ci LIBINPUT_BUTTON_STATE_RELEASED); 798a46c0ec8Sopenharmony_ci 799a46c0ec8Sopenharmony_ci litest_delete_device(keyboard); 800a46c0ec8Sopenharmony_ci litest_delete_device(touchpad); 801a46c0ec8Sopenharmony_ci 802a46c0ec8Sopenharmony_ci litest_destroy_context(li); 803a46c0ec8Sopenharmony_ci} 804a46c0ec8Sopenharmony_ciEND_TEST 805a46c0ec8Sopenharmony_ci 806a46c0ec8Sopenharmony_ciSTART_TEST(udev_absinfo_override) 807a46c0ec8Sopenharmony_ci{ 808a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 809a46c0ec8Sopenharmony_ci struct libevdev *evdev = dev->evdev; 810a46c0ec8Sopenharmony_ci const struct input_absinfo *abs; 811a46c0ec8Sopenharmony_ci struct udev_device *ud; 812a46c0ec8Sopenharmony_ci struct udev_list_entry *entry; 813a46c0ec8Sopenharmony_ci bool found_x = false, found_y = false, 814a46c0ec8Sopenharmony_ci found_mt_x = false, found_mt_y = false; 815a46c0ec8Sopenharmony_ci 816a46c0ec8Sopenharmony_ci ud = libinput_device_get_udev_device(dev->libinput_device); 817a46c0ec8Sopenharmony_ci ck_assert_notnull(ud); 818a46c0ec8Sopenharmony_ci 819a46c0ec8Sopenharmony_ci /* Custom checks for this special litest device only */ 820a46c0ec8Sopenharmony_ci 821a46c0ec8Sopenharmony_ci entry = udev_device_get_properties_list_entry(ud); 822a46c0ec8Sopenharmony_ci while (entry) { 823a46c0ec8Sopenharmony_ci const char *key, *value; 824a46c0ec8Sopenharmony_ci 825a46c0ec8Sopenharmony_ci key = udev_list_entry_get_name(entry); 826a46c0ec8Sopenharmony_ci value = udev_list_entry_get_value(entry); 827a46c0ec8Sopenharmony_ci 828a46c0ec8Sopenharmony_ci if (streq(key, "EVDEV_ABS_00")) { 829a46c0ec8Sopenharmony_ci found_x = true; 830a46c0ec8Sopenharmony_ci ck_assert(streq(value, "1:1000:100:10")); 831a46c0ec8Sopenharmony_ci } 832a46c0ec8Sopenharmony_ci if (streq(key, "EVDEV_ABS_01")) { 833a46c0ec8Sopenharmony_ci found_y = true; 834a46c0ec8Sopenharmony_ci ck_assert(streq(value, "2:2000:200:20")); 835a46c0ec8Sopenharmony_ci } 836a46c0ec8Sopenharmony_ci if (streq(key, "EVDEV_ABS_35")) { 837a46c0ec8Sopenharmony_ci found_mt_x = true; 838a46c0ec8Sopenharmony_ci ck_assert(streq(value, "3:3000:300:30")); 839a46c0ec8Sopenharmony_ci } 840a46c0ec8Sopenharmony_ci if (streq(key, "EVDEV_ABS_36")) { 841a46c0ec8Sopenharmony_ci found_mt_y = true; 842a46c0ec8Sopenharmony_ci ck_assert(streq(value, "4:4000:400:40")); 843a46c0ec8Sopenharmony_ci } 844a46c0ec8Sopenharmony_ci 845a46c0ec8Sopenharmony_ci entry = udev_list_entry_get_next(entry); 846a46c0ec8Sopenharmony_ci } 847a46c0ec8Sopenharmony_ci udev_device_unref(ud); 848a46c0ec8Sopenharmony_ci 849a46c0ec8Sopenharmony_ci ck_assert(found_x); 850a46c0ec8Sopenharmony_ci ck_assert(found_y); 851a46c0ec8Sopenharmony_ci ck_assert(found_mt_x); 852a46c0ec8Sopenharmony_ci ck_assert(found_mt_y); 853a46c0ec8Sopenharmony_ci 854a46c0ec8Sopenharmony_ci abs = libevdev_get_abs_info(evdev, ABS_X); 855a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->minimum, 1); 856a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->maximum, 1000); 857a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->resolution, 100); 858a46c0ec8Sopenharmony_ci /* if everything goes well, we override the fuzz to 0 */ 859a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->fuzz, 0); 860a46c0ec8Sopenharmony_ci 861a46c0ec8Sopenharmony_ci abs = libevdev_get_abs_info(evdev, ABS_Y); 862a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->minimum, 2); 863a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->maximum, 2000); 864a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->resolution, 200); 865a46c0ec8Sopenharmony_ci /* if everything goes well, we override the fuzz to 0 */ 866a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->fuzz, 0); 867a46c0ec8Sopenharmony_ci 868a46c0ec8Sopenharmony_ci abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X); 869a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->minimum, 3); 870a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->maximum, 3000); 871a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->resolution, 300); 872a46c0ec8Sopenharmony_ci /* if everything goes well, we override the fuzz to 0 */ 873a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->fuzz, 0); 874a46c0ec8Sopenharmony_ci 875a46c0ec8Sopenharmony_ci abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_Y); 876a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->minimum, 4); 877a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->maximum, 4000); 878a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->resolution, 400); 879a46c0ec8Sopenharmony_ci /* if everything goes well, we override the fuzz to 0 */ 880a46c0ec8Sopenharmony_ci ck_assert_int_eq(abs->fuzz, 0); 881a46c0ec8Sopenharmony_ci} 882a46c0ec8Sopenharmony_ciEND_TEST 883a46c0ec8Sopenharmony_ci 884a46c0ec8Sopenharmony_ciTEST_COLLECTION(misc) 885a46c0ec8Sopenharmony_ci{ 886a46c0ec8Sopenharmony_ci litest_add_no_device(event_conversion_device_notify); 887a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_pointer, LITEST_MOUSE); 888a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_pointer_abs, LITEST_XEN_VIRTUAL_POINTER); 889a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_key, LITEST_KEYBOARD); 890a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_touch, LITEST_WACOM_TOUCH); 891a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_gesture, LITEST_BCM5974); 892a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_tablet, LITEST_WACOM_CINTIQ); 893a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_tablet_pad, LITEST_WACOM_INTUOS5_PAD); 894a46c0ec8Sopenharmony_ci litest_add_for_device(event_conversion_switch, LITEST_LID_SWITCH); 895a46c0ec8Sopenharmony_ci 896a46c0ec8Sopenharmony_ci litest_add_deviceless(context_ref_counting); 897a46c0ec8Sopenharmony_ci litest_add_deviceless(config_status_string); 898a46c0ec8Sopenharmony_ci 899a46c0ec8Sopenharmony_ci litest_add_for_device(timer_offset_bug_warning, LITEST_SYNAPTICS_TOUCHPAD); 900a46c0ec8Sopenharmony_ci litest_add_for_device(timer_delay_bug_warning, LITEST_MOUSE); 901a46c0ec8Sopenharmony_ci litest_add_no_device(timer_flush); 902a46c0ec8Sopenharmony_ci 903a46c0ec8Sopenharmony_ci litest_add_no_device(fd_no_event_leak); 904a46c0ec8Sopenharmony_ci 905a46c0ec8Sopenharmony_ci litest_add_for_device(udev_absinfo_override, LITEST_ABSINFO_OVERRIDE); 906a46c0ec8Sopenharmony_ci} 907