1
0

test-keyboard.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /*
  2. * Copyright © 2014 Jonas Ådahl <jadahl@gmail.com>
  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 <stdio.h>
  25. #include "libinput-util.h"
  26. #include "litest.h"
  27. START_TEST(keyboard_seat_key_count)
  28. {
  29. struct litest_device *devices[4];
  30. const int num_devices = ARRAY_LENGTH(devices);
  31. struct libinput_event *ev;
  32. struct libinput_event_keyboard *kev;
  33. int i;
  34. int seat_key_count = 0;
  35. int expected_key_button_count = 0;
  36. char device_name[255];
  37. _litest_context_destroy_ struct libinput *libinput = litest_create_context();
  38. for (i = 0; i < num_devices; ++i) {
  39. sprintf(device_name, "litest Generic keyboard (%d)", i);
  40. devices[i] = litest_add_device_with_overrides(libinput,
  41. LITEST_KEYBOARD,
  42. device_name,
  43. NULL,
  44. NULL,
  45. NULL);
  46. }
  47. litest_drain_events(libinput);
  48. for (i = 0; i < num_devices; ++i)
  49. litest_keyboard_key(devices[i], KEY_A, true);
  50. litest_dispatch(libinput);
  51. while ((ev = libinput_get_event(libinput))) {
  52. kev = litest_is_keyboard_event(ev, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
  53. ++expected_key_button_count;
  54. seat_key_count = libinput_event_keyboard_get_seat_key_count(kev);
  55. litest_assert_int_eq(expected_key_button_count, seat_key_count);
  56. libinput_event_destroy(ev);
  57. litest_dispatch(libinput);
  58. }
  59. litest_assert_int_eq(seat_key_count, num_devices);
  60. for (i = 0; i < num_devices; ++i)
  61. litest_keyboard_key(devices[i], KEY_A, false);
  62. litest_dispatch(libinput);
  63. while ((ev = libinput_get_event(libinput))) {
  64. kev = libinput_event_get_keyboard_event(ev);
  65. litest_assert_notnull(kev);
  66. litest_assert_int_eq(libinput_event_keyboard_get_key(kev),
  67. (unsigned int)KEY_A);
  68. litest_assert_enum_eq(libinput_event_keyboard_get_key_state(kev),
  69. LIBINPUT_KEY_STATE_RELEASED);
  70. --expected_key_button_count;
  71. seat_key_count = libinput_event_keyboard_get_seat_key_count(kev);
  72. litest_assert_int_eq(expected_key_button_count, seat_key_count);
  73. libinput_event_destroy(ev);
  74. litest_dispatch(libinput);
  75. }
  76. litest_assert_int_eq(seat_key_count, 0);
  77. for (i = 0; i < num_devices; ++i)
  78. litest_device_destroy(devices[i]);
  79. }
  80. END_TEST
  81. START_TEST(keyboard_ignore_no_pressed_release)
  82. {
  83. struct litest_device *dev;
  84. struct libinput_event *event;
  85. struct libinput_event_keyboard *kevent;
  86. int events[] = {
  87. EV_KEY,
  88. KEY_A,
  89. -1,
  90. -1,
  91. };
  92. enum libinput_key_state expected_states[] = {
  93. LIBINPUT_KEY_STATE_PRESSED,
  94. LIBINPUT_KEY_STATE_RELEASED,
  95. };
  96. /* We can't send pressed -> released -> pressed events using uinput
  97. * as such non-symmetric events are dropped. Work-around this by first
  98. * adding the test device to the tested context after having sent an
  99. * initial pressed event. */
  100. _litest_context_destroy_ struct libinput *unused_libinput =
  101. litest_create_context();
  102. dev = litest_add_device_with_overrides(unused_libinput,
  103. LITEST_KEYBOARD,
  104. "Generic keyboard",
  105. NULL,
  106. NULL,
  107. events);
  108. litest_keyboard_key(dev, KEY_A, true);
  109. litest_drain_events(unused_libinput);
  110. _litest_context_destroy_ struct libinput *libinput = litest_create_context();
  111. libinput_path_add_device(libinput, libevdev_uinput_get_devnode(dev->uinput));
  112. litest_drain_events(libinput);
  113. litest_keyboard_key(dev, KEY_A, false);
  114. litest_keyboard_key(dev, KEY_A, true);
  115. litest_keyboard_key(dev, KEY_A, false);
  116. litest_dispatch(libinput);
  117. ARRAY_FOR_EACH(expected_states, state) {
  118. event = libinput_get_event(libinput);
  119. litest_assert_notnull(event);
  120. litest_assert_event_type(event, LIBINPUT_EVENT_KEYBOARD_KEY);
  121. kevent = libinput_event_get_keyboard_event(event);
  122. litest_assert_int_eq(libinput_event_keyboard_get_key(kevent),
  123. (unsigned int)KEY_A);
  124. litest_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
  125. *state);
  126. libinput_event_destroy(event);
  127. litest_dispatch(libinput);
  128. }
  129. litest_assert_empty_queue(libinput);
  130. litest_device_destroy(dev);
  131. }
  132. END_TEST
  133. START_TEST(keyboard_key_auto_release)
  134. {
  135. struct litest_device *dev;
  136. struct libinput_event *event;
  137. enum libinput_event_type type;
  138. struct libinput_event_keyboard *kevent;
  139. struct {
  140. int code;
  141. int released;
  142. } keys[] = {
  143. {
  144. .code = KEY_A,
  145. },
  146. {
  147. .code = KEY_S,
  148. },
  149. {
  150. .code = KEY_D,
  151. },
  152. {
  153. .code = KEY_G,
  154. },
  155. {
  156. .code = KEY_Z,
  157. },
  158. {
  159. .code = KEY_DELETE,
  160. },
  161. {
  162. .code = KEY_F24,
  163. },
  164. };
  165. int events[2 * (ARRAY_LENGTH(keys) + 1)];
  166. unsigned i;
  167. int key;
  168. int valid_code;
  169. /* Enable all tested keys on the device */
  170. i = 0;
  171. while (i < 2 * ARRAY_LENGTH(keys)) {
  172. key = keys[i / 2].code;
  173. events[i++] = EV_KEY;
  174. events[i++] = key;
  175. }
  176. events[i++] = -1;
  177. events[i++] = -1;
  178. _litest_context_destroy_ struct libinput *libinput = litest_create_context();
  179. dev = litest_add_device_with_overrides(libinput,
  180. LITEST_KEYBOARD,
  181. "Generic keyboard",
  182. NULL,
  183. NULL,
  184. events);
  185. litest_drain_events(libinput);
  186. /* Send pressed events, without releasing */
  187. for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
  188. key = keys[i].code;
  189. litest_event(dev, EV_KEY, key, 1);
  190. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  191. litest_dispatch(libinput);
  192. event = libinput_get_event(libinput);
  193. litest_is_keyboard_event(event, key, LIBINPUT_KEY_STATE_PRESSED);
  194. libinput_event_destroy(event);
  195. }
  196. litest_drain_events(libinput);
  197. /* "Disconnect" device */
  198. litest_device_destroy(dev);
  199. /* Mark all released keys until device is removed */
  200. while (1) {
  201. event = libinput_get_event(libinput);
  202. litest_assert_notnull(event);
  203. type = libinput_event_get_type(event);
  204. if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
  205. libinput_event_destroy(event);
  206. break;
  207. }
  208. litest_assert_event_type(event, LIBINPUT_EVENT_KEYBOARD_KEY);
  209. kevent = libinput_event_get_keyboard_event(event);
  210. litest_assert_enum_eq(libinput_event_keyboard_get_key_state(kevent),
  211. LIBINPUT_KEY_STATE_RELEASED);
  212. key = libinput_event_keyboard_get_key(kevent);
  213. valid_code = 0;
  214. for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
  215. if (keys[i].code == key) {
  216. litest_assert_int_eq(keys[i].released, 0);
  217. keys[i].released = 1;
  218. valid_code = 1;
  219. }
  220. }
  221. litest_assert_int_eq(valid_code, 1);
  222. libinput_event_destroy(event);
  223. }
  224. /* Check that all pressed keys has been released. */
  225. for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
  226. litest_assert_int_eq(keys[i].released, 1);
  227. }
  228. }
  229. END_TEST
  230. START_TEST(keyboard_has_key)
  231. {
  232. struct litest_device *dev = litest_current_device();
  233. struct libinput_device *device = dev->libinput_device;
  234. unsigned int code;
  235. int evdev_has, libinput_has;
  236. litest_assert(
  237. libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD));
  238. for (code = 0; code < KEY_CNT; code++) {
  239. evdev_has = libevdev_has_event_code(dev->evdev, EV_KEY, code);
  240. libinput_has = libinput_device_keyboard_has_key(device, code);
  241. litest_assert_int_eq(evdev_has, libinput_has);
  242. }
  243. }
  244. END_TEST
  245. START_TEST(keyboard_keys_bad_device)
  246. {
  247. struct litest_device *dev = litest_current_device();
  248. struct libinput_device *device = dev->libinput_device;
  249. unsigned int code;
  250. int has_key;
  251. if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD))
  252. return LITEST_NOT_APPLICABLE;
  253. for (code = 0; code < KEY_CNT; code++) {
  254. has_key = libinput_device_keyboard_has_key(device, code);
  255. litest_assert_int_eq(has_key, -1);
  256. }
  257. }
  258. END_TEST
  259. START_TEST(keyboard_time_usec)
  260. {
  261. struct litest_device *dev = litest_current_device();
  262. struct libinput *li = dev->libinput;
  263. struct libinput_event_keyboard *kev;
  264. struct libinput_event *event;
  265. uint64_t time_usec;
  266. if (!libevdev_has_event_code(dev->evdev, EV_KEY, KEY_A))
  267. return LITEST_NOT_APPLICABLE;
  268. litest_drain_events(dev->libinput);
  269. litest_keyboard_key(dev, KEY_A, true);
  270. litest_dispatch(li);
  271. event = libinput_get_event(li);
  272. kev = litest_is_keyboard_event(event, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
  273. time_usec = libinput_event_keyboard_get_time_usec(kev);
  274. litest_assert_int_eq(libinput_event_keyboard_get_time(kev),
  275. (uint32_t)(time_usec / 1000));
  276. libinput_event_destroy(event);
  277. litest_drain_events(dev->libinput);
  278. }
  279. END_TEST
  280. START_TEST(keyboard_no_buttons)
  281. {
  282. struct litest_device *dev = litest_current_device();
  283. struct libinput *li = dev->libinput;
  284. struct libinput_event *event;
  285. int code;
  286. const char *name;
  287. litest_drain_events(dev->libinput);
  288. for (code = 0; code < KEY_MAX; code++) {
  289. if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
  290. continue;
  291. name = libevdev_event_code_get_name(EV_KEY, code);
  292. if (!strstartswith(name, "KEY_"))
  293. continue;
  294. litest_keyboard_key(dev, code, true);
  295. litest_keyboard_key(dev, code, false);
  296. litest_dispatch(li);
  297. event = libinput_get_event(li);
  298. litest_is_keyboard_event(event, code, LIBINPUT_KEY_STATE_PRESSED);
  299. libinput_event_destroy(event);
  300. event = libinput_get_event(li);
  301. litest_is_keyboard_event(event, code, LIBINPUT_KEY_STATE_RELEASED);
  302. libinput_event_destroy(event);
  303. }
  304. }
  305. END_TEST
  306. START_TEST(keyboard_frame_order)
  307. {
  308. struct litest_device *dev = litest_current_device();
  309. struct libinput *li = dev->libinput;
  310. if (!libevdev_has_event_code(dev->evdev, EV_KEY, KEY_A) ||
  311. !libevdev_has_event_code(dev->evdev, EV_KEY, KEY_LEFTSHIFT))
  312. return LITEST_NOT_APPLICABLE;
  313. litest_drain_events(li);
  314. litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 1);
  315. litest_event(dev, EV_KEY, KEY_A, 1);
  316. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  317. litest_dispatch(li);
  318. litest_assert_key_event(li, KEY_LEFTSHIFT, LIBINPUT_KEY_STATE_PRESSED);
  319. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
  320. litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 0);
  321. litest_event(dev, EV_KEY, KEY_A, 0);
  322. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  323. litest_dispatch(li);
  324. litest_assert_key_event(li, KEY_LEFTSHIFT, LIBINPUT_KEY_STATE_RELEASED);
  325. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
  326. litest_event(dev, EV_KEY, KEY_A, 1);
  327. litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 1);
  328. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  329. litest_dispatch(li);
  330. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
  331. litest_assert_key_event(li, KEY_LEFTSHIFT, LIBINPUT_KEY_STATE_PRESSED);
  332. litest_event(dev, EV_KEY, KEY_A, 0);
  333. litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 0);
  334. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  335. litest_dispatch(li);
  336. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
  337. litest_assert_key_event(li, KEY_LEFTSHIFT, LIBINPUT_KEY_STATE_RELEASED);
  338. litest_dispatch(li);
  339. }
  340. END_TEST
  341. START_TEST(keyboard_leds)
  342. {
  343. struct litest_device *dev = litest_current_device();
  344. struct libinput_device *device = dev->libinput_device;
  345. /* we can't actually test the results here without physically
  346. * looking at the LEDs. So all we do is trigger the code for devices
  347. * with and without LEDs and check that it doesn't go boom
  348. */
  349. libinput_device_led_update(device, LIBINPUT_LED_NUM_LOCK);
  350. libinput_device_led_update(device, LIBINPUT_LED_CAPS_LOCK);
  351. libinput_device_led_update(device, LIBINPUT_LED_SCROLL_LOCK);
  352. libinput_device_led_update(device, LIBINPUT_LED_COMPOSE);
  353. libinput_device_led_update(device, LIBINPUT_LED_KANA);
  354. libinput_device_led_update(device,
  355. LIBINPUT_LED_NUM_LOCK | LIBINPUT_LED_CAPS_LOCK);
  356. libinput_device_led_update(device,
  357. LIBINPUT_LED_NUM_LOCK | LIBINPUT_LED_CAPS_LOCK |
  358. LIBINPUT_LED_SCROLL_LOCK);
  359. libinput_device_led_update(device,
  360. LIBINPUT_LED_NUM_LOCK | LIBINPUT_LED_CAPS_LOCK |
  361. LIBINPUT_LED_SCROLL_LOCK |
  362. LIBINPUT_LED_COMPOSE | LIBINPUT_LED_KANA);
  363. libinput_device_led_update(device, 0);
  364. libinput_device_led_update(device, -1);
  365. }
  366. END_TEST
  367. START_TEST(keyboard_no_scroll)
  368. {
  369. struct litest_device *dev = litest_current_device();
  370. struct libinput_device *device = dev->libinput_device;
  371. enum libinput_config_scroll_method method;
  372. enum libinput_config_status status;
  373. method = libinput_device_config_scroll_get_method(device);
  374. litest_assert_enum_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
  375. method = libinput_device_config_scroll_get_default_method(device);
  376. litest_assert_enum_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
  377. status = libinput_device_config_scroll_set_method(device,
  378. LIBINPUT_CONFIG_SCROLL_2FG);
  379. litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
  380. status = libinput_device_config_scroll_set_method(device,
  381. LIBINPUT_CONFIG_SCROLL_EDGE);
  382. litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
  383. status = libinput_device_config_scroll_set_method(
  384. device,
  385. LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
  386. litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
  387. status = libinput_device_config_scroll_set_method(
  388. device,
  389. LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
  390. litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
  391. }
  392. END_TEST
  393. START_TEST(keyboard_alt_printscreen)
  394. {
  395. struct litest_device *dev = litest_current_device();
  396. struct libinput *li = dev->libinput;
  397. litest_drain_events(li);
  398. /* normal key press, not ignored */
  399. litest_event(dev, EV_KEY, KEY_LEFTALT, 1);
  400. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  401. litest_dispatch(li);
  402. litest_assert_key_event(li, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
  403. /* normal key repeat, ignored */
  404. litest_event(dev, EV_KEY, KEY_LEFTALT, 2);
  405. litest_event(dev, EV_SYN, SYN_REPORT, 1);
  406. litest_dispatch(li);
  407. litest_assert_empty_queue(li);
  408. /* not a repeat, not ignored */
  409. litest_event(dev, EV_KEY, KEY_LEFTALT, 0);
  410. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  411. litest_dispatch(li);
  412. litest_assert_key_event(li, KEY_LEFTALT, LIBINPUT_KEY_STATE_RELEASED);
  413. litest_assert_empty_queue(li);
  414. /* special alt+printscreen frame, *not* ignored */
  415. litest_event(dev, EV_KEY, KEY_LEFTALT, 1);
  416. litest_event(dev, EV_KEY, KEY_SYSRQ, 1);
  417. litest_event(dev, EV_SYN, SYN_REPORT, 1);
  418. litest_dispatch(li);
  419. /* special alt+printscreen frame, *not* ignored */
  420. litest_event(dev, EV_KEY, KEY_LEFTALT, 0);
  421. litest_event(dev, EV_KEY, KEY_SYSRQ, 0);
  422. litest_event(dev, EV_SYN, SYN_REPORT, 1);
  423. litest_dispatch(li);
  424. /* Note: The kernel first releases KEY_LEFTALT when pressing KEY_SYSRQ,
  425. * then later generates press/release for KEY_LEFTALT + KEY_SYSRQ
  426. * once *both* keys are released. The order is reshuffled so we have
  427. * alt down, sysrq down, sysrq up, alt up.
  428. */
  429. litest_assert_key_event(li, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
  430. litest_assert_key_event(li, KEY_LEFTALT, LIBINPUT_KEY_STATE_RELEASED);
  431. litest_assert_key_event(li, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
  432. litest_assert_key_event(li, KEY_SYSRQ, LIBINPUT_KEY_STATE_PRESSED);
  433. litest_assert_key_event(li, KEY_SYSRQ, LIBINPUT_KEY_STATE_RELEASED);
  434. litest_assert_key_event(li, KEY_LEFTALT, LIBINPUT_KEY_STATE_RELEASED);
  435. litest_assert_empty_queue(li);
  436. }
  437. END_TEST
  438. START_TEST(keyboard_keycode_obfuscation)
  439. {
  440. #ifdef EVENT_DEBUGGING
  441. struct litest_device *dev = litest_current_device();
  442. struct libinput *li = dev->libinput;
  443. litest_drain_events(li);
  444. litest_with_logcapture(li, capture) {
  445. litest_event(dev, EV_KEY, KEY_Q, 1);
  446. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  447. litest_event(dev, EV_KEY, KEY_Q, 0);
  448. litest_event(dev, EV_SYN, SYN_REPORT, 0);
  449. litest_dispatch(li);
  450. litest_drain_events(li);
  451. /* clang-format off */
  452. /* We get two possible debug messages:
  453. * Queuing event14 KEYBOARD_KEY +0.000s KEY_Q (16) released
  454. * event14: plugin evdev - 0.000 EV_KEY KEY_Q 0
  455. *
  456. * Both KEY_Q must be obfuscated to KEY_A
  457. */
  458. /* clang-format on */
  459. char **strv = capture->debugs;
  460. litest_assert_strv_no_substring(strv, "KEY_Q");
  461. strv = capture->debugs;
  462. size_t index;
  463. litest_assert(strv_find_substring(strv, "KEY_A", &index));
  464. do {
  465. litest_assert_str_in("EV_KEY", strv[index]);
  466. strv += index + 1;
  467. } while (strv_find_substring(strv, "KEY_A", &index));
  468. }
  469. #else
  470. return LITEST_SKIP;
  471. #endif
  472. }
  473. END_TEST
  474. START_TEST(keyboard_nkey_rollover)
  475. {
  476. struct litest_device *dev = litest_current_device();
  477. struct libinput *li = dev->libinput;
  478. int nkeys = litest_test_param_get_i32(test_env->params, "nkeys");
  479. litest_drain_events(li);
  480. /* The kernel allocates a 7 + 1 buffer for devices without EV_ABS and
  481. * EV_REL, see
  482. * drivers/input/input.c:input_estimate_events_per_packet()
  483. *
  484. * If the device exceeds that buffer the current set is flushed out
  485. * as SYN_REPORT 1 followed by (if any) the remaining events immediately
  486. * after.
  487. *
  488. * Either way, we expect n keys to arrive, regardless what the kernel
  489. * does.
  490. */
  491. for (int i = 0; i < nkeys; i++) {
  492. litest_event_unchecked(dev, EV_KEY, KEY_A + i, 1);
  493. litest_event_unchecked(dev, EV_MSC, MSC_SCAN, 0x1000 + i);
  494. }
  495. litest_event_unchecked(dev, EV_SYN, SYN_REPORT, 0);
  496. for (int i = 0; i < nkeys; i++) {
  497. litest_event_unchecked(dev, EV_KEY, KEY_A + i, 0);
  498. litest_event_unchecked(dev, EV_MSC, MSC_SCAN, 0x1000 + i);
  499. }
  500. litest_event_unchecked(dev, EV_SYN, SYN_REPORT, 0);
  501. litest_dispatch(li);
  502. for (int i = 0; i < nkeys; i++) {
  503. litest_checkpoint("here for %d", i);
  504. litest_assert_key_event(li, KEY_A + i, LIBINPUT_KEY_STATE_PRESSED);
  505. }
  506. for (int i = 0; i < nkeys; i++) {
  507. litest_assert_key_event(li, KEY_A + i, LIBINPUT_KEY_STATE_RELEASED);
  508. }
  509. litest_assert_empty_queue(li);
  510. }
  511. END_TEST
  512. TEST_COLLECTION(keyboard)
  513. {
  514. /* clang-format off */
  515. litest_add_no_device(keyboard_seat_key_count);
  516. litest_add_no_device(keyboard_ignore_no_pressed_release);
  517. litest_add_no_device(keyboard_key_auto_release);
  518. litest_add(keyboard_has_key, LITEST_KEYS, LITEST_ANY);
  519. litest_add(keyboard_keys_bad_device, LITEST_ANY, LITEST_ANY);
  520. litest_add(keyboard_time_usec, LITEST_KEYS, LITEST_ANY);
  521. litest_add(keyboard_no_buttons, LITEST_KEYS, LITEST_ANY);
  522. litest_add(keyboard_frame_order, LITEST_KEYS, LITEST_ANY);
  523. litest_add(keyboard_leds, LITEST_ANY, LITEST_ANY);
  524. litest_add(keyboard_no_scroll, LITEST_KEYS, LITEST_WHEEL);
  525. litest_add_for_device(keyboard_alt_printscreen, LITEST_KEYBOARD);
  526. litest_add_for_device(keyboard_keycode_obfuscation, LITEST_KEYBOARD);
  527. /* Adding for one device only to be able to hardcode buffer sizes */
  528. litest_with_parameters(params, "nkeys", 'i', 4, 3, 4, 5, 6)
  529. litest_add_parametrized_for_device(keyboard_nkey_rollover, LITEST_KEYBOARD, params);
  530. /* clang-format on */
  531. }