test-path.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. /*
  2. * Copyright © 2013 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 <stdio.h>
  28. #include <sys/stat.h>
  29. #include <unistd.h>
  30. #include "libinput-util.h"
  31. #include "litest.h"
  32. struct counter {
  33. int open_func_count;
  34. int close_func_count;
  35. };
  36. static int
  37. open_restricted_count(const char *path, int flags, void *data)
  38. {
  39. struct counter *c = data;
  40. int fd;
  41. c->open_func_count++;
  42. fd = open(path, flags);
  43. return fd < 0 ? -errno : fd;
  44. }
  45. static void
  46. close_restricted_count(int fd, void *data)
  47. {
  48. struct counter *c = data;
  49. c->close_func_count++;
  50. close(fd);
  51. }
  52. static const struct libinput_interface counting_interface = {
  53. .open_restricted = open_restricted_count,
  54. .close_restricted = close_restricted_count,
  55. };
  56. static int
  57. open_restricted(const char *path, int flags, void *data)
  58. {
  59. int fd = open(path, flags);
  60. return fd < 0 ? -errno : fd;
  61. }
  62. static void
  63. close_restricted(int fd, void *data)
  64. {
  65. close(fd);
  66. }
  67. static const struct libinput_interface simple_interface = {
  68. .open_restricted = open_restricted,
  69. .close_restricted = close_restricted,
  70. };
  71. START_TEST(path_create_NULL)
  72. {
  73. struct libinput *li;
  74. struct counter counter;
  75. counter.open_func_count = 0;
  76. counter.close_func_count = 0;
  77. li = libinput_path_create_context(NULL, NULL);
  78. litest_assert(li == NULL);
  79. li = libinput_path_create_context(&counting_interface, &counter);
  80. litest_assert_notnull(li);
  81. libinput_unref(li);
  82. litest_assert_int_eq(counter.open_func_count, 0);
  83. litest_assert_int_eq(counter.close_func_count, 0);
  84. }
  85. END_TEST
  86. START_TEST(path_create_invalid)
  87. {
  88. struct libinput *li;
  89. struct libinput_device *device;
  90. const char *path = "/tmp";
  91. struct counter counter;
  92. counter.open_func_count = 0;
  93. counter.close_func_count = 0;
  94. li = libinput_path_create_context(&counting_interface, &counter);
  95. litest_assert_notnull(li);
  96. litest_disable_log_handler(li);
  97. device = libinput_path_add_device(li, path);
  98. litest_assert(device == NULL);
  99. litest_assert_int_eq(counter.open_func_count, 0);
  100. litest_assert_int_eq(counter.close_func_count, 0);
  101. litest_restore_log_handler(li);
  102. libinput_unref(li);
  103. litest_assert_int_eq(counter.close_func_count, 0);
  104. }
  105. END_TEST
  106. START_TEST(path_create_invalid_kerneldev)
  107. {
  108. struct libinput *li;
  109. struct libinput_device *device;
  110. const char *path = "/dev/uinput";
  111. struct counter counter;
  112. counter.open_func_count = 0;
  113. counter.close_func_count = 0;
  114. li = libinput_path_create_context(&counting_interface, &counter);
  115. litest_assert_notnull(li);
  116. litest_disable_log_handler(li);
  117. device = libinput_path_add_device(li, path);
  118. litest_assert(device == NULL);
  119. litest_assert_int_eq(counter.open_func_count, 1);
  120. litest_assert_int_eq(counter.close_func_count, 1);
  121. litest_restore_log_handler(li);
  122. libinput_unref(li);
  123. litest_assert_int_eq(counter.close_func_count, 1);
  124. }
  125. END_TEST
  126. START_TEST(path_create_invalid_file)
  127. {
  128. struct libinput *li;
  129. struct libinput_device *device;
  130. char path[] = "/tmp/litest_path_XXXXXX";
  131. int fd;
  132. struct counter counter;
  133. umask(002);
  134. fd = mkstemp(path);
  135. litest_assert_int_ge(fd, 0);
  136. close(fd);
  137. counter.open_func_count = 0;
  138. counter.close_func_count = 0;
  139. li = libinput_path_create_context(&counting_interface, &counter);
  140. unlink(path);
  141. litest_disable_log_handler(li);
  142. litest_assert_notnull(li);
  143. device = libinput_path_add_device(li, path);
  144. litest_assert(device == NULL);
  145. litest_assert_int_eq(counter.open_func_count, 0);
  146. litest_assert_int_eq(counter.close_func_count, 0);
  147. litest_restore_log_handler(li);
  148. libinput_unref(li);
  149. litest_assert_int_eq(counter.close_func_count, 0);
  150. }
  151. END_TEST
  152. START_TEST(path_create_pathmax_file)
  153. {
  154. struct libinput *li;
  155. struct libinput_device *device;
  156. struct counter counter;
  157. _autofree_ char *path = zalloc(PATH_MAX * 2);
  158. memset(path, 'a', PATH_MAX * 2 - 1);
  159. counter.open_func_count = 0;
  160. counter.close_func_count = 0;
  161. li = libinput_path_create_context(&counting_interface, &counter);
  162. litest_set_log_handler_bug(li);
  163. litest_assert_notnull(li);
  164. device = libinput_path_add_device(li, path);
  165. litest_assert(device == NULL);
  166. litest_assert_int_eq(counter.open_func_count, 0);
  167. litest_assert_int_eq(counter.close_func_count, 0);
  168. litest_restore_log_handler(li);
  169. libinput_unref(li);
  170. litest_assert_int_eq(counter.close_func_count, 0);
  171. }
  172. END_TEST
  173. START_TEST(path_create_destroy)
  174. {
  175. struct libinput *li;
  176. struct libinput_device *device;
  177. struct libevdev_uinput *uinput;
  178. struct counter counter;
  179. counter.open_func_count = 0;
  180. counter.close_func_count = 0;
  181. /* clang-format off */
  182. uinput = litest_create_uinput_device("test device", NULL,
  183. EV_KEY, BTN_LEFT,
  184. EV_KEY, BTN_RIGHT,
  185. EV_REL, REL_X,
  186. EV_REL, REL_Y,
  187. -1);
  188. /* clang-format on */
  189. li = libinput_path_create_context(&counting_interface, &counter);
  190. litest_assert_notnull(li);
  191. litest_disable_log_handler(li);
  192. litest_assert(libinput_get_user_data(li) == &counter);
  193. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
  194. litest_assert_notnull(device);
  195. litest_assert_int_eq(counter.open_func_count, 1);
  196. libevdev_uinput_destroy(uinput);
  197. libinput_unref(li);
  198. litest_assert_int_eq(counter.close_func_count, 1);
  199. }
  200. END_TEST
  201. START_TEST(path_force_destroy)
  202. {
  203. struct litest_device *dev = litest_current_device();
  204. struct libinput *li;
  205. struct libinput_device *device;
  206. li = libinput_path_create_context(&simple_interface, NULL);
  207. litest_assert_notnull(li);
  208. libinput_ref(li);
  209. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
  210. litest_assert_notnull(device);
  211. while (libinput_unref(li) != NULL)
  212. ;
  213. }
  214. END_TEST
  215. START_TEST(path_set_user_data)
  216. {
  217. struct libinput *li;
  218. int data1, data2;
  219. li = libinput_path_create_context(&simple_interface, &data1);
  220. litest_assert_notnull(li);
  221. litest_assert(libinput_get_user_data(li) == &data1);
  222. libinput_set_user_data(li, &data2);
  223. litest_assert(libinput_get_user_data(li) == &data2);
  224. libinput_unref(li);
  225. }
  226. END_TEST
  227. START_TEST(path_added_seat)
  228. {
  229. struct litest_device *dev = litest_current_device();
  230. struct libinput *li = dev->libinput;
  231. struct libinput_event *event;
  232. struct libinput_device *device;
  233. struct libinput_seat *seat;
  234. const char *seat_name;
  235. litest_dispatch(li);
  236. event = libinput_get_event(li);
  237. litest_assert_notnull(event);
  238. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  239. device = libinput_event_get_device(event);
  240. seat = libinput_device_get_seat(device);
  241. litest_assert_notnull(seat);
  242. seat_name = libinput_seat_get_logical_name(seat);
  243. litest_assert_str_eq(seat_name, "default");
  244. libinput_event_destroy(event);
  245. }
  246. END_TEST
  247. START_TEST(path_seat_change)
  248. {
  249. struct litest_device *dev = litest_current_device();
  250. struct libinput *li = dev->libinput;
  251. struct libinput_event *event;
  252. struct libinput_device *device;
  253. struct libinput_seat *seat1, *seat2;
  254. const char *seat1_name;
  255. const char *seat2_name = "new seat";
  256. int rc;
  257. litest_dispatch(li);
  258. event = libinput_get_event(li);
  259. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  260. device = libinput_event_get_device(event);
  261. libinput_device_ref(device);
  262. seat1 = libinput_device_get_seat(device);
  263. libinput_seat_ref(seat1);
  264. seat1_name = libinput_seat_get_logical_name(seat1);
  265. libinput_event_destroy(event);
  266. litest_drain_events(li);
  267. rc = libinput_device_set_seat_logical_name(device, seat2_name);
  268. litest_assert_int_eq(rc, 0);
  269. litest_dispatch(li);
  270. event = libinput_get_event(li);
  271. litest_assert_notnull(event);
  272. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
  273. litest_assert(libinput_event_get_device(event) == device);
  274. libinput_event_destroy(event);
  275. event = libinput_get_event(li);
  276. litest_assert_notnull(event);
  277. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  278. litest_assert(libinput_event_get_device(event) != device);
  279. libinput_device_unref(device);
  280. device = libinput_event_get_device(event);
  281. seat2 = libinput_device_get_seat(device);
  282. litest_assert_str_ne(libinput_seat_get_logical_name(seat2), seat1_name);
  283. litest_assert_str_eq(libinput_seat_get_logical_name(seat2), seat2_name);
  284. libinput_event_destroy(event);
  285. libinput_seat_unref(seat1);
  286. /* litest: swap the new device in, so cleanup works */
  287. libinput_device_unref(dev->libinput_device);
  288. libinput_device_ref(device);
  289. dev->libinput_device = device;
  290. }
  291. END_TEST
  292. START_TEST(path_added_device)
  293. {
  294. struct litest_device *dev = litest_current_device();
  295. struct libinput *li = dev->libinput;
  296. struct libinput_event *event;
  297. struct libinput_device *device;
  298. litest_dispatch(li);
  299. event = libinput_get_event(li);
  300. litest_assert_notnull(event);
  301. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  302. device = libinput_event_get_device(event);
  303. litest_assert_notnull(device);
  304. libinput_event_destroy(event);
  305. }
  306. END_TEST
  307. START_TEST(path_add_device)
  308. {
  309. struct litest_device *dev = litest_current_device();
  310. struct libinput *li = dev->libinput;
  311. struct libinput_event *event;
  312. struct libinput_device *device;
  313. litest_dispatch(li);
  314. event = libinput_get_event(li);
  315. litest_assert_notnull(event);
  316. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  317. device = libinput_event_get_device(event);
  318. litest_assert_notnull(device);
  319. _autofree_ char *sysname1 = safe_strdup(libinput_device_get_sysname(device));
  320. libinput_event_destroy(event);
  321. litest_assert_empty_queue(li);
  322. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
  323. litest_assert_notnull(device);
  324. litest_dispatch(li);
  325. event = libinput_get_event(li);
  326. litest_assert_notnull(event);
  327. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  328. device = libinput_event_get_device(event);
  329. litest_assert_notnull(device);
  330. _autofree_ char *sysname2 = safe_strdup(libinput_device_get_sysname(device));
  331. libinput_event_destroy(event);
  332. litest_assert_str_eq(sysname1, sysname2);
  333. }
  334. END_TEST
  335. START_TEST(path_add_invalid_path)
  336. {
  337. struct libinput_device *device;
  338. _litest_context_destroy_ struct libinput *li = litest_create_context();
  339. litest_disable_log_handler(li);
  340. device = libinput_path_add_device(li, "/tmp/");
  341. litest_restore_log_handler(li);
  342. litest_assert(device == NULL);
  343. litest_dispatch(li);
  344. litest_assert_empty_queue(li);
  345. }
  346. END_TEST
  347. START_TEST(path_device_sysname)
  348. {
  349. struct litest_device *dev = litest_current_device();
  350. struct libinput_event *ev;
  351. struct libinput_device *device;
  352. const char *sysname;
  353. litest_dispatch(dev->libinput);
  354. ev = libinput_get_event(dev->libinput);
  355. litest_assert_notnull(ev);
  356. litest_assert_event_type(ev, LIBINPUT_EVENT_DEVICE_ADDED);
  357. device = libinput_event_get_device(ev);
  358. litest_assert_notnull(device);
  359. sysname = libinput_device_get_sysname(device);
  360. litest_assert_notnull(sysname);
  361. litest_assert_int_gt(strlen(sysname), 1U);
  362. litest_assert(strchr(sysname, '/') == NULL);
  363. litest_assert(strstartswith(sysname, "event"));
  364. libinput_event_destroy(ev);
  365. }
  366. END_TEST
  367. START_TEST(path_remove_device)
  368. {
  369. struct litest_device *dev = litest_current_device();
  370. struct libinput *li = dev->libinput;
  371. struct libinput_event *event;
  372. struct libinput_device *device;
  373. int remove_event = 0;
  374. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
  375. litest_assert_notnull(device);
  376. litest_drain_events(li);
  377. libinput_path_remove_device(device);
  378. litest_dispatch(li);
  379. while ((event = libinput_get_event(li))) {
  380. enum libinput_event_type type;
  381. type = libinput_event_get_type(event);
  382. if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
  383. remove_event++;
  384. libinput_event_destroy(event);
  385. }
  386. litest_assert_int_eq(remove_event, 1);
  387. }
  388. END_TEST
  389. START_TEST(path_double_remove_device)
  390. {
  391. struct litest_device *dev = litest_current_device();
  392. struct libinput *li = dev->libinput;
  393. struct libinput_event *event;
  394. struct libinput_device *device;
  395. int remove_event = 0;
  396. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
  397. litest_assert_notnull(device);
  398. litest_drain_events(li);
  399. libinput_path_remove_device(device);
  400. libinput_path_remove_device(device);
  401. litest_dispatch(li);
  402. while ((event = libinput_get_event(li))) {
  403. enum libinput_event_type type;
  404. type = libinput_event_get_type(event);
  405. if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
  406. remove_event++;
  407. libinput_event_destroy(event);
  408. }
  409. litest_assert_int_eq(remove_event, 1);
  410. }
  411. END_TEST
  412. START_TEST(path_suspend)
  413. {
  414. struct libinput *li;
  415. struct libinput_device *device;
  416. struct libevdev_uinput *uinput;
  417. int rc;
  418. void *userdata = &rc;
  419. /* clang-format off */
  420. uinput = litest_create_uinput_device("test device", NULL,
  421. EV_KEY, BTN_LEFT,
  422. EV_KEY, BTN_RIGHT,
  423. EV_REL, REL_X,
  424. EV_REL, REL_Y,
  425. -1);
  426. /* clang-format on */
  427. li = libinput_path_create_context(&simple_interface, userdata);
  428. litest_assert_notnull(li);
  429. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
  430. litest_assert_notnull(device);
  431. libinput_suspend(li);
  432. libinput_resume(li);
  433. libevdev_uinput_destroy(uinput);
  434. libinput_unref(li);
  435. }
  436. END_TEST
  437. START_TEST(path_double_suspend)
  438. {
  439. struct libinput *li;
  440. struct libinput_device *device;
  441. struct libevdev_uinput *uinput;
  442. int rc;
  443. void *userdata = &rc;
  444. /* clang-format off */
  445. uinput = litest_create_uinput_device("test device", NULL,
  446. EV_KEY, BTN_LEFT,
  447. EV_KEY, BTN_RIGHT,
  448. EV_REL, REL_X,
  449. EV_REL, REL_Y,
  450. -1);
  451. /* clang-format on */
  452. li = libinput_path_create_context(&simple_interface, userdata);
  453. litest_assert_notnull(li);
  454. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
  455. litest_assert_notnull(device);
  456. libinput_suspend(li);
  457. libinput_suspend(li);
  458. libinput_resume(li);
  459. libevdev_uinput_destroy(uinput);
  460. libinput_unref(li);
  461. }
  462. END_TEST
  463. START_TEST(path_double_resume)
  464. {
  465. struct libinput *li;
  466. struct libinput_device *device;
  467. struct libevdev_uinput *uinput;
  468. int rc;
  469. void *userdata = &rc;
  470. /* clang-format off */
  471. uinput = litest_create_uinput_device("test device", NULL,
  472. EV_KEY, BTN_LEFT,
  473. EV_KEY, BTN_RIGHT,
  474. EV_REL, REL_X,
  475. EV_REL, REL_Y,
  476. -1);
  477. /* clang-format on */
  478. li = libinput_path_create_context(&simple_interface, userdata);
  479. litest_assert_notnull(li);
  480. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
  481. litest_assert_notnull(device);
  482. libinput_suspend(li);
  483. libinput_resume(li);
  484. libinput_resume(li);
  485. libevdev_uinput_destroy(uinput);
  486. libinput_unref(li);
  487. }
  488. END_TEST
  489. START_TEST(path_add_device_suspend_resume)
  490. {
  491. struct libinput *li;
  492. struct libinput_device *device;
  493. struct libinput_event *event;
  494. struct libevdev_uinput *uinput1, *uinput2;
  495. int rc;
  496. int nevents;
  497. void *userdata = &rc;
  498. /* clang-format off */
  499. uinput1 = litest_create_uinput_device("test device", NULL,
  500. EV_KEY, BTN_LEFT,
  501. EV_KEY, BTN_RIGHT,
  502. EV_REL, REL_X,
  503. EV_REL, REL_Y,
  504. -1);
  505. uinput2 = litest_create_uinput_device("test device 2", NULL,
  506. EV_KEY, BTN_LEFT,
  507. EV_KEY, BTN_RIGHT,
  508. EV_REL, REL_X,
  509. EV_REL, REL_Y,
  510. -1);
  511. /* clang-format on */
  512. li = libinput_path_create_context(&simple_interface, userdata);
  513. litest_assert_notnull(li);
  514. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput1));
  515. litest_assert_notnull(device);
  516. libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
  517. litest_dispatch(li);
  518. nevents = 0;
  519. while ((event = libinput_get_event(li))) {
  520. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  521. libinput_event_destroy(event);
  522. nevents++;
  523. }
  524. litest_assert_int_eq(nevents, 2);
  525. libinput_suspend(li);
  526. litest_dispatch(li);
  527. nevents = 0;
  528. while ((event = libinput_get_event(li))) {
  529. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
  530. libinput_event_destroy(event);
  531. nevents++;
  532. }
  533. litest_assert_int_eq(nevents, 2);
  534. libinput_resume(li);
  535. litest_dispatch(li);
  536. nevents = 0;
  537. while ((event = libinput_get_event(li))) {
  538. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  539. libinput_event_destroy(event);
  540. nevents++;
  541. }
  542. litest_assert_int_eq(nevents, 2);
  543. libevdev_uinput_destroy(uinput1);
  544. libevdev_uinput_destroy(uinput2);
  545. libinput_unref(li);
  546. }
  547. END_TEST
  548. START_TEST(path_add_device_suspend_resume_fail)
  549. {
  550. struct libinput *li;
  551. struct libinput_device *device;
  552. struct libinput_event *event;
  553. struct libevdev_uinput *uinput1, *uinput2;
  554. int rc;
  555. int nevents;
  556. void *userdata = &rc;
  557. /* clang-format off */
  558. uinput1 = litest_create_uinput_device("test device", NULL,
  559. EV_KEY, BTN_LEFT,
  560. EV_KEY, BTN_RIGHT,
  561. EV_REL, REL_X,
  562. EV_REL, REL_Y,
  563. -1);
  564. uinput2 = litest_create_uinput_device("test device 2", NULL,
  565. EV_KEY, BTN_LEFT,
  566. EV_KEY, BTN_RIGHT,
  567. EV_REL, REL_X,
  568. EV_REL, REL_Y,
  569. -1);
  570. /* clang-format on */
  571. li = libinput_path_create_context(&simple_interface, userdata);
  572. litest_assert_notnull(li);
  573. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput1));
  574. litest_assert_notnull(device);
  575. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
  576. litest_assert_notnull(device);
  577. litest_dispatch(li);
  578. nevents = 0;
  579. while ((event = libinput_get_event(li))) {
  580. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  581. libinput_event_destroy(event);
  582. nevents++;
  583. }
  584. litest_assert_int_eq(nevents, 2);
  585. libinput_suspend(li);
  586. litest_dispatch(li);
  587. nevents = 0;
  588. while ((event = libinput_get_event(li))) {
  589. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
  590. libinput_event_destroy(event);
  591. nevents++;
  592. }
  593. litest_assert_int_eq(nevents, 2);
  594. /* now drop one of the devices */
  595. libevdev_uinput_destroy(uinput1);
  596. rc = libinput_resume(li);
  597. litest_assert_int_eq(rc, -1);
  598. litest_dispatch(li);
  599. nevents = 0;
  600. while ((event = libinput_get_event(li))) {
  601. enum libinput_event_type type;
  602. type = libinput_event_get_type(event);
  603. /* We expect one device being added, second one fails,
  604. * causing a removed event for the first one */
  605. if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
  606. type != LIBINPUT_EVENT_DEVICE_REMOVED)
  607. litest_abort_msg("Unexpected event type");
  608. libinput_event_destroy(event);
  609. nevents++;
  610. }
  611. litest_assert_int_eq(nevents, 2);
  612. libevdev_uinput_destroy(uinput2);
  613. libinput_unref(li);
  614. }
  615. END_TEST
  616. START_TEST(path_add_device_suspend_resume_remove_device)
  617. {
  618. struct libinput *li;
  619. struct libinput_device *device;
  620. struct libinput_event *event;
  621. struct libevdev_uinput *uinput1, *uinput2;
  622. int rc;
  623. int nevents;
  624. void *userdata = &rc;
  625. /* clang-format off */
  626. uinput1 = litest_create_uinput_device("test device", NULL,
  627. EV_KEY, BTN_LEFT,
  628. EV_KEY, BTN_RIGHT,
  629. EV_REL, REL_X,
  630. EV_REL, REL_Y,
  631. -1);
  632. uinput2 = litest_create_uinput_device("test device 2", NULL,
  633. EV_KEY, BTN_LEFT,
  634. EV_KEY, BTN_RIGHT,
  635. EV_REL, REL_X,
  636. EV_REL, REL_Y,
  637. -1);
  638. /* clang-format on */
  639. li = libinput_path_create_context(&simple_interface, userdata);
  640. litest_assert_notnull(li);
  641. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput1));
  642. litest_assert_notnull(device);
  643. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
  644. libinput_device_ref(device);
  645. litest_dispatch(li);
  646. nevents = 0;
  647. while ((event = libinput_get_event(li))) {
  648. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  649. libinput_event_destroy(event);
  650. nevents++;
  651. }
  652. litest_assert_int_eq(nevents, 2);
  653. libinput_suspend(li);
  654. litest_dispatch(li);
  655. nevents = 0;
  656. while ((event = libinput_get_event(li))) {
  657. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
  658. libinput_event_destroy(event);
  659. nevents++;
  660. }
  661. litest_assert_int_eq(nevents, 2);
  662. /* now drop and remove one of the devices */
  663. libevdev_uinput_destroy(uinput2);
  664. libinput_path_remove_device(device);
  665. libinput_device_unref(device);
  666. rc = libinput_resume(li);
  667. litest_assert_int_eq(rc, 0);
  668. litest_dispatch(li);
  669. nevents = 0;
  670. while ((event = libinput_get_event(li))) {
  671. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
  672. libinput_event_destroy(event);
  673. nevents++;
  674. }
  675. litest_assert_int_eq(nevents, 1);
  676. libevdev_uinput_destroy(uinput1);
  677. libinput_unref(li);
  678. }
  679. END_TEST
  680. START_TEST(path_device_gone)
  681. {
  682. struct libinput *li;
  683. struct libinput_device *device;
  684. struct libevdev_uinput *uinput;
  685. struct libinput_event *event;
  686. /* clang-format off */
  687. uinput = litest_create_uinput_device("test device", NULL,
  688. EV_KEY, BTN_LEFT,
  689. EV_KEY, BTN_RIGHT,
  690. EV_REL, REL_X,
  691. EV_REL, REL_Y,
  692. -1);
  693. /* clang-format on */
  694. li = libinput_path_create_context(&simple_interface, NULL);
  695. litest_assert_notnull(li);
  696. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
  697. litest_assert_notnull(device);
  698. litest_drain_events(li);
  699. libevdev_uinput_destroy(uinput);
  700. litest_dispatch(li);
  701. event = libinput_get_event(li);
  702. litest_assert_notnull(event);
  703. litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
  704. libinput_event_destroy(event);
  705. libinput_unref(li);
  706. }
  707. END_TEST
  708. START_TEST(path_seat_recycle)
  709. {
  710. struct libinput *li;
  711. struct libevdev_uinput *uinput;
  712. int rc;
  713. void *userdata = &rc;
  714. struct libinput_event *ev;
  715. struct libinput_device *device;
  716. struct libinput_seat *saved_seat = NULL;
  717. struct libinput_seat *seat;
  718. int data = 0;
  719. int found = 0;
  720. void *user_data;
  721. /* clang-format off */
  722. uinput = litest_create_uinput_device("test device", NULL,
  723. EV_KEY, BTN_LEFT,
  724. EV_KEY, BTN_RIGHT,
  725. EV_REL, REL_X,
  726. EV_REL, REL_Y,
  727. -1);
  728. /* clang-format on */
  729. li = libinput_path_create_context(&simple_interface, userdata);
  730. litest_assert_notnull(li);
  731. device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
  732. litest_assert_notnull(device);
  733. litest_dispatch(li);
  734. ev = libinput_get_event(li);
  735. litest_assert_notnull(ev);
  736. litest_assert_event_type(ev, LIBINPUT_EVENT_DEVICE_ADDED);
  737. device = libinput_event_get_device(ev);
  738. litest_assert_notnull(device);
  739. saved_seat = libinput_device_get_seat(device);
  740. libinput_seat_set_user_data(saved_seat, &data);
  741. libinput_seat_ref(saved_seat);
  742. libinput_event_destroy(ev);
  743. litest_assert_notnull(saved_seat);
  744. litest_assert_empty_queue(li);
  745. libinput_suspend(li);
  746. litest_drain_events(li);
  747. libinput_resume(li);
  748. litest_dispatch(li);
  749. ev = libinput_get_event(li);
  750. litest_assert_notnull(ev);
  751. litest_assert_event_type(ev, LIBINPUT_EVENT_DEVICE_ADDED);
  752. device = libinput_event_get_device(ev);
  753. litest_assert_notnull(device);
  754. seat = libinput_device_get_seat(device);
  755. user_data = libinput_seat_get_user_data(seat);
  756. if (user_data == &data) {
  757. found = 1;
  758. litest_assert(seat == saved_seat);
  759. }
  760. libinput_event_destroy(ev);
  761. litest_assert(found == 1);
  762. libinput_unref(li);
  763. libevdev_uinput_destroy(uinput);
  764. }
  765. END_TEST
  766. START_TEST(path_udev_assign_seat)
  767. {
  768. struct litest_device *dev = litest_current_device();
  769. struct libinput *li = dev->libinput;
  770. int rc;
  771. litest_set_log_handler_bug(li);
  772. rc = libinput_udev_assign_seat(li, "foo");
  773. litest_assert_int_eq(rc, -1);
  774. litest_restore_log_handler(li);
  775. }
  776. END_TEST
  777. START_TEST(path_ignore_device)
  778. {
  779. struct litest_device *dev;
  780. struct libinput_device *device;
  781. const char *path;
  782. dev = litest_create(LITEST_IGNORED_MOUSE, NULL, NULL, NULL, NULL);
  783. path = libevdev_uinput_get_devnode(dev->uinput);
  784. litest_assert_notnull(path);
  785. _litest_context_destroy_ struct libinput *li = litest_create_context();
  786. device = libinput_path_add_device(li, path);
  787. litest_assert(device == NULL);
  788. litest_device_destroy(dev);
  789. }
  790. END_TEST
  791. TEST_COLLECTION(path)
  792. {
  793. /* clang-format off */
  794. litest_add_no_device(path_create_NULL);
  795. litest_add_no_device(path_create_invalid);
  796. litest_add_no_device(path_create_invalid_file);
  797. litest_add_no_device(path_create_invalid_kerneldev);
  798. litest_add_no_device(path_create_pathmax_file);
  799. litest_add_no_device(path_create_destroy);
  800. litest_add(path_force_destroy, LITEST_ANY, LITEST_ANY);
  801. litest_add_no_device(path_set_user_data);
  802. litest_add_no_device(path_suspend);
  803. litest_add_no_device(path_double_suspend);
  804. litest_add_no_device(path_double_resume);
  805. litest_add_no_device(path_add_device_suspend_resume);
  806. litest_add_no_device(path_add_device_suspend_resume_fail);
  807. litest_add_no_device(path_add_device_suspend_resume_remove_device);
  808. litest_add_for_device(path_added_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
  809. litest_add_for_device(path_seat_change, LITEST_SYNAPTICS_CLICKPAD_X220);
  810. litest_add(path_added_device, LITEST_ANY, LITEST_ANY);
  811. litest_add(path_device_sysname, LITEST_ANY, LITEST_ANY);
  812. litest_add_for_device(path_add_device, LITEST_SYNAPTICS_CLICKPAD_X220);
  813. litest_add_no_device(path_add_invalid_path);
  814. litest_add_for_device(path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
  815. litest_add_for_device(path_double_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
  816. litest_add_no_device(path_device_gone);
  817. litest_add_no_device(path_seat_recycle);
  818. litest_add_for_device(path_udev_assign_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
  819. litest_add_no_device(path_ignore_device);
  820. /* clang-format on */
  821. }