• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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