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