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