1
0

test-misc.c 27 KB

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