test-totem.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*
  2. * Copyright © 2018 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.h>
  27. #include <stdarg.h>
  28. #include <stdbool.h>
  29. #include <unistd.h>
  30. #include "util-input-event.h"
  31. #include "libinput-util.h"
  32. #include "litest.h"
  33. START_TEST(totem_type)
  34. {
  35. struct litest_device *dev = litest_current_device();
  36. struct libinput *li = dev->libinput;
  37. struct libinput_event *event;
  38. struct libinput_event_tablet_tool *t;
  39. struct libinput_tablet_tool *tool;
  40. litest_drain_events(li);
  41. litest_tablet_proximity_in(dev, 50, 50, NULL);
  42. litest_dispatch(li);
  43. event = libinput_get_event(li);
  44. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  45. tool = libinput_event_tablet_tool_get_tool(t);
  46. litest_assert_enum_eq(libinput_tablet_tool_get_type(tool),
  47. LIBINPUT_TABLET_TOOL_TYPE_TOTEM);
  48. libinput_event_destroy(event);
  49. }
  50. END_TEST
  51. START_TEST(totem_axes)
  52. {
  53. struct litest_device *dev = litest_current_device();
  54. struct libinput *li = dev->libinput;
  55. struct libinput_event *event;
  56. struct libinput_event_tablet_tool *t;
  57. struct libinput_tablet_tool *tool;
  58. litest_drain_events(li);
  59. litest_tablet_proximity_in(dev, 50, 50, NULL);
  60. litest_dispatch(li);
  61. event = libinput_get_event(li);
  62. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  63. tool = libinput_event_tablet_tool_get_tool(t);
  64. litest_assert(libinput_tablet_tool_has_rotation(tool));
  65. litest_assert(libinput_tablet_tool_has_size(tool));
  66. litest_assert(libinput_tablet_tool_has_button(tool, BTN_0));
  67. libinput_event_destroy(event);
  68. }
  69. END_TEST
  70. START_TEST(totem_proximity_in_out)
  71. {
  72. struct litest_device *dev = litest_current_device();
  73. struct libinput *li = dev->libinput;
  74. struct libinput_event *event;
  75. struct libinput_event_tablet_tool *t;
  76. litest_drain_events(li);
  77. litest_tablet_proximity_in(dev, 50, 50, NULL);
  78. litest_dispatch(li);
  79. event = libinput_get_event(li);
  80. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  81. litest_assert_enum_eq(libinput_event_tablet_tool_get_proximity_state(t),
  82. LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
  83. libinput_event_destroy(event);
  84. event = libinput_get_event(li);
  85. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
  86. litest_assert_enum_eq(libinput_event_tablet_tool_get_tip_state(t),
  87. LIBINPUT_TABLET_TOOL_TIP_DOWN);
  88. libinput_event_destroy(event);
  89. litest_assert_empty_queue(li);
  90. litest_tablet_proximity_out(dev);
  91. litest_dispatch(li);
  92. event = libinput_get_event(li);
  93. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
  94. litest_assert_enum_eq(libinput_event_tablet_tool_get_tip_state(t),
  95. LIBINPUT_TABLET_TOOL_TIP_UP);
  96. libinput_event_destroy(event);
  97. event = libinput_get_event(li);
  98. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  99. litest_assert_enum_eq(libinput_event_tablet_tool_get_proximity_state(t),
  100. LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
  101. libinput_event_destroy(event);
  102. }
  103. END_TEST
  104. START_TEST(totem_proximity_in_on_init)
  105. {
  106. struct litest_device *dev = litest_current_device();
  107. struct libinput_event *event;
  108. struct libinput_event_tablet_tool *t;
  109. const char *devnode;
  110. double x, y;
  111. double w, h;
  112. const struct input_absinfo *abs;
  113. abs = libevdev_get_abs_info(dev->evdev, ABS_MT_POSITION_X);
  114. w = absinfo_range(abs) / abs->resolution;
  115. abs = libevdev_get_abs_info(dev->evdev, ABS_MT_POSITION_Y);
  116. h = absinfo_range(abs) / abs->resolution;
  117. litest_tablet_proximity_in(dev, 50, 50, NULL);
  118. /* for simplicity, we create a new litest context */
  119. devnode = libevdev_uinput_get_devnode(dev->uinput);
  120. _litest_context_destroy_ struct libinput *li = litest_create_context();
  121. libinput_path_add_device(li, devnode);
  122. litest_dispatch(li);
  123. litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED);
  124. event = libinput_get_event(li);
  125. libinput_event_destroy(event);
  126. event = libinput_get_event(li);
  127. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  128. litest_assert_enum_eq(libinput_event_tablet_tool_get_proximity_state(t),
  129. LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
  130. x = libinput_event_tablet_tool_get_x(t);
  131. y = libinput_event_tablet_tool_get_y(t);
  132. litest_assert_double_gt(x, w / 2 - 1);
  133. litest_assert_double_lt(x, w / 2 + 1);
  134. litest_assert_double_gt(y, h / 2 - 1);
  135. litest_assert_double_lt(y, h / 2 + 1);
  136. libinput_event_destroy(event);
  137. event = libinput_get_event(li);
  138. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
  139. litest_assert_enum_eq(libinput_event_tablet_tool_get_tip_state(t),
  140. LIBINPUT_TABLET_TOOL_TIP_DOWN);
  141. x = libinput_event_tablet_tool_get_x(t);
  142. y = libinput_event_tablet_tool_get_y(t);
  143. litest_assert_double_gt(x, w / 2 - 1);
  144. litest_assert_double_lt(x, w / 2 + 1);
  145. litest_assert_double_gt(y, h / 2 - 1);
  146. litest_assert_double_lt(y, h / 2 + 1);
  147. libinput_event_destroy(event);
  148. litest_assert_empty_queue(li);
  149. }
  150. END_TEST
  151. START_TEST(totem_proximity_out_on_suspend)
  152. {
  153. struct litest_device *dev = litest_current_device();
  154. struct libinput_event *event;
  155. struct libinput_event_tablet_tool *t;
  156. const char *devnode;
  157. /* for simplicity, we create a new litest context */
  158. devnode = libevdev_uinput_get_devnode(dev->uinput);
  159. _litest_context_destroy_ struct libinput *li = litest_create_context();
  160. libinput_path_add_device(li, devnode);
  161. litest_tablet_proximity_in(dev, 50, 50, NULL);
  162. litest_drain_events(li);
  163. libinput_suspend(li);
  164. litest_dispatch(li);
  165. event = libinput_get_event(li);
  166. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
  167. litest_assert_enum_eq(libinput_event_tablet_tool_get_tip_state(t),
  168. LIBINPUT_TABLET_TOOL_TIP_UP);
  169. libinput_event_destroy(event);
  170. event = libinput_get_event(li);
  171. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  172. litest_assert_enum_eq(libinput_event_tablet_tool_get_proximity_state(t),
  173. LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
  174. libinput_event_destroy(event);
  175. litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_REMOVED);
  176. }
  177. END_TEST
  178. START_TEST(totem_motion)
  179. {
  180. struct litest_device *dev = litest_current_device();
  181. struct libinput *li = dev->libinput;
  182. struct libinput_event *event;
  183. double x = 50, y = 50;
  184. double current_x, current_y, old_x, old_y;
  185. litest_tablet_proximity_in(dev, x, y, NULL);
  186. litest_drain_events(li);
  187. for (int i = 0; i < 30; i++, x++, y--) {
  188. struct libinput_event_tablet_tool *t;
  189. litest_tablet_motion(dev, x + 1, y + 1, NULL);
  190. litest_dispatch(li);
  191. event = libinput_get_event(li);
  192. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
  193. litest_assert(libinput_event_tablet_tool_x_has_changed(t));
  194. litest_assert(libinput_event_tablet_tool_y_has_changed(t));
  195. current_x = libinput_event_tablet_tool_get_x(t);
  196. current_y = libinput_event_tablet_tool_get_y(t);
  197. if (i != 0) {
  198. litest_assert_double_gt(current_x, old_x);
  199. litest_assert_double_lt(current_y, old_y);
  200. }
  201. old_x = current_x;
  202. old_y = current_y;
  203. libinput_event_destroy(event);
  204. }
  205. }
  206. END_TEST
  207. START_TEST(totem_rotation)
  208. {
  209. struct litest_device *dev = litest_current_device();
  210. struct libinput *li = dev->libinput;
  211. struct libinput_event *event;
  212. double r, old_r;
  213. struct axis_replacement axes[] = {
  214. { ABS_MT_ORIENTATION, 50 }, /* mid-point is 0 */
  215. { -1, -1 },
  216. };
  217. litest_tablet_proximity_in(dev, 50, 50, axes);
  218. litest_drain_events(li);
  219. old_r = 360;
  220. for (int i = 1; i < 30; i++) {
  221. struct libinput_event_tablet_tool *t;
  222. litest_axis_set_value(axes, ABS_MT_ORIENTATION, 50 + i);
  223. litest_tablet_motion(dev, 50, 50, axes);
  224. litest_dispatch(li);
  225. event = libinput_get_event(li);
  226. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
  227. litest_assert(!libinput_event_tablet_tool_x_has_changed(t));
  228. litest_assert(!libinput_event_tablet_tool_y_has_changed(t));
  229. litest_assert(libinput_event_tablet_tool_rotation_has_changed(t));
  230. r = libinput_event_tablet_tool_get_rotation(t);
  231. litest_assert_double_lt(r, old_r);
  232. old_r = r;
  233. libinput_event_destroy(event);
  234. }
  235. old_r = 0;
  236. for (int i = 1; i < 30; i++) {
  237. struct libinput_event_tablet_tool *t;
  238. litest_axis_set_value(axes, ABS_MT_ORIENTATION, 50 - i);
  239. litest_tablet_motion(dev, 50, 50, axes);
  240. litest_dispatch(li);
  241. event = libinput_get_event(li);
  242. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
  243. litest_assert(!libinput_event_tablet_tool_x_has_changed(t));
  244. litest_assert(!libinput_event_tablet_tool_y_has_changed(t));
  245. litest_assert(libinput_event_tablet_tool_rotation_has_changed(t));
  246. r = libinput_event_tablet_tool_get_rotation(t);
  247. litest_assert_double_gt(r, old_r);
  248. old_r = r;
  249. libinput_event_destroy(event);
  250. }
  251. }
  252. END_TEST
  253. START_TEST(totem_size)
  254. {
  255. struct litest_device *dev = litest_current_device();
  256. struct libinput *li = dev->libinput;
  257. struct libinput_event *event;
  258. struct libinput_event_tablet_tool *t;
  259. double smin, smaj;
  260. litest_drain_events(li);
  261. litest_tablet_proximity_in(dev, 50, 50, NULL);
  262. litest_dispatch(li);
  263. event = libinput_get_event(li);
  264. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  265. litest_assert(libinput_event_tablet_tool_size_major_has_changed(t));
  266. litest_assert(libinput_event_tablet_tool_size_minor_has_changed(t));
  267. smaj = libinput_event_tablet_tool_get_size_major(t);
  268. smin = libinput_event_tablet_tool_get_size_minor(t);
  269. libinput_event_destroy(event);
  270. litest_assert_double_eq(smaj, 71.8);
  271. litest_assert_double_eq(smin, 71.8);
  272. litest_drain_events(li);
  273. }
  274. END_TEST
  275. START_TEST(totem_button)
  276. {
  277. struct litest_device *dev = litest_current_device();
  278. struct libinput *li = dev->libinput;
  279. struct libinput_event *event;
  280. struct libinput_event_tablet_tool *t;
  281. litest_tablet_proximity_in(dev, 30, 40, NULL);
  282. litest_drain_events(li);
  283. litest_button_click(dev, BTN_0, true);
  284. litest_dispatch(li);
  285. event = libinput_get_event(li);
  286. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
  287. litest_assert_int_eq(libinput_event_tablet_tool_get_button(t),
  288. (unsigned int)BTN_0);
  289. litest_assert_enum_eq(libinput_event_tablet_tool_get_button_state(t),
  290. LIBINPUT_BUTTON_STATE_PRESSED);
  291. litest_assert_enum_eq(libinput_event_tablet_tool_get_tip_state(t),
  292. LIBINPUT_TABLET_TOOL_TIP_DOWN);
  293. libinput_event_destroy(event);
  294. litest_button_click(dev, BTN_0, false);
  295. litest_dispatch(li);
  296. event = libinput_get_event(li);
  297. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
  298. litest_assert_int_eq(libinput_event_tablet_tool_get_button(t),
  299. (unsigned int)BTN_0);
  300. litest_assert_enum_eq(libinput_event_tablet_tool_get_button_state(t),
  301. LIBINPUT_BUTTON_STATE_RELEASED);
  302. litest_assert_enum_eq(libinput_event_tablet_tool_get_tip_state(t),
  303. LIBINPUT_TABLET_TOOL_TIP_DOWN);
  304. libinput_event_destroy(event);
  305. }
  306. END_TEST
  307. START_TEST(totem_button_down_on_init)
  308. {
  309. struct litest_device *dev = litest_current_device();
  310. struct libinput_event *event;
  311. struct libinput_event_tablet_tool *t;
  312. const char *devnode;
  313. litest_tablet_proximity_in(dev, 50, 50, NULL);
  314. litest_button_click(dev, BTN_0, true);
  315. /* for simplicity, we create a new litest context */
  316. devnode = libevdev_uinput_get_devnode(dev->uinput);
  317. _litest_context_destroy_ struct libinput *li = litest_create_context();
  318. libinput_path_add_device(li, devnode);
  319. litest_dispatch(li);
  320. litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED);
  321. event = libinput_get_event(li);
  322. libinput_event_destroy(event);
  323. event = libinput_get_event(li);
  324. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
  325. litest_assert_enum_eq(libinput_event_tablet_tool_get_proximity_state(t),
  326. LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
  327. libinput_event_destroy(event);
  328. event = libinput_get_event(li);
  329. t = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_TIP);
  330. litest_assert_enum_eq(libinput_event_tablet_tool_get_tip_state(t),
  331. LIBINPUT_TABLET_TOOL_TIP_DOWN);
  332. libinput_event_destroy(event);
  333. /* The button is down on init but we don't expect an event */
  334. litest_assert_empty_queue(li);
  335. litest_button_click(dev, BTN_0, false);
  336. litest_dispatch(li);
  337. litest_assert_empty_queue(li);
  338. /* but buttons after this should be sent */
  339. litest_button_click(dev, BTN_0, true);
  340. litest_dispatch(li);
  341. litest_assert_tablet_button_event(li, BTN_0, LIBINPUT_BUTTON_STATE_PRESSED);
  342. litest_button_click(dev, BTN_0, false);
  343. litest_dispatch(li);
  344. litest_assert_tablet_button_event(li, BTN_0, LIBINPUT_BUTTON_STATE_RELEASED);
  345. }
  346. END_TEST
  347. START_TEST(totem_button_up_on_delete)
  348. {
  349. _litest_context_destroy_ struct libinput *li = litest_create_context();
  350. struct litest_device *dev = litest_add_device(li, LITEST_DELL_CANVAS_TOTEM);
  351. litest_tablet_proximity_in(dev, 10, 10, NULL);
  352. litest_drain_events(li);
  353. litest_button_click(dev, BTN_0, true);
  354. litest_drain_events(li);
  355. litest_device_destroy(dev);
  356. litest_dispatch(li);
  357. litest_assert_tablet_button_event(li, BTN_0, LIBINPUT_BUTTON_STATE_RELEASED);
  358. litest_assert_tablet_tip_event(li, LIBINPUT_TABLET_TOOL_TIP_UP);
  359. litest_assert_tablet_proximity_event(li,
  360. LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
  361. }
  362. END_TEST
  363. START_TEST(totem_arbitration_below)
  364. {
  365. struct litest_device *totem = litest_current_device();
  366. struct litest_device *touch;
  367. struct libinput *li = totem->libinput;
  368. touch = litest_add_device(li, LITEST_DELL_CANVAS_TOTEM_TOUCH);
  369. litest_drain_events(li);
  370. /* touches below the totem, cancelled once the totem is down */
  371. litest_touch_down(touch, 0, 50, 50);
  372. litest_dispatch(li);
  373. litest_assert_touch_down_frame(li);
  374. litest_touch_move_to(touch, 0, 50, 50, 50, 70, 10);
  375. litest_dispatch(li);
  376. while (libinput_next_event_type(li)) {
  377. litest_assert_touch_motion_frame(li);
  378. }
  379. litest_tablet_proximity_in(totem, 50, 70, NULL);
  380. litest_dispatch(li);
  381. litest_assert_tablet_proximity_event(li,
  382. LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
  383. litest_assert_tablet_tip_event(li, LIBINPUT_TABLET_TOOL_TIP_DOWN);
  384. litest_assert_touch_cancel(li);
  385. litest_touch_move_to(touch, 0, 50, 70, 20, 50, 10);
  386. litest_assert_empty_queue(li);
  387. litest_tablet_motion(totem, 20, 50, NULL);
  388. litest_assert_only_typed_events(li, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
  389. litest_touch_up(touch, 0);
  390. litest_assert_empty_queue(li);
  391. litest_device_destroy(touch);
  392. }
  393. END_TEST
  394. START_TEST(totem_arbitration_during)
  395. {
  396. struct litest_device *totem = litest_current_device();
  397. struct litest_device *touch;
  398. struct libinput *li = totem->libinput;
  399. touch = litest_add_device(li, LITEST_DELL_CANVAS_TOTEM_TOUCH);
  400. litest_drain_events(li);
  401. litest_tablet_proximity_in(totem, 50, 50, NULL);
  402. litest_dispatch(li);
  403. litest_drain_events(li);
  404. for (int i = 0; i < 3; i++) {
  405. litest_touch_down(touch, 0, 51, 51);
  406. litest_touch_move_to(touch, 0, 51, 50, 90, 80, 10);
  407. litest_touch_up(touch, 0);
  408. litest_assert_empty_queue(li);
  409. }
  410. litest_device_destroy(touch);
  411. }
  412. END_TEST
  413. START_TEST(totem_arbitration_outside_rect)
  414. {
  415. struct litest_device *totem = litest_current_device();
  416. struct litest_device *touch;
  417. struct libinput *li = totem->libinput;
  418. touch = litest_add_device(li, LITEST_DELL_CANVAS_TOTEM_TOUCH);
  419. litest_drain_events(li);
  420. litest_tablet_proximity_in(totem, 50, 50, NULL);
  421. litest_dispatch(li);
  422. litest_drain_events(li);
  423. for (int i = 0; i < 3; i++) {
  424. litest_touch_down(touch, 0, 81, 51);
  425. litest_touch_move_to(touch, 0, 81, 50, 90, 80, 10);
  426. litest_touch_up(touch, 0);
  427. litest_dispatch(li);
  428. litest_assert_touch_sequence(li);
  429. }
  430. /* moving onto the totem is fine */
  431. litest_touch_down(touch, 0, 81, 51);
  432. litest_touch_move_to(touch, 0, 81, 50, 50, 50, 10);
  433. litest_touch_up(touch, 0);
  434. litest_dispatch(li);
  435. litest_assert_touch_sequence(li);
  436. litest_device_destroy(touch);
  437. }
  438. END_TEST
  439. START_TEST(totem_touch_size_missing_resolution)
  440. {
  441. struct libinput_device *device;
  442. /* Match the Dell Canvas Totem quirk: vendor=0x2575, product=0x0204,
  443. * name matching "*System Multi Axis", bus=USB */
  444. struct input_id id = {
  445. .bustype = 0x3,
  446. .vendor = 0x2575,
  447. .product = 0x0204,
  448. };
  449. struct input_absinfo absinfo[] = {
  450. { ABS_MT_SLOT, 0, 4, 0, 0, 0 },
  451. { ABS_MT_TOUCH_MAJOR, 0, 32767, 0, 0, 10 },
  452. { ABS_MT_TOUCH_MINOR, 0, 32767, 0, 0, 0 }, /* resolution missing */
  453. { ABS_MT_ORIENTATION, -89, 89, 0, 0, 0 },
  454. { ABS_MT_POSITION_X, 0, 32767, 0, 0, 55 },
  455. { ABS_MT_POSITION_Y, 0, 32767, 0, 0, 98 },
  456. { ABS_MT_TOOL_TYPE, 9, 10, 0, 0, 0 },
  457. { ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
  458. { -1, -1, -1, -1, -1, -1 },
  459. };
  460. /* clang-format off */
  461. int events[] = {
  462. EV_KEY, BTN_0,
  463. INPUT_PROP_MAX, INPUT_PROP_DIRECT,
  464. -1, -1,
  465. };
  466. /* clang-format on */
  467. _destroy_(libevdev_uinput) *uinput =
  468. litest_create_uinput_device_from_description(
  469. "CoolTouch System Multi Axis",
  470. &id,
  471. absinfo,
  472. events);
  473. _litest_context_destroy_ struct libinput *li = litest_create_context();
  474. litest_disable_log_handler(li);
  475. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
  476. litest_restore_log_handler(li);
  477. /* The device matches the Dell Canvas Totem quirk but has
  478. * ABS_MT_TOUCH_MINOR resolution missing. The totem dispatch
  479. * should reject it, so it must not be recognized as a tablet
  480. * tool device. */
  481. if (device)
  482. litest_assert(!libinput_device_has_capability(
  483. device,
  484. LIBINPUT_DEVICE_CAP_TABLET_TOOL));
  485. }
  486. END_TEST
  487. TEST_COLLECTION(totem)
  488. {
  489. /* clang-format off */
  490. litest_add(totem_type, LITEST_TOTEM, LITEST_ANY);
  491. litest_add(totem_axes, LITEST_TOTEM, LITEST_ANY);
  492. litest_add(totem_proximity_in_out, LITEST_TOTEM, LITEST_ANY);
  493. litest_add(totem_proximity_in_on_init, LITEST_TOTEM, LITEST_ANY);
  494. litest_add(totem_proximity_out_on_suspend, LITEST_TOTEM, LITEST_ANY);
  495. litest_add(totem_motion, LITEST_TOTEM, LITEST_ANY);
  496. litest_add(totem_rotation, LITEST_TOTEM, LITEST_ANY);
  497. litest_add(totem_size, LITEST_TOTEM, LITEST_ANY);
  498. litest_add(totem_button, LITEST_TOTEM, LITEST_ANY);
  499. litest_add(totem_button_down_on_init, LITEST_TOTEM, LITEST_ANY);
  500. litest_add_no_device(totem_button_up_on_delete);
  501. litest_add_no_device(totem_touch_size_missing_resolution);
  502. litest_add(totem_arbitration_below, LITEST_TOTEM, LITEST_ANY);
  503. litest_add(totem_arbitration_during, LITEST_TOTEM, LITEST_ANY);
  504. litest_add(totem_arbitration_outside_rect, LITEST_TOTEM, LITEST_ANY);
  505. /* clang-format on */
  506. }