1
0

test-switch.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  1. /*
  2. * Copyright © 2017 James Ye <jye836@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 <fcntl.h>
  25. #include <libevdev/libevdev.h>
  26. #include <libinput.h>
  27. #include "libinput-util.h"
  28. #include "litest.h"
  29. static inline bool
  30. switch_has_lid(struct litest_device *dev)
  31. {
  32. return libinput_device_switch_has_switch(dev->libinput_device,
  33. LIBINPUT_SWITCH_LID) > 0;
  34. }
  35. static inline bool
  36. switch_has_tablet_mode(struct litest_device *dev)
  37. {
  38. return libinput_device_switch_has_switch(dev->libinput_device,
  39. LIBINPUT_SWITCH_TABLET_MODE) > 0;
  40. }
  41. START_TEST(switch_has_cap)
  42. {
  43. struct litest_device *dev = litest_current_device();
  44. /* Need to check for this specific device here because the
  45. * unreliable tablet mode switch removes the capability too */
  46. if (dev->which == LITEST_TABLET_MODE_UNRELIABLE) {
  47. litest_assert(
  48. !libinput_device_has_capability(dev->libinput_device,
  49. LIBINPUT_DEVICE_CAP_SWITCH));
  50. return LITEST_NOT_APPLICABLE;
  51. }
  52. litest_assert(libinput_device_has_capability(dev->libinput_device,
  53. LIBINPUT_DEVICE_CAP_SWITCH));
  54. }
  55. END_TEST
  56. START_TEST(switch_has_lid_switch)
  57. {
  58. struct litest_device *dev = litest_current_device();
  59. if (!libevdev_has_event_code(dev->evdev, EV_SW, SW_LID))
  60. return LITEST_NOT_APPLICABLE;
  61. litest_assert_int_eq(libinput_device_switch_has_switch(dev->libinput_device,
  62. LIBINPUT_SWITCH_LID),
  63. 1);
  64. }
  65. END_TEST
  66. static bool
  67. tablet_mode_switch_is_reliable(struct litest_device *dev)
  68. {
  69. bool is_unreliable = false;
  70. quirks_get_bool(dev->quirks,
  71. QUIRK_MODEL_TABLET_MODE_SWITCH_UNRELIABLE,
  72. &is_unreliable);
  73. return !is_unreliable;
  74. }
  75. START_TEST(switch_has_tablet_mode_switch)
  76. {
  77. struct litest_device *dev = litest_current_device();
  78. int has_switch;
  79. if (!libevdev_has_event_code(dev->evdev, EV_SW, SW_TABLET_MODE))
  80. return LITEST_NOT_APPLICABLE;
  81. has_switch = libinput_device_switch_has_switch(dev->libinput_device,
  82. LIBINPUT_SWITCH_TABLET_MODE);
  83. if (!tablet_mode_switch_is_reliable(dev))
  84. litest_assert_int_ne(has_switch, 1);
  85. else
  86. litest_assert_int_eq(has_switch, 1);
  87. }
  88. END_TEST
  89. START_TEST(switch_has_keypad_slide_switch)
  90. {
  91. struct litest_device *dev = litest_current_device();
  92. if (!libevdev_has_event_code(dev->evdev, EV_SW, SW_KEYPAD_SLIDE))
  93. return LITEST_NOT_APPLICABLE;
  94. litest_assert_int_eq(
  95. libinput_device_switch_has_switch(dev->libinput_device,
  96. LIBINPUT_SWITCH_KEYPAD_SLIDE),
  97. 1);
  98. }
  99. END_TEST
  100. START_TEST(switch_toggle)
  101. {
  102. struct litest_device *dev = litest_current_device();
  103. struct libinput *li = dev->libinput;
  104. struct libinput_event *event;
  105. enum libinput_switch sw = litest_test_param_get_i32(test_env->params, "switch");
  106. litest_drain_events(li);
  107. litest_grab_device(dev);
  108. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
  109. litest_dispatch(li);
  110. if (libinput_device_switch_has_switch(dev->libinput_device, sw) > 0) {
  111. event = libinput_get_event(li);
  112. litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON);
  113. libinput_event_destroy(event);
  114. } else {
  115. litest_assert_empty_queue(li);
  116. }
  117. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF);
  118. litest_dispatch(li);
  119. if (libinput_device_switch_has_switch(dev->libinput_device, sw) > 0) {
  120. event = libinput_get_event(li);
  121. litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_OFF);
  122. libinput_event_destroy(event);
  123. }
  124. litest_assert_empty_queue(li);
  125. litest_ungrab_device(dev);
  126. }
  127. END_TEST
  128. START_TEST(switch_toggle_double)
  129. {
  130. struct litest_device *dev = litest_current_device();
  131. struct libinput *li = dev->libinput;
  132. struct libinput_event *event;
  133. enum libinput_switch sw = litest_test_param_get_i32(test_env->params, "switch");
  134. if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0)
  135. return LITEST_NOT_APPLICABLE;
  136. litest_drain_events(li);
  137. litest_grab_device(dev);
  138. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
  139. litest_dispatch(li);
  140. event = libinput_get_event(li);
  141. litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON);
  142. libinput_event_destroy(event);
  143. /* This will be filtered by the kernel, so this test is a bit
  144. * useless */
  145. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
  146. litest_dispatch(li);
  147. litest_assert_empty_queue(li);
  148. litest_ungrab_device(dev);
  149. }
  150. END_TEST
  151. static bool
  152. lid_switch_is_reliable(struct litest_device *dev)
  153. {
  154. char *prop;
  155. bool is_reliable = false;
  156. if (quirks_get_string(dev->quirks, QUIRK_ATTR_LID_SWITCH_RELIABILITY, &prop)) {
  157. is_reliable = streq(prop, "reliable");
  158. }
  159. return is_reliable;
  160. }
  161. START_TEST(switch_down_on_init)
  162. {
  163. struct litest_device *dev = litest_current_device();
  164. struct libinput_event *event;
  165. enum libinput_switch sw = litest_test_param_get_i32(test_env->params, "switch");
  166. if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0)
  167. return LITEST_NOT_APPLICABLE;
  168. if (sw == LIBINPUT_SWITCH_LID && !lid_switch_is_reliable(dev))
  169. return LITEST_NOT_APPLICABLE;
  170. litest_grab_device(dev);
  171. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
  172. litest_ungrab_device(dev);
  173. /* need separate context to test */
  174. _litest_context_destroy_ struct libinput *li = litest_create_context();
  175. libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
  176. litest_dispatch(li);
  177. litest_wait_for_event_of_type(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  178. event = libinput_get_event(li);
  179. litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON);
  180. libinput_event_destroy(event);
  181. while ((event = libinput_get_event(li))) {
  182. litest_assert_enum_ne(libinput_event_get_type(event),
  183. LIBINPUT_EVENT_SWITCH_TOGGLE);
  184. libinput_event_destroy(event);
  185. }
  186. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF);
  187. litest_dispatch(li);
  188. event = libinput_get_event(li);
  189. litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_OFF);
  190. libinput_event_destroy(event);
  191. litest_assert_empty_queue(li);
  192. }
  193. END_TEST
  194. START_TEST(switch_not_down_on_init)
  195. {
  196. struct litest_device *dev = litest_current_device();
  197. struct libinput_event *event;
  198. enum libinput_switch sw = LIBINPUT_SWITCH_LID;
  199. if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0)
  200. return LITEST_NOT_APPLICABLE;
  201. if (sw == LIBINPUT_SWITCH_LID && lid_switch_is_reliable(dev))
  202. return LITEST_NOT_APPLICABLE;
  203. litest_grab_device(dev);
  204. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
  205. litest_ungrab_device(dev);
  206. /* need separate context to test */
  207. _litest_context_destroy_ struct libinput *li = litest_create_context();
  208. libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
  209. litest_dispatch(li);
  210. while ((event = libinput_get_event(li)) != NULL) {
  211. litest_assert_enum_ne(libinput_event_get_type(event),
  212. LIBINPUT_EVENT_SWITCH_TOGGLE);
  213. libinput_event_destroy(event);
  214. }
  215. litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF);
  216. litest_assert_empty_queue(li);
  217. }
  218. END_TEST
  219. static inline struct litest_device *
  220. switch_init_paired_touchpad(struct libinput *li)
  221. {
  222. enum litest_device_type which = LITEST_SYNAPTICS_I2C;
  223. return litest_add_device(li, which);
  224. }
  225. START_TEST(switch_disable_touchpad)
  226. {
  227. struct litest_device *sw = litest_current_device();
  228. struct litest_device *touchpad;
  229. struct libinput *li = sw->libinput;
  230. enum libinput_switch which =
  231. litest_test_param_get_i32(test_env->params, "switch");
  232. if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
  233. return LITEST_NOT_APPLICABLE;
  234. touchpad = switch_init_paired_touchpad(li);
  235. litest_disable_tap(touchpad->libinput_device);
  236. litest_disable_hold_gestures(touchpad->libinput_device);
  237. litest_drain_events(li);
  238. litest_grab_device(sw);
  239. /* switch is on - no events */
  240. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  241. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  242. litest_touch_down(touchpad, 0, 50, 50);
  243. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  244. litest_touch_up(touchpad, 0);
  245. litest_assert_empty_queue(li);
  246. /* switch is off - motion events */
  247. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
  248. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  249. litest_touch_down(touchpad, 0, 50, 50);
  250. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  251. litest_touch_up(touchpad, 0);
  252. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  253. litest_device_destroy(touchpad);
  254. litest_ungrab_device(sw);
  255. }
  256. END_TEST
  257. START_TEST(switch_disable_touchpad_during_touch)
  258. {
  259. struct litest_device *sw = litest_current_device();
  260. struct litest_device *touchpad;
  261. struct libinput *li = sw->libinput;
  262. enum libinput_switch which =
  263. litest_test_param_get_i32(test_env->params, "switch");
  264. if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
  265. return LITEST_NOT_APPLICABLE;
  266. touchpad = switch_init_paired_touchpad(li);
  267. litest_disable_tap(touchpad->libinput_device);
  268. litest_disable_hold_gestures(touchpad->libinput_device);
  269. litest_drain_events(li);
  270. litest_touch_down(touchpad, 0, 50, 50);
  271. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5);
  272. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  273. litest_grab_device(sw);
  274. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  275. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  276. litest_ungrab_device(sw);
  277. litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 5);
  278. litest_touch_up(touchpad, 0);
  279. litest_assert_empty_queue(li);
  280. litest_device_destroy(touchpad);
  281. }
  282. END_TEST
  283. START_TEST(switch_disable_touchpad_edge_scroll)
  284. {
  285. struct litest_device *sw = litest_current_device();
  286. struct litest_device *touchpad;
  287. struct libinput *li = sw->libinput;
  288. enum libinput_switch which =
  289. litest_test_param_get_i32(test_env->params, "switch");
  290. if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
  291. return LITEST_NOT_APPLICABLE;
  292. touchpad = switch_init_paired_touchpad(li);
  293. litest_enable_edge_scroll(touchpad);
  294. litest_drain_events(li);
  295. litest_grab_device(sw);
  296. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  297. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  298. litest_ungrab_device(sw);
  299. litest_touch_down(touchpad, 0, 99, 20);
  300. litest_dispatch(li);
  301. litest_timeout_edgescroll(li);
  302. litest_dispatch(li);
  303. litest_assert_empty_queue(li);
  304. litest_touch_move_to(touchpad, 0, 99, 20, 99, 80, 60);
  305. litest_dispatch(li);
  306. litest_assert_empty_queue(li);
  307. litest_touch_move_to(touchpad, 0, 99, 80, 99, 20, 60);
  308. litest_touch_up(touchpad, 0);
  309. litest_dispatch(li);
  310. litest_assert_empty_queue(li);
  311. litest_device_destroy(touchpad);
  312. }
  313. END_TEST
  314. START_TEST(switch_disable_touchpad_edge_scroll_interrupt)
  315. {
  316. struct litest_device *sw = litest_current_device();
  317. struct litest_device *touchpad;
  318. struct libinput *li = sw->libinput;
  319. struct libinput_event *event;
  320. enum libinput_switch which =
  321. litest_test_param_get_i32(test_env->params, "switch");
  322. if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
  323. return LITEST_NOT_APPLICABLE;
  324. touchpad = switch_init_paired_touchpad(li);
  325. litest_enable_edge_scroll(touchpad);
  326. litest_drain_events(li);
  327. litest_touch_down(touchpad, 0, 99, 20);
  328. litest_dispatch(li);
  329. litest_timeout_edgescroll(li);
  330. litest_touch_move_to(touchpad, 0, 99, 20, 99, 30, 10);
  331. litest_dispatch(li);
  332. litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
  333. litest_grab_device(sw);
  334. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  335. litest_ungrab_device(sw);
  336. litest_dispatch(li);
  337. litest_assert_axis_end_sequence(li,
  338. LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
  339. LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
  340. LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
  341. event = libinput_get_event(li);
  342. litest_is_switch_event(event, which, LIBINPUT_SWITCH_STATE_ON);
  343. libinput_event_destroy(event);
  344. litest_device_destroy(touchpad);
  345. }
  346. END_TEST
  347. START_TEST(switch_disable_touchpad_already_open)
  348. {
  349. struct litest_device *sw = litest_current_device();
  350. struct litest_device *touchpad;
  351. struct libinput *li = sw->libinput;
  352. enum libinput_switch which =
  353. litest_test_param_get_i32(test_env->params, "switch");
  354. if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
  355. return LITEST_NOT_APPLICABLE;
  356. touchpad = switch_init_paired_touchpad(li);
  357. litest_disable_tap(touchpad->libinput_device);
  358. litest_disable_hold_gestures(touchpad->libinput_device);
  359. litest_drain_events(li);
  360. /* default: switch is off - motion events */
  361. litest_touch_down(touchpad, 0, 50, 50);
  362. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  363. litest_touch_up(touchpad, 0);
  364. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  365. /* disable switch - motion events */
  366. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
  367. litest_assert_empty_queue(li);
  368. litest_touch_down(touchpad, 0, 50, 50);
  369. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  370. litest_touch_up(touchpad, 0);
  371. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  372. litest_device_destroy(touchpad);
  373. }
  374. END_TEST
  375. START_TEST(switch_dont_resume_disabled_touchpad)
  376. {
  377. struct litest_device *sw = litest_current_device();
  378. struct litest_device *touchpad;
  379. struct libinput *li = sw->libinput;
  380. enum libinput_switch which =
  381. litest_test_param_get_i32(test_env->params, "switch");
  382. if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
  383. return LITEST_NOT_APPLICABLE;
  384. touchpad = switch_init_paired_touchpad(li);
  385. litest_disable_tap(touchpad->libinput_device);
  386. litest_disable_hold_gestures(touchpad->libinput_device);
  387. libinput_device_config_send_events_set_mode(
  388. touchpad->libinput_device,
  389. LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
  390. litest_drain_events(li);
  391. /* switch is on - no events */
  392. litest_grab_device(sw);
  393. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  394. litest_ungrab_device(sw);
  395. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  396. litest_touch_down(touchpad, 0, 50, 50);
  397. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  398. litest_touch_up(touchpad, 0);
  399. litest_assert_empty_queue(li);
  400. /* switch is off but but tp is still disabled */
  401. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
  402. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  403. litest_touch_down(touchpad, 0, 50, 50);
  404. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  405. litest_touch_up(touchpad, 0);
  406. litest_assert_empty_queue(li);
  407. litest_device_destroy(touchpad);
  408. }
  409. END_TEST
  410. START_TEST(switch_dont_resume_disabled_touchpad_external_mouse)
  411. {
  412. struct litest_device *sw = litest_current_device();
  413. struct litest_device *touchpad, *mouse;
  414. struct libinput *li = sw->libinput;
  415. enum libinput_switch which =
  416. litest_test_param_get_i32(test_env->params, "switch");
  417. if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
  418. return LITEST_NOT_APPLICABLE;
  419. touchpad = switch_init_paired_touchpad(li);
  420. mouse = litest_add_device(li, LITEST_MOUSE);
  421. litest_disable_tap(touchpad->libinput_device);
  422. litest_disable_hold_gestures(touchpad->libinput_device);
  423. libinput_device_config_send_events_set_mode(
  424. touchpad->libinput_device,
  425. LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE);
  426. litest_drain_events(li);
  427. litest_touch_down(touchpad, 0, 50, 50);
  428. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  429. litest_touch_up(touchpad, 0);
  430. litest_assert_empty_queue(li);
  431. /* switch is on - no events */
  432. litest_grab_device(sw);
  433. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  434. litest_ungrab_device(sw);
  435. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  436. litest_touch_down(touchpad, 0, 50, 50);
  437. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  438. litest_touch_up(touchpad, 0);
  439. litest_assert_empty_queue(li);
  440. /* switch is off but but tp is still disabled */
  441. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
  442. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  443. litest_touch_down(touchpad, 0, 50, 50);
  444. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  445. litest_touch_up(touchpad, 0);
  446. litest_assert_empty_queue(li);
  447. litest_device_destroy(touchpad);
  448. litest_device_destroy(mouse);
  449. }
  450. END_TEST
  451. START_TEST(lid_open_on_key)
  452. {
  453. struct litest_device *sw = litest_current_device();
  454. struct litest_device *keyboard;
  455. struct libinput *li = sw->libinput;
  456. struct libinput_event *event;
  457. if (!switch_has_lid(sw))
  458. return LITEST_NOT_APPLICABLE;
  459. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  460. litest_grab_device(sw);
  461. for (int i = 0; i < 3; i++) {
  462. litest_switch_action(sw, LIBINPUT_SWITCH_LID, LIBINPUT_SWITCH_STATE_ON);
  463. litest_drain_events(li);
  464. litest_event(keyboard, EV_KEY, KEY_A, 1);
  465. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  466. litest_event(keyboard, EV_KEY, KEY_A, 0);
  467. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  468. litest_dispatch(li);
  469. event = libinput_get_event(li);
  470. litest_is_switch_event(event,
  471. LIBINPUT_SWITCH_LID,
  472. LIBINPUT_SWITCH_STATE_OFF);
  473. libinput_event_destroy(event);
  474. litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
  475. litest_switch_action(sw,
  476. LIBINPUT_SWITCH_LID,
  477. LIBINPUT_SWITCH_STATE_OFF);
  478. litest_assert_empty_queue(li);
  479. }
  480. litest_ungrab_device(sw);
  481. litest_device_destroy(keyboard);
  482. }
  483. END_TEST
  484. START_TEST(lid_open_on_key_touchpad_enabled)
  485. {
  486. struct litest_device *sw = litest_current_device();
  487. struct litest_device *keyboard, *touchpad;
  488. struct libinput *li = sw->libinput;
  489. if (!switch_has_lid(sw))
  490. return LITEST_NOT_APPLICABLE;
  491. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  492. touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
  493. litest_disable_hold_gestures(touchpad->libinput_device);
  494. litest_grab_device(sw);
  495. litest_switch_action(sw, LIBINPUT_SWITCH_LID, LIBINPUT_SWITCH_STATE_ON);
  496. litest_ungrab_device(sw);
  497. litest_drain_events(li);
  498. litest_event(keyboard, EV_KEY, KEY_A, 1);
  499. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  500. litest_event(keyboard, EV_KEY, KEY_A, 0);
  501. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  502. litest_drain_events(li);
  503. litest_timeout_dwt_long(li);
  504. litest_touch_down(touchpad, 0, 50, 50);
  505. litest_touch_move_to(touchpad, 0, 50, 50, 70, 70, 10);
  506. litest_touch_up(touchpad, 0);
  507. litest_dispatch(li);
  508. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  509. litest_device_destroy(keyboard);
  510. litest_device_destroy(touchpad);
  511. }
  512. END_TEST
  513. START_TEST(switch_suspend_with_keyboard)
  514. {
  515. struct litest_device *keyboard;
  516. struct litest_device *sw;
  517. enum libinput_switch which =
  518. litest_test_param_get_i32(test_env->params, "switch");
  519. _litest_context_destroy_ struct libinput *li = litest_create_context();
  520. switch (which) {
  521. case LIBINPUT_SWITCH_LID:
  522. sw = litest_add_device(li, LITEST_LID_SWITCH);
  523. break;
  524. case LIBINPUT_SWITCH_TABLET_MODE:
  525. sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
  526. break;
  527. case LIBINPUT_SWITCH_KEYPAD_SLIDE:
  528. sw = litest_add_device(li, LITEST_KEYPAD_SLIDE_SWITCH);
  529. break;
  530. default:
  531. abort();
  532. }
  533. litest_dispatch(li);
  534. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  535. litest_dispatch(li);
  536. litest_grab_device(sw);
  537. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  538. litest_drain_events(li);
  539. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
  540. litest_drain_events(li);
  541. litest_ungrab_device(sw);
  542. litest_device_destroy(keyboard);
  543. litest_drain_events(li);
  544. litest_device_destroy(sw);
  545. litest_dispatch(li);
  546. }
  547. END_TEST
  548. START_TEST(switch_suspend_with_touchpad)
  549. {
  550. struct litest_device *touchpad, *sw;
  551. enum libinput_switch which =
  552. litest_test_param_get_i32(test_env->params, "switch");
  553. _litest_context_destroy_ struct libinput *li = litest_create_context();
  554. switch (which) {
  555. case LIBINPUT_SWITCH_LID:
  556. sw = litest_add_device(li, LITEST_LID_SWITCH);
  557. break;
  558. case LIBINPUT_SWITCH_TABLET_MODE:
  559. sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
  560. break;
  561. default:
  562. abort();
  563. }
  564. litest_drain_events(li);
  565. touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
  566. litest_drain_events(li);
  567. litest_grab_device(sw);
  568. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
  569. litest_drain_events(li);
  570. litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
  571. litest_drain_events(li);
  572. litest_ungrab_device(sw);
  573. litest_device_destroy(sw);
  574. litest_drain_events(li);
  575. litest_device_destroy(touchpad);
  576. litest_drain_events(li);
  577. }
  578. END_TEST
  579. START_TEST(lid_update_hw_on_key)
  580. {
  581. struct litest_device *sw = litest_current_device();
  582. struct libinput *li = sw->libinput;
  583. struct litest_device *keyboard;
  584. _free_(libevdev) *evdev = NULL;
  585. struct input_event event;
  586. int rc;
  587. if (!switch_has_lid(sw))
  588. return LITEST_NOT_APPLICABLE;
  589. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  590. litest_grab_device(sw);
  591. litest_switch_action(sw, LIBINPUT_SWITCH_LID, LIBINPUT_SWITCH_STATE_ON);
  592. litest_drain_events(li);
  593. litest_ungrab_device(sw);
  594. /* Separate direct libevdev context to check if the HW event goes
  595. * through */
  596. _autoclose_ int fd =
  597. open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY | O_NONBLOCK);
  598. litest_assert_int_ge(fd, 0);
  599. litest_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
  600. litest_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
  601. /* Typing on the keyboard should trigger a lid open event */
  602. litest_event(keyboard, EV_KEY, KEY_A, 1);
  603. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  604. litest_event(keyboard, EV_KEY, KEY_A, 0);
  605. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  606. litest_drain_events(li);
  607. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  608. litest_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
  609. litest_assert_int_eq(event.type, EV_SW);
  610. litest_assert_int_eq(event.code, SW_LID);
  611. litest_assert_int_eq(event.value, 0);
  612. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  613. litest_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
  614. litest_assert_int_eq(event.type, EV_SYN);
  615. litest_assert_int_eq(event.code, SYN_REPORT);
  616. litest_assert_int_eq(event.value, 0);
  617. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  618. litest_assert_int_eq(rc, -EAGAIN);
  619. litest_device_destroy(keyboard);
  620. }
  621. END_TEST
  622. START_TEST(lid_update_hw_on_key_closed_on_init)
  623. {
  624. struct litest_device *sw = litest_current_device();
  625. struct litest_device *keyboard;
  626. _free_(libevdev) * evdev;
  627. struct input_event event;
  628. int rc;
  629. litest_grab_device(sw);
  630. litest_switch_action(sw, LIBINPUT_SWITCH_LID, LIBINPUT_SWITCH_STATE_ON);
  631. litest_ungrab_device(sw);
  632. /* Separate direct libevdev context to check if the HW event goes
  633. * through */
  634. _autoclose_ int fd =
  635. open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY | O_NONBLOCK);
  636. litest_assert_int_ge(fd, 0);
  637. litest_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
  638. litest_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
  639. keyboard = litest_add_device(sw->libinput, LITEST_KEYBOARD);
  640. /* separate context for the right state on init */
  641. _litest_context_destroy_ struct libinput *li = litest_create_context();
  642. libinput_path_add_device(li, libevdev_uinput_get_devnode(sw->uinput));
  643. libinput_path_add_device(li, libevdev_uinput_get_devnode(keyboard->uinput));
  644. /* don't expect a switch waiting for us, this is run for an
  645. * unreliable device */
  646. while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
  647. litest_assert_enum_ne(libinput_next_event_type(li),
  648. LIBINPUT_EVENT_SWITCH_TOGGLE);
  649. libinput_event_destroy(libinput_get_event(li));
  650. }
  651. litest_event(keyboard, EV_KEY, KEY_A, 1);
  652. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  653. litest_event(keyboard, EV_KEY, KEY_A, 0);
  654. litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
  655. /* No switch event, we're still in vanilla (open) state */
  656. litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
  657. /* Make sure kernel state has updated */
  658. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  659. litest_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
  660. litest_assert_int_eq(event.type, EV_SW);
  661. litest_assert_int_eq(event.code, SW_LID);
  662. litest_assert_int_eq(event.value, 0);
  663. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  664. litest_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
  665. litest_assert_int_eq(event.type, EV_SYN);
  666. litest_assert_int_eq(event.code, SYN_REPORT);
  667. litest_assert_int_eq(event.value, 0);
  668. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  669. litest_assert_int_eq(rc, -EAGAIN);
  670. litest_device_destroy(keyboard);
  671. }
  672. END_TEST
  673. START_TEST(lid_update_hw_on_key_multiple_keyboards)
  674. {
  675. struct litest_device *sw = litest_current_device();
  676. struct libinput *li = sw->libinput;
  677. struct litest_device *keyboard1, *keyboard2;
  678. _free_(libevdev) * evdev;
  679. struct input_event event;
  680. int rc;
  681. if (!switch_has_lid(sw))
  682. return LITEST_NOT_APPLICABLE;
  683. keyboard1 = litest_add_device(li, LITEST_KEYBOARD_BLADE_STEALTH_VIDEOSWITCH);
  684. litest_dispatch(li);
  685. keyboard2 = litest_add_device(li, LITEST_KEYBOARD_BLADE_STEALTH);
  686. litest_dispatch(li);
  687. litest_grab_device(sw);
  688. litest_switch_action(sw, LIBINPUT_SWITCH_LID, LIBINPUT_SWITCH_STATE_ON);
  689. litest_drain_events(li);
  690. litest_ungrab_device(sw);
  691. /* Separate direct libevdev context to check if the HW event goes
  692. * through */
  693. _autoclose_ int fd =
  694. open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY | O_NONBLOCK);
  695. litest_assert_int_ge(fd, 0);
  696. litest_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
  697. litest_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
  698. /* Typing on the second keyboard should trigger a lid open event */
  699. litest_event(keyboard2, EV_KEY, KEY_A, 1);
  700. litest_event(keyboard2, EV_SYN, SYN_REPORT, 0);
  701. litest_event(keyboard2, EV_KEY, KEY_A, 0);
  702. litest_event(keyboard2, EV_SYN, SYN_REPORT, 0);
  703. litest_drain_events(li);
  704. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  705. litest_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
  706. litest_assert_int_eq(event.type, EV_SW);
  707. litest_assert_int_eq(event.code, SW_LID);
  708. litest_assert_int_eq(event.value, 0);
  709. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  710. litest_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
  711. litest_assert_int_eq(event.type, EV_SYN);
  712. litest_assert_int_eq(event.code, SYN_REPORT);
  713. litest_assert_int_eq(event.value, 0);
  714. rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
  715. litest_assert_int_eq(rc, -EAGAIN);
  716. litest_device_destroy(keyboard1);
  717. litest_device_destroy(keyboard2);
  718. }
  719. END_TEST
  720. START_TEST(lid_key_press)
  721. {
  722. struct litest_device *sw = litest_current_device();
  723. struct libinput *li = sw->libinput;
  724. litest_drain_events(li);
  725. litest_keyboard_key(sw, KEY_VOLUMEUP, true);
  726. litest_keyboard_key(sw, KEY_VOLUMEUP, false);
  727. litest_dispatch(li);
  728. /* Check that we're routing key events from a lid device too */
  729. litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
  730. }
  731. END_TEST
  732. START_TEST(tablet_mode_disable_touchpad_on_init)
  733. {
  734. struct litest_device *sw = litest_current_device();
  735. struct litest_device *touchpad;
  736. struct libinput *li = sw->libinput;
  737. if (!switch_has_tablet_mode(sw))
  738. return LITEST_NOT_APPLICABLE;
  739. litest_grab_device(sw);
  740. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  741. litest_drain_events(li);
  742. /* touchpad comes with switch already on - no events */
  743. touchpad = switch_init_paired_touchpad(li);
  744. litest_disable_tap(touchpad->libinput_device);
  745. litest_disable_hold_gestures(touchpad->libinput_device);
  746. litest_drain_events(li);
  747. litest_touch_down(touchpad, 0, 50, 50);
  748. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  749. litest_touch_up(touchpad, 0);
  750. litest_assert_empty_queue(li);
  751. litest_switch_action(sw,
  752. LIBINPUT_SWITCH_TABLET_MODE,
  753. LIBINPUT_SWITCH_STATE_OFF);
  754. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  755. litest_touch_down(touchpad, 0, 50, 50);
  756. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  757. litest_touch_up(touchpad, 0);
  758. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  759. litest_ungrab_device(sw);
  760. litest_device_destroy(touchpad);
  761. }
  762. END_TEST
  763. START_TEST(tablet_mode_disable_touchpad_on_resume)
  764. {
  765. struct litest_device *sw = litest_current_device();
  766. struct litest_device *touchpad;
  767. struct libinput *li = sw->libinput;
  768. struct libinput_event *event;
  769. bool have_switch_toggle = false;
  770. if (!switch_has_tablet_mode(sw))
  771. return LITEST_NOT_APPLICABLE;
  772. touchpad = switch_init_paired_touchpad(li);
  773. litest_disable_tap(touchpad->libinput_device);
  774. litest_disable_hold_gestures(touchpad->libinput_device);
  775. litest_drain_events(li);
  776. libinput_suspend(li);
  777. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  778. litest_drain_events(li);
  779. libinput_resume(li);
  780. litest_dispatch(li);
  781. while ((event = libinput_get_event(li))) {
  782. enum libinput_event_type type;
  783. type = libinput_event_get_type(event);
  784. switch (type) {
  785. case LIBINPUT_EVENT_DEVICE_ADDED:
  786. break;
  787. case LIBINPUT_EVENT_SWITCH_TOGGLE:
  788. litest_is_switch_event(event,
  789. LIBINPUT_SWITCH_TABLET_MODE,
  790. LIBINPUT_SWITCH_STATE_ON);
  791. have_switch_toggle = true;
  792. break;
  793. default:
  794. litest_abort_msg("Unexpected event type");
  795. }
  796. libinput_event_destroy(event);
  797. }
  798. litest_assert(have_switch_toggle);
  799. litest_touch_down(touchpad, 0, 50, 50);
  800. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  801. litest_touch_up(touchpad, 0);
  802. litest_assert_empty_queue(li);
  803. litest_switch_action(sw,
  804. LIBINPUT_SWITCH_TABLET_MODE,
  805. LIBINPUT_SWITCH_STATE_OFF);
  806. litest_dispatch(li);
  807. event = libinput_get_event(li);
  808. litest_is_switch_event(event,
  809. LIBINPUT_SWITCH_TABLET_MODE,
  810. LIBINPUT_SWITCH_STATE_OFF);
  811. libinput_event_destroy(event);
  812. litest_touch_down(touchpad, 0, 50, 50);
  813. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  814. litest_touch_up(touchpad, 0);
  815. litest_dispatch(li);
  816. litest_drain_events_of_type(li,
  817. LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
  818. LIBINPUT_EVENT_GESTURE_HOLD_END);
  819. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  820. litest_device_destroy(touchpad);
  821. }
  822. END_TEST
  823. START_TEST(tablet_mode_enable_touchpad_on_resume)
  824. {
  825. struct litest_device *sw = litest_current_device();
  826. struct litest_device *touchpad;
  827. struct libinput *li = sw->libinput;
  828. struct libinput_event *event;
  829. if (!switch_has_tablet_mode(sw))
  830. return LITEST_NOT_APPLICABLE;
  831. touchpad = switch_init_paired_touchpad(li);
  832. litest_disable_tap(touchpad->libinput_device);
  833. litest_drain_events(li);
  834. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  835. libinput_suspend(li);
  836. litest_drain_events(li);
  837. litest_switch_action(sw,
  838. LIBINPUT_SWITCH_TABLET_MODE,
  839. LIBINPUT_SWITCH_STATE_OFF);
  840. libinput_resume(li);
  841. litest_dispatch(li);
  842. litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED);
  843. litest_touch_down(touchpad, 0, 50, 50);
  844. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  845. litest_touch_up(touchpad, 0);
  846. litest_drain_events_of_type(li,
  847. LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
  848. LIBINPUT_EVENT_GESTURE_HOLD_END);
  849. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  850. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  851. litest_dispatch(li);
  852. event = libinput_get_event(li);
  853. litest_is_switch_event(event,
  854. LIBINPUT_SWITCH_TABLET_MODE,
  855. LIBINPUT_SWITCH_STATE_ON);
  856. libinput_event_destroy(event);
  857. litest_touch_down(touchpad, 0, 50, 50);
  858. litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
  859. litest_touch_up(touchpad, 0);
  860. litest_assert_empty_queue(li);
  861. litest_device_destroy(touchpad);
  862. }
  863. END_TEST
  864. START_TEST(tablet_mode_disable_keyboard)
  865. {
  866. struct litest_device *sw = litest_current_device();
  867. struct litest_device *keyboard;
  868. struct libinput *li = sw->libinput;
  869. if (!switch_has_tablet_mode(sw))
  870. return LITEST_NOT_APPLICABLE;
  871. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  872. litest_drain_events(li);
  873. litest_keyboard_key(keyboard, KEY_A, true);
  874. litest_keyboard_key(keyboard, KEY_A, false);
  875. litest_keyboard_key(keyboard, KEY_B, true); /* KEY_B down but not up */
  876. litest_dispatch(li);
  877. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
  878. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
  879. litest_assert_key_event(li,
  880. KEY_B,
  881. LIBINPUT_KEY_STATE_PRESSED); /* KEY_B down but not up */
  882. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  883. /* The key currently down must be released */
  884. litest_assert_key_event(li, KEY_B, LIBINPUT_KEY_STATE_RELEASED);
  885. litest_assert_switch_event(li,
  886. LIBINPUT_SWITCH_TABLET_MODE,
  887. LIBINPUT_SWITCH_STATE_ON);
  888. litest_assert_empty_queue(li);
  889. litest_keyboard_key(keyboard, KEY_B, false); /* release the kernel device */
  890. litest_keyboard_key(keyboard, KEY_A, true);
  891. litest_keyboard_key(keyboard, KEY_A, false);
  892. litest_assert_empty_queue(li);
  893. litest_switch_action(sw,
  894. LIBINPUT_SWITCH_TABLET_MODE,
  895. LIBINPUT_SWITCH_STATE_OFF);
  896. litest_assert_switch_event(li,
  897. LIBINPUT_SWITCH_TABLET_MODE,
  898. LIBINPUT_SWITCH_STATE_OFF);
  899. litest_keyboard_key(keyboard, KEY_A, true);
  900. litest_keyboard_key(keyboard, KEY_A, false);
  901. litest_keyboard_key(keyboard, KEY_B, true);
  902. litest_keyboard_key(keyboard, KEY_B, false);
  903. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
  904. litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
  905. litest_assert_key_event(li, KEY_B, LIBINPUT_KEY_STATE_PRESSED);
  906. litest_assert_key_event(li, KEY_B, LIBINPUT_KEY_STATE_RELEASED);
  907. litest_device_destroy(keyboard);
  908. }
  909. END_TEST
  910. START_TEST(tablet_mode_disable_keyboard_on_init)
  911. {
  912. struct litest_device *sw = litest_current_device();
  913. struct litest_device *keyboard;
  914. struct libinput *li = sw->libinput;
  915. if (!switch_has_tablet_mode(sw))
  916. return LITEST_NOT_APPLICABLE;
  917. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  918. litest_drain_events(li);
  919. /* keyboard comes with switch already on - no events */
  920. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  921. litest_drain_events(li);
  922. litest_keyboard_key(keyboard, KEY_A, true);
  923. litest_keyboard_key(keyboard, KEY_A, false);
  924. litest_assert_empty_queue(li);
  925. litest_switch_action(sw,
  926. LIBINPUT_SWITCH_TABLET_MODE,
  927. LIBINPUT_SWITCH_STATE_OFF);
  928. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  929. litest_keyboard_key(keyboard, KEY_A, true);
  930. litest_keyboard_key(keyboard, KEY_A, false);
  931. litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
  932. litest_device_destroy(keyboard);
  933. }
  934. END_TEST
  935. START_TEST(tablet_mode_disable_keyboard_on_resume)
  936. {
  937. struct litest_device *sw = litest_current_device();
  938. struct litest_device *keyboard;
  939. struct libinput *li = sw->libinput;
  940. struct libinput_event *event;
  941. bool have_switch_toggle = false;
  942. if (!switch_has_tablet_mode(sw))
  943. return LITEST_NOT_APPLICABLE;
  944. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  945. litest_drain_events(li);
  946. libinput_suspend(li);
  947. /* We cannot grab this device because libinput doesn't have an open
  948. * fd to this device, we need an independent grab.
  949. */
  950. libevdev_grab(sw->evdev, LIBEVDEV_GRAB);
  951. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  952. libevdev_grab(sw->evdev, LIBEVDEV_UNGRAB);
  953. litest_drain_events(li);
  954. libinput_resume(li);
  955. litest_dispatch(li);
  956. while ((event = libinput_get_event(li))) {
  957. enum libinput_event_type type;
  958. type = libinput_event_get_type(event);
  959. switch (type) {
  960. case LIBINPUT_EVENT_DEVICE_ADDED:
  961. break;
  962. case LIBINPUT_EVENT_SWITCH_TOGGLE:
  963. litest_is_switch_event(event,
  964. LIBINPUT_SWITCH_TABLET_MODE,
  965. LIBINPUT_SWITCH_STATE_ON);
  966. have_switch_toggle = true;
  967. break;
  968. default:
  969. litest_abort_msg("Unexpected event type");
  970. }
  971. libinput_event_destroy(event);
  972. }
  973. litest_assert(have_switch_toggle);
  974. litest_keyboard_key(keyboard, KEY_A, true);
  975. litest_keyboard_key(keyboard, KEY_A, false);
  976. litest_assert_empty_queue(li);
  977. litest_grab_device(sw);
  978. litest_switch_action(sw,
  979. LIBINPUT_SWITCH_TABLET_MODE,
  980. LIBINPUT_SWITCH_STATE_OFF);
  981. litest_ungrab_device(sw);
  982. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  983. litest_keyboard_key(keyboard, KEY_A, true);
  984. litest_keyboard_key(keyboard, KEY_A, false);
  985. litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
  986. litest_device_destroy(keyboard);
  987. }
  988. END_TEST
  989. START_TEST(tablet_mode_enable_keyboard_on_resume)
  990. {
  991. struct litest_device *sw = litest_current_device();
  992. struct litest_device *keyboard;
  993. struct libinput *li = sw->libinput;
  994. if (!switch_has_tablet_mode(sw))
  995. return LITEST_NOT_APPLICABLE;
  996. keyboard = litest_add_device(li, LITEST_KEYBOARD);
  997. litest_grab_device(sw);
  998. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  999. litest_drain_events(li);
  1000. litest_ungrab_device(sw);
  1001. libinput_suspend(li);
  1002. litest_drain_events(li);
  1003. litest_switch_action(sw,
  1004. LIBINPUT_SWITCH_TABLET_MODE,
  1005. LIBINPUT_SWITCH_STATE_OFF);
  1006. libinput_resume(li);
  1007. litest_dispatch(li);
  1008. litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED);
  1009. litest_keyboard_key(keyboard, KEY_A, true);
  1010. litest_keyboard_key(keyboard, KEY_A, false);
  1011. litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
  1012. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  1013. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  1014. litest_keyboard_key(keyboard, KEY_A, true);
  1015. litest_keyboard_key(keyboard, KEY_A, false);
  1016. litest_assert_empty_queue(li);
  1017. litest_device_destroy(keyboard);
  1018. }
  1019. END_TEST
  1020. START_TEST(tablet_mode_disable_trackpoint)
  1021. {
  1022. struct litest_device *sw = litest_current_device();
  1023. struct litest_device *trackpoint;
  1024. struct libinput *li = sw->libinput;
  1025. if (!switch_has_tablet_mode(sw))
  1026. return LITEST_NOT_APPLICABLE;
  1027. trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
  1028. litest_drain_events(li);
  1029. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1030. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1031. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1032. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1033. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  1034. litest_grab_device(sw);
  1035. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  1036. litest_drain_events(li);
  1037. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1038. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1039. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1040. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1041. litest_assert_empty_queue(li);
  1042. litest_switch_action(sw,
  1043. LIBINPUT_SWITCH_TABLET_MODE,
  1044. LIBINPUT_SWITCH_STATE_OFF);
  1045. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  1046. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1047. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1048. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1049. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1050. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  1051. litest_ungrab_device(sw);
  1052. litest_device_destroy(trackpoint);
  1053. }
  1054. END_TEST
  1055. START_TEST(tablet_mode_disable_trackpoint_on_init)
  1056. {
  1057. struct litest_device *sw = litest_current_device();
  1058. struct litest_device *trackpoint;
  1059. struct libinput *li = sw->libinput;
  1060. if (!switch_has_tablet_mode(sw))
  1061. return LITEST_NOT_APPLICABLE;
  1062. litest_grab_device(sw);
  1063. litest_switch_action(sw, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON);
  1064. litest_drain_events(li);
  1065. /* trackpoint comes with switch already on - no events */
  1066. trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
  1067. litest_drain_events(li);
  1068. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1069. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1070. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1071. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1072. litest_assert_empty_queue(li);
  1073. litest_switch_action(sw,
  1074. LIBINPUT_SWITCH_TABLET_MODE,
  1075. LIBINPUT_SWITCH_STATE_OFF);
  1076. litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
  1077. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1078. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1079. litest_event(trackpoint, EV_REL, REL_Y, -1);
  1080. litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
  1081. litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
  1082. litest_ungrab_device(sw);
  1083. litest_device_destroy(trackpoint);
  1084. }
  1085. END_TEST
  1086. START_TEST(dock_toggle)
  1087. {
  1088. struct litest_device *sw = litest_current_device();
  1089. struct libinput *li = sw->libinput;
  1090. if (!libevdev_has_event_code(sw->evdev, EV_SW, SW_DOCK))
  1091. return LITEST_NOT_APPLICABLE;
  1092. litest_drain_events(li);
  1093. litest_grab_device(sw);
  1094. litest_event(sw, EV_SW, SW_DOCK, 1);
  1095. litest_dispatch(li);
  1096. litest_event(sw, EV_SW, SW_DOCK, 0);
  1097. litest_dispatch(li);
  1098. litest_ungrab_device(sw);
  1099. litest_assert_empty_queue(li);
  1100. }
  1101. END_TEST
  1102. TEST_COLLECTION(switch)
  1103. {
  1104. /* clang-format off */
  1105. litest_add(switch_has_cap, LITEST_SWITCH, LITEST_ANY);
  1106. litest_add(switch_has_lid_switch, LITEST_SWITCH, LITEST_ANY);
  1107. litest_add(switch_has_tablet_mode_switch, LITEST_SWITCH, LITEST_ANY);
  1108. litest_add(switch_has_keypad_slide_switch, LITEST_SWITCH, LITEST_ANY);
  1109. litest_add(switch_not_down_on_init, LITEST_SWITCH, LITEST_ANY);
  1110. litest_with_parameters(params, "switch", 'I', 3, litest_named_i32(LIBINPUT_SWITCH_LID, "lid"),
  1111. litest_named_i32(LIBINPUT_SWITCH_TABLET_MODE, "tablet_mode"),
  1112. litest_named_i32(LIBINPUT_SWITCH_KEYPAD_SLIDE, "keypad_slide")) {
  1113. litest_add_parametrized(switch_toggle, LITEST_SWITCH, LITEST_ANY, params);
  1114. litest_add_parametrized(switch_toggle_double, LITEST_SWITCH, LITEST_ANY, params);
  1115. litest_add_parametrized(switch_down_on_init, LITEST_SWITCH, LITEST_ANY, params);
  1116. litest_add_parametrized(switch_not_down_on_init, LITEST_SWITCH, LITEST_ANY, params);
  1117. }
  1118. litest_with_parameters(params, "switch", 'I', 2, litest_named_i32(LIBINPUT_SWITCH_LID, "lid"),
  1119. litest_named_i32(LIBINPUT_SWITCH_TABLET_MODE, "tablet_mode")) {
  1120. litest_add_parametrized(switch_disable_touchpad, LITEST_SWITCH, LITEST_ANY, params);
  1121. litest_add_parametrized(switch_disable_touchpad_during_touch, LITEST_SWITCH, LITEST_ANY, params);
  1122. litest_add_parametrized(switch_disable_touchpad_edge_scroll, LITEST_SWITCH, LITEST_ANY, params);
  1123. litest_add_parametrized(switch_disable_touchpad_edge_scroll_interrupt, LITEST_SWITCH, LITEST_ANY, params);
  1124. litest_add_parametrized(switch_disable_touchpad_already_open, LITEST_SWITCH, LITEST_ANY, params);
  1125. litest_add_parametrized(switch_dont_resume_disabled_touchpad, LITEST_SWITCH, LITEST_ANY, params);
  1126. litest_add_parametrized(switch_dont_resume_disabled_touchpad_external_mouse, LITEST_SWITCH, LITEST_ANY, params);
  1127. litest_add_parametrized_no_device(switch_suspend_with_keyboard, params);
  1128. litest_add_parametrized_no_device(switch_suspend_with_touchpad, params);
  1129. }
  1130. litest_add(lid_open_on_key, LITEST_SWITCH, LITEST_ANY);
  1131. litest_add(lid_open_on_key_touchpad_enabled, LITEST_SWITCH, LITEST_ANY);
  1132. litest_add_for_device(lid_update_hw_on_key, LITEST_LID_SWITCH_SURFACE3);
  1133. litest_add_for_device(lid_update_hw_on_key_closed_on_init, LITEST_LID_SWITCH_SURFACE3);
  1134. litest_add_for_device(lid_update_hw_on_key_multiple_keyboards, LITEST_LID_SWITCH_SURFACE3);
  1135. litest_add_for_device(lid_key_press, LITEST_GPIO_KEYS);
  1136. litest_add(tablet_mode_disable_touchpad_on_init, LITEST_SWITCH, LITEST_ANY);
  1137. litest_add(tablet_mode_disable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY);
  1138. litest_add(tablet_mode_enable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY);
  1139. litest_add(tablet_mode_disable_keyboard, LITEST_SWITCH, LITEST_ANY);
  1140. litest_add(tablet_mode_disable_keyboard_on_init, LITEST_SWITCH, LITEST_ANY);
  1141. litest_add(tablet_mode_disable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY);
  1142. litest_add(tablet_mode_enable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY);
  1143. litest_add(tablet_mode_disable_trackpoint, LITEST_SWITCH, LITEST_ANY);
  1144. litest_add(tablet_mode_disable_trackpoint_on_init, LITEST_SWITCH, LITEST_ANY);
  1145. litest_add(dock_toggle, LITEST_SWITCH, LITEST_ANY);
  1146. /* clang-format on */
  1147. }