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_notnull(li);
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_notnull(li);
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_notnull(li);
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_notnull(li);
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_pathmax_file)193 START_TEST(path_create_pathmax_file)
194 {
195 struct libinput *li;
196 struct libinput_device *device;
197 char *path;
198 struct counter counter;
199
200 path = zalloc(PATH_MAX * 2);
201 memset(path, 'a', PATH_MAX * 2 - 1);
202
203 counter.open_func_count = 0;
204 counter.close_func_count = 0;
205
206 li = libinput_path_create_context(&counting_interface, &counter);
207
208 litest_set_log_handler_bug(li);
209 ck_assert_notnull(li);
210 device = libinput_path_add_device(li, path);
211 ck_assert(device == NULL);
212
213 ck_assert_int_eq(counter.open_func_count, 0);
214 ck_assert_int_eq(counter.close_func_count, 0);
215
216 litest_restore_log_handler(li);
217 libinput_unref(li);
218 ck_assert_int_eq(counter.close_func_count, 0);
219
220 free(path);
221 }
222 END_TEST
223
224
START_TEST(path_create_destroy)225 START_TEST(path_create_destroy)
226 {
227 struct libinput *li;
228 struct libinput_device *device;
229 struct libevdev_uinput *uinput;
230 struct counter counter;
231
232 counter.open_func_count = 0;
233 counter.close_func_count = 0;
234
235 uinput = litest_create_uinput_device("test device", NULL,
236 EV_KEY, BTN_LEFT,
237 EV_KEY, BTN_RIGHT,
238 EV_REL, REL_X,
239 EV_REL, REL_Y,
240 -1);
241
242 li = libinput_path_create_context(&counting_interface, &counter);
243 ck_assert_notnull(li);
244
245 litest_disable_log_handler(li);
246
247 ck_assert(libinput_get_user_data(li) == &counter);
248
249 device = libinput_path_add_device(li,
250 libevdev_uinput_get_devnode(uinput));
251 ck_assert_notnull(device);
252
253 ck_assert_int_eq(counter.open_func_count, 1);
254
255 libevdev_uinput_destroy(uinput);
256 libinput_unref(li);
257 ck_assert_int_eq(counter.close_func_count, 1);
258 }
259 END_TEST
260
START_TEST(path_force_destroy)261 START_TEST(path_force_destroy)
262 {
263 struct litest_device *dev = litest_current_device();
264 struct libinput *li;
265 struct libinput_device *device;
266
267 li = libinput_path_create_context(&simple_interface, NULL);
268 ck_assert_notnull(li);
269 libinput_ref(li);
270 device = libinput_path_add_device(li,
271 libevdev_uinput_get_devnode(dev->uinput));
272 ck_assert_notnull(device);
273
274 while (libinput_unref(li) != NULL)
275 ;
276 }
277 END_TEST
278
START_TEST(path_set_user_data)279 START_TEST(path_set_user_data)
280 {
281 struct libinput *li;
282 int data1, data2;
283
284 li = libinput_path_create_context(&simple_interface, &data1);
285 ck_assert_notnull(li);
286 ck_assert(libinput_get_user_data(li) == &data1);
287 libinput_set_user_data(li, &data2);
288 ck_assert(libinput_get_user_data(li) == &data2);
289
290 libinput_unref(li);
291 }
292 END_TEST
293
START_TEST(path_added_seat)294 START_TEST(path_added_seat)
295 {
296 struct litest_device *dev = litest_current_device();
297 struct libinput *li = dev->libinput;
298 struct libinput_event *event;
299 struct libinput_device *device;
300 struct libinput_seat *seat;
301 const char *seat_name;
302 enum libinput_event_type type;
303
304 libinput_dispatch(li);
305
306 event = libinput_get_event(li);
307 ck_assert_notnull(event);
308
309 type = libinput_event_get_type(event);
310 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
311
312 device = libinput_event_get_device(event);
313 seat = libinput_device_get_seat(device);
314 ck_assert_notnull(seat);
315
316 seat_name = libinput_seat_get_logical_name(seat);
317 ck_assert_str_eq(seat_name, "default");
318
319 libinput_event_destroy(event);
320 }
321 END_TEST
322
START_TEST(path_seat_change)323 START_TEST(path_seat_change)
324 {
325 struct litest_device *dev = litest_current_device();
326 struct libinput *li = dev->libinput;
327 struct libinput_event *event;
328 struct libinput_device *device;
329 struct libinput_seat *seat1, *seat2;
330 const char *seat1_name;
331 const char *seat2_name = "new seat";
332 int rc;
333
334 libinput_dispatch(li);
335
336 event = libinput_get_event(li);
337 ck_assert_int_eq(libinput_event_get_type(event),
338 LIBINPUT_EVENT_DEVICE_ADDED);
339
340 device = libinput_event_get_device(event);
341 libinput_device_ref(device);
342
343 seat1 = libinput_device_get_seat(device);
344 libinput_seat_ref(seat1);
345
346 seat1_name = libinput_seat_get_logical_name(seat1);
347 libinput_event_destroy(event);
348
349 litest_drain_events(li);
350
351 rc = libinput_device_set_seat_logical_name(device,
352 seat2_name);
353 ck_assert_int_eq(rc, 0);
354
355 libinput_dispatch(li);
356
357 event = libinput_get_event(li);
358 ck_assert_notnull(event);
359
360 ck_assert_int_eq(libinput_event_get_type(event),
361 LIBINPUT_EVENT_DEVICE_REMOVED);
362
363 ck_assert(libinput_event_get_device(event) == device);
364 libinput_event_destroy(event);
365
366 event = libinput_get_event(li);
367 ck_assert_notnull(event);
368 ck_assert_int_eq(libinput_event_get_type(event),
369 LIBINPUT_EVENT_DEVICE_ADDED);
370 ck_assert(libinput_event_get_device(event) != device);
371 libinput_device_unref(device);
372
373 device = libinput_event_get_device(event);
374 seat2 = libinput_device_get_seat(device);
375
376 ck_assert_str_ne(libinput_seat_get_logical_name(seat2),
377 seat1_name);
378 ck_assert_str_eq(libinput_seat_get_logical_name(seat2),
379 seat2_name);
380 libinput_event_destroy(event);
381
382 libinput_seat_unref(seat1);
383
384 /* litest: swap the new device in, so cleanup works */
385 libinput_device_unref(dev->libinput_device);
386 libinput_device_ref(device);
387 dev->libinput_device = device;
388 }
389 END_TEST
390
START_TEST(path_added_device)391 START_TEST(path_added_device)
392 {
393 struct litest_device *dev = litest_current_device();
394 struct libinput *li = dev->libinput;
395 struct libinput_event *event;
396 struct libinput_device *device;
397 enum libinput_event_type type;
398
399 libinput_dispatch(li);
400
401 event = libinput_get_event(li);
402 ck_assert_notnull(event);
403 type = libinput_event_get_type(event);
404 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
405 device = libinput_event_get_device(event);
406 ck_assert_notnull(device);
407
408 libinput_event_destroy(event);
409 }
410 END_TEST
411
START_TEST(path_add_device)412 START_TEST(path_add_device)
413 {
414 struct litest_device *dev = litest_current_device();
415 struct libinput *li = dev->libinput;
416 struct libinput_event *event;
417 struct libinput_device *device;
418 char *sysname1 = NULL, *sysname2 = NULL;
419 enum libinput_event_type type;
420
421 libinput_dispatch(li);
422
423 event = libinput_get_event(li);
424 ck_assert_notnull(event);
425 type = libinput_event_get_type(event);
426 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
427 device = libinput_event_get_device(event);
428 ck_assert_notnull(device);
429 sysname1 = safe_strdup(libinput_device_get_sysname(device));
430 libinput_event_destroy(event);
431
432 litest_assert_empty_queue(li);
433
434 device = libinput_path_add_device(li,
435 libevdev_uinput_get_devnode(dev->uinput));
436 ck_assert_notnull(device);
437
438 libinput_dispatch(li);
439
440 event = libinput_get_event(li);
441 ck_assert_notnull(event);
442 type = libinput_event_get_type(event);
443 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
444 device = libinput_event_get_device(event);
445 ck_assert_notnull(device);
446 sysname2 = safe_strdup(libinput_device_get_sysname(device));
447 libinput_event_destroy(event);
448
449 ck_assert_str_eq(sysname1, sysname2);
450
451 free(sysname1);
452 free(sysname2);
453 }
454 END_TEST
455
START_TEST(path_add_invalid_path)456 START_TEST(path_add_invalid_path)
457 {
458 struct libinput *li;
459 struct libinput_device *device;
460
461 li = litest_create_context();
462
463 litest_disable_log_handler(li);
464 device = libinput_path_add_device(li, "/tmp/");
465 litest_restore_log_handler(li);
466 ck_assert(device == NULL);
467
468 libinput_dispatch(li);
469
470 litest_assert_empty_queue(li);
471
472 litest_destroy_context(li);
473 }
474 END_TEST
475
START_TEST(path_device_sysname)476 START_TEST(path_device_sysname)
477 {
478 struct litest_device *dev = litest_current_device();
479 struct libinput_event *ev;
480 struct libinput_device *device;
481 const char *sysname;
482 enum libinput_event_type type;
483
484 libinput_dispatch(dev->libinput);
485
486 ev = libinput_get_event(dev->libinput);
487 ck_assert_notnull(ev);
488 type = libinput_event_get_type(ev);
489 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
490 device = libinput_event_get_device(ev);
491 ck_assert_notnull(device);
492 sysname = libinput_device_get_sysname(device);
493
494 ck_assert_notnull(sysname);
495 ck_assert_int_gt(strlen(sysname), 1);
496 ck_assert(strchr(sysname, '/') == NULL);
497 ck_assert(strneq(sysname, "event", 5));
498
499 libinput_event_destroy(ev);
500 }
501 END_TEST
502
START_TEST(path_remove_device)503 START_TEST(path_remove_device)
504 {
505 struct litest_device *dev = litest_current_device();
506 struct libinput *li = dev->libinput;
507 struct libinput_event *event;
508 struct libinput_device *device;
509 int remove_event = 0;
510
511 device = libinput_path_add_device(li,
512 libevdev_uinput_get_devnode(dev->uinput));
513 ck_assert_notnull(device);
514 litest_drain_events(li);
515
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_double_remove_device)533 START_TEST(path_double_remove_device)
534 {
535 struct litest_device *dev = litest_current_device();
536 struct libinput *li = dev->libinput;
537 struct libinput_event *event;
538 struct libinput_device *device;
539 int remove_event = 0;
540
541 device = libinput_path_add_device(li,
542 libevdev_uinput_get_devnode(dev->uinput));
543 ck_assert_notnull(device);
544 litest_drain_events(li);
545
546 libinput_path_remove_device(device);
547 libinput_path_remove_device(device);
548 libinput_dispatch(li);
549
550 while ((event = libinput_get_event(li))) {
551 enum libinput_event_type type;
552 type = libinput_event_get_type(event);
553
554 if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
555 remove_event++;
556
557 libinput_event_destroy(event);
558 }
559
560 ck_assert_int_eq(remove_event, 1);
561 }
562 END_TEST
563
START_TEST(path_suspend)564 START_TEST(path_suspend)
565 {
566 struct libinput *li;
567 struct libinput_device *device;
568 struct libevdev_uinput *uinput;
569 int rc;
570 void *userdata = &rc;
571
572 uinput = litest_create_uinput_device("test device", NULL,
573 EV_KEY, BTN_LEFT,
574 EV_KEY, BTN_RIGHT,
575 EV_REL, REL_X,
576 EV_REL, REL_Y,
577 -1);
578
579 li = libinput_path_create_context(&simple_interface, userdata);
580 ck_assert_notnull(li);
581
582 device = libinput_path_add_device(li,
583 libevdev_uinput_get_devnode(uinput));
584 ck_assert_notnull(device);
585
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_suspend)594 START_TEST(path_double_suspend)
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_notnull(li);
611
612 device = libinput_path_add_device(li,
613 libevdev_uinput_get_devnode(uinput));
614 ck_assert_notnull(device);
615
616 libinput_suspend(li);
617 libinput_suspend(li);
618 libinput_resume(li);
619
620 libevdev_uinput_destroy(uinput);
621 libinput_unref(li);
622 }
623 END_TEST
624
START_TEST(path_double_resume)625 START_TEST(path_double_resume)
626 {
627 struct libinput *li;
628 struct libinput_device *device;
629 struct libevdev_uinput *uinput;
630 int rc;
631 void *userdata = &rc;
632
633 uinput = litest_create_uinput_device("test device", NULL,
634 EV_KEY, BTN_LEFT,
635 EV_KEY, BTN_RIGHT,
636 EV_REL, REL_X,
637 EV_REL, REL_Y,
638 -1);
639
640 li = libinput_path_create_context(&simple_interface, userdata);
641 ck_assert_notnull(li);
642
643 device = libinput_path_add_device(li,
644 libevdev_uinput_get_devnode(uinput));
645 ck_assert_notnull(device);
646
647 libinput_suspend(li);
648 libinput_resume(li);
649 libinput_resume(li);
650
651 libevdev_uinput_destroy(uinput);
652 libinput_unref(li);
653 }
654 END_TEST
655
START_TEST(path_add_device_suspend_resume)656 START_TEST(path_add_device_suspend_resume)
657 {
658 struct libinput *li;
659 struct libinput_device *device;
660 struct libinput_event *event;
661 struct libevdev_uinput *uinput1, *uinput2;
662 int rc;
663 int nevents;
664 void *userdata = &rc;
665
666 uinput1 = litest_create_uinput_device("test device", NULL,
667 EV_KEY, BTN_LEFT,
668 EV_KEY, BTN_RIGHT,
669 EV_REL, REL_X,
670 EV_REL, REL_Y,
671 -1);
672 uinput2 = litest_create_uinput_device("test device 2", NULL,
673 EV_KEY, BTN_LEFT,
674 EV_KEY, BTN_RIGHT,
675 EV_REL, REL_X,
676 EV_REL, REL_Y,
677 -1);
678
679 li = libinput_path_create_context(&simple_interface, userdata);
680 ck_assert_notnull(li);
681
682 device = libinput_path_add_device(li,
683 libevdev_uinput_get_devnode(uinput1));
684 ck_assert_notnull(device);
685 libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
686
687 libinput_dispatch(li);
688
689 nevents = 0;
690 while ((event = libinput_get_event(li))) {
691 enum libinput_event_type type;
692 type = libinput_event_get_type(event);
693 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
694 libinput_event_destroy(event);
695 nevents++;
696 }
697
698 ck_assert_int_eq(nevents, 2);
699
700 libinput_suspend(li);
701 libinput_dispatch(li);
702
703 nevents = 0;
704 while ((event = libinput_get_event(li))) {
705 enum libinput_event_type type;
706 type = libinput_event_get_type(event);
707 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
708 libinput_event_destroy(event);
709 nevents++;
710 }
711
712 ck_assert_int_eq(nevents, 2);
713
714 libinput_resume(li);
715 libinput_dispatch(li);
716
717 nevents = 0;
718 while ((event = libinput_get_event(li))) {
719 enum libinput_event_type type;
720 type = libinput_event_get_type(event);
721 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
722 libinput_event_destroy(event);
723 nevents++;
724 }
725
726 ck_assert_int_eq(nevents, 2);
727
728 libevdev_uinput_destroy(uinput1);
729 libevdev_uinput_destroy(uinput2);
730 libinput_unref(li);
731 }
732 END_TEST
733
START_TEST(path_add_device_suspend_resume_fail)734 START_TEST(path_add_device_suspend_resume_fail)
735 {
736 struct libinput *li;
737 struct libinput_device *device;
738 struct libinput_event *event;
739 struct libevdev_uinput *uinput1, *uinput2;
740 int rc;
741 int nevents;
742 void *userdata = &rc;
743
744 uinput1 = litest_create_uinput_device("test device", NULL,
745 EV_KEY, BTN_LEFT,
746 EV_KEY, BTN_RIGHT,
747 EV_REL, REL_X,
748 EV_REL, REL_Y,
749 -1);
750 uinput2 = litest_create_uinput_device("test device 2", NULL,
751 EV_KEY, BTN_LEFT,
752 EV_KEY, BTN_RIGHT,
753 EV_REL, REL_X,
754 EV_REL, REL_Y,
755 -1);
756
757 li = libinput_path_create_context(&simple_interface, userdata);
758 ck_assert_notnull(li);
759
760 device = libinput_path_add_device(li,
761 libevdev_uinput_get_devnode(uinput1));
762 ck_assert_notnull(device);
763 device = libinput_path_add_device(li,
764 libevdev_uinput_get_devnode(uinput2));
765 ck_assert_notnull(device);
766
767 libinput_dispatch(li);
768
769 nevents = 0;
770 while ((event = libinput_get_event(li))) {
771 enum libinput_event_type type;
772 type = libinput_event_get_type(event);
773 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
774 libinput_event_destroy(event);
775 nevents++;
776 }
777
778 ck_assert_int_eq(nevents, 2);
779
780 libinput_suspend(li);
781 libinput_dispatch(li);
782
783 nevents = 0;
784 while ((event = libinput_get_event(li))) {
785 enum libinput_event_type type;
786 type = libinput_event_get_type(event);
787 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
788 libinput_event_destroy(event);
789 nevents++;
790 }
791
792 ck_assert_int_eq(nevents, 2);
793
794 /* now drop one of the devices */
795 libevdev_uinput_destroy(uinput1);
796 rc = libinput_resume(li);
797 ck_assert_int_eq(rc, -1);
798
799 libinput_dispatch(li);
800
801 nevents = 0;
802 while ((event = libinput_get_event(li))) {
803 enum libinput_event_type type;
804 type = libinput_event_get_type(event);
805 /* We expect one device being added, second one fails,
806 * causing a removed event for the first one */
807 if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
808 type != LIBINPUT_EVENT_DEVICE_REMOVED)
809 ck_abort();
810 libinput_event_destroy(event);
811 nevents++;
812 }
813
814 ck_assert_int_eq(nevents, 2);
815
816 libevdev_uinput_destroy(uinput2);
817 libinput_unref(li);
818 }
819 END_TEST
820
START_TEST(path_add_device_suspend_resume_remove_device)821 START_TEST(path_add_device_suspend_resume_remove_device)
822 {
823 struct libinput *li;
824 struct libinput_device *device;
825 struct libinput_event *event;
826 struct libevdev_uinput *uinput1, *uinput2;
827 int rc;
828 int nevents;
829 void *userdata = &rc;
830
831 uinput1 = litest_create_uinput_device("test device", NULL,
832 EV_KEY, BTN_LEFT,
833 EV_KEY, BTN_RIGHT,
834 EV_REL, REL_X,
835 EV_REL, REL_Y,
836 -1);
837 uinput2 = litest_create_uinput_device("test device 2", NULL,
838 EV_KEY, BTN_LEFT,
839 EV_KEY, BTN_RIGHT,
840 EV_REL, REL_X,
841 EV_REL, REL_Y,
842 -1);
843
844 li = libinput_path_create_context(&simple_interface, userdata);
845 ck_assert_notnull(li);
846
847 device = libinput_path_add_device(li,
848 libevdev_uinput_get_devnode(uinput1));
849 ck_assert_notnull(device);
850 device = libinput_path_add_device(li,
851 libevdev_uinput_get_devnode(uinput2));
852
853 libinput_device_ref(device);
854 libinput_dispatch(li);
855
856 nevents = 0;
857 while ((event = libinput_get_event(li))) {
858 enum libinput_event_type type;
859 type = libinput_event_get_type(event);
860 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
861 libinput_event_destroy(event);
862 nevents++;
863 }
864
865 ck_assert_int_eq(nevents, 2);
866
867 libinput_suspend(li);
868 libinput_dispatch(li);
869
870 nevents = 0;
871 while ((event = libinput_get_event(li))) {
872 enum libinput_event_type type;
873 type = libinput_event_get_type(event);
874 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
875 libinput_event_destroy(event);
876 nevents++;
877 }
878
879 ck_assert_int_eq(nevents, 2);
880
881 /* now drop and remove one of the devices */
882 libevdev_uinput_destroy(uinput2);
883 libinput_path_remove_device(device);
884 libinput_device_unref(device);
885
886 rc = libinput_resume(li);
887 ck_assert_int_eq(rc, 0);
888
889 libinput_dispatch(li);
890
891 nevents = 0;
892 while ((event = libinput_get_event(li))) {
893 enum libinput_event_type type;
894 type = libinput_event_get_type(event);
895 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
896 libinput_event_destroy(event);
897 nevents++;
898 }
899
900 ck_assert_int_eq(nevents, 1);
901
902 libevdev_uinput_destroy(uinput1);
903 libinput_unref(li);
904 }
905 END_TEST
906
START_TEST(path_device_gone)907 START_TEST(path_device_gone)
908 {
909 struct libinput *li;
910 struct libinput_device *device;
911 struct libevdev_uinput *uinput;
912 struct libinput_event *event;
913
914 uinput = litest_create_uinput_device("test device", NULL,
915 EV_KEY, BTN_LEFT,
916 EV_KEY, BTN_RIGHT,
917 EV_REL, REL_X,
918 EV_REL, REL_Y,
919 -1);
920
921 li = libinput_path_create_context(&simple_interface, NULL);
922 ck_assert_notnull(li);
923
924 device = libinput_path_add_device(li,
925 libevdev_uinput_get_devnode(uinput));
926 ck_assert_notnull(device);
927
928 litest_drain_events(li);
929
930 libevdev_uinput_destroy(uinput);
931
932 libinput_dispatch(li);
933
934 event = libinput_get_event(li);
935 ck_assert_notnull(event);
936 litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
937 libinput_event_destroy(event);
938
939 libinput_unref(li);
940 }
941 END_TEST
942
START_TEST(path_seat_recycle)943 START_TEST(path_seat_recycle)
944 {
945 struct libinput *li;
946 struct libevdev_uinput *uinput;
947 int rc;
948 void *userdata = &rc;
949 struct libinput_event *ev;
950 struct libinput_device *device;
951 struct libinput_seat *saved_seat = NULL;
952 struct libinput_seat *seat;
953 int data = 0;
954 int found = 0;
955 void *user_data;
956 enum libinput_event_type type;
957
958 uinput = litest_create_uinput_device("test device", NULL,
959 EV_KEY, BTN_LEFT,
960 EV_KEY, BTN_RIGHT,
961 EV_REL, REL_X,
962 EV_REL, REL_Y,
963 -1);
964
965 li = libinput_path_create_context(&simple_interface, userdata);
966 ck_assert_notnull(li);
967
968 device = libinput_path_add_device(li,
969 libevdev_uinput_get_devnode(uinput));
970 ck_assert_notnull(device);
971
972 libinput_dispatch(li);
973
974 ev = libinput_get_event(li);
975 ck_assert_notnull(ev);
976 type = libinput_event_get_type(ev);
977 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
978 device = libinput_event_get_device(ev);
979 ck_assert_notnull(device);
980 saved_seat = libinput_device_get_seat(device);
981 libinput_seat_set_user_data(saved_seat, &data);
982 libinput_seat_ref(saved_seat);
983 libinput_event_destroy(ev);
984 ck_assert_notnull(saved_seat);
985
986 litest_assert_empty_queue(li);
987
988 libinput_suspend(li);
989
990 litest_drain_events(li);
991
992 libinput_resume(li);
993
994 libinput_dispatch(li);
995 ev = libinput_get_event(li);
996 ck_assert_notnull(ev);
997 type = libinput_event_get_type(ev);
998 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
999 device = libinput_event_get_device(ev);
1000 ck_assert_notnull(device);
1001
1002 seat = libinput_device_get_seat(device);
1003 user_data = libinput_seat_get_user_data(seat);
1004 if (user_data == &data) {
1005 found = 1;
1006 ck_assert(seat == saved_seat);
1007 }
1008
1009 libinput_event_destroy(ev);
1010 ck_assert(found == 1);
1011
1012 libinput_unref(li);
1013
1014 libevdev_uinput_destroy(uinput);
1015 }
1016 END_TEST
1017
START_TEST(path_udev_assign_seat)1018 START_TEST(path_udev_assign_seat)
1019 {
1020 struct litest_device *dev = litest_current_device();
1021 struct libinput *li = dev->libinput;
1022 int rc;
1023
1024 litest_set_log_handler_bug(li);
1025 rc = libinput_udev_assign_seat(li, "foo");
1026 ck_assert_int_eq(rc, -1);
1027 litest_restore_log_handler(li);
1028 }
1029 END_TEST
1030
START_TEST(path_ignore_device)1031 START_TEST(path_ignore_device)
1032 {
1033 struct litest_device *dev;
1034 struct libinput *li;
1035 struct libinput_device *device;
1036 const char *path;
1037
1038 dev = litest_create(LITEST_IGNORED_MOUSE, NULL, NULL, NULL, NULL);
1039 path = libevdev_uinput_get_devnode(dev->uinput);
1040 ck_assert_notnull(path);
1041
1042 li = litest_create_context();
1043 device = libinput_path_add_device(li, path);
1044 ck_assert(device == NULL);
1045
1046 litest_destroy_context(li);
1047 litest_delete_device(dev);
1048 }
1049 END_TEST
1050
TEST_COLLECTION(path)1051 TEST_COLLECTION(path)
1052 {
1053 litest_add_no_device(path_create_NULL);
1054 litest_add_no_device(path_create_invalid);
1055 litest_add_no_device(path_create_invalid_file);
1056 litest_add_no_device(path_create_invalid_kerneldev);
1057 litest_add_no_device(path_create_pathmax_file);
1058 litest_add_no_device(path_create_destroy);
1059 litest_add(path_force_destroy, LITEST_ANY, LITEST_ANY);
1060 litest_add_no_device(path_set_user_data);
1061 litest_add_no_device(path_suspend);
1062 litest_add_no_device(path_double_suspend);
1063 litest_add_no_device(path_double_resume);
1064 litest_add_no_device(path_add_device_suspend_resume);
1065 litest_add_no_device(path_add_device_suspend_resume_fail);
1066 litest_add_no_device(path_add_device_suspend_resume_remove_device);
1067 litest_add_for_device(path_added_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
1068 litest_add_for_device(path_seat_change, LITEST_SYNAPTICS_CLICKPAD_X220);
1069 litest_add(path_added_device, LITEST_ANY, LITEST_ANY);
1070 litest_add(path_device_sysname, LITEST_ANY, LITEST_ANY);
1071 litest_add_for_device(path_add_device, LITEST_SYNAPTICS_CLICKPAD_X220);
1072 litest_add_no_device(path_add_invalid_path);
1073 litest_add_for_device(path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
1074 litest_add_for_device(path_double_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
1075 litest_add_no_device(path_device_gone);
1076 litest_add_no_device(path_seat_recycle);
1077 litest_add_for_device(path_udev_assign_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
1078
1079 litest_add_no_device(path_ignore_device);
1080 }
1081