1 /*
2  * Copyright © 2014 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 <libinput-util.h>
31 #include <unistd.h>
32 #include <stdarg.h>
33 
34 #include "litest.h"
35 #include "libinput-util.h"
36 #define  TEST_VERSIONSORT
37 #include "libinput-versionsort.h"
38 
open_restricted(const char * path,int flags,void * data)39 static int open_restricted(const char *path, int flags, void *data)
40 {
41 	int fd = open(path, flags);
42 	return fd < 0 ? -errno : fd;
43 }
close_restricted(int fd,void * data)44 static void close_restricted(int fd, void *data)
45 {
46 	close(fd);
47 }
48 
49 static const struct libinput_interface simple_interface = {
50 	.open_restricted = open_restricted,
51 	.close_restricted = close_restricted,
52 };
53 
54 static struct libevdev_uinput *
create_simple_test_device(const char * name,...)55 create_simple_test_device(const char *name, ...)
56 {
57 	va_list args;
58 	struct libevdev_uinput *uinput;
59 	struct libevdev *evdev;
60 	unsigned int type, code;
61 	int rc;
62 	struct input_absinfo abs = {
63 		.value = -1,
64 		.minimum = 0,
65 		.maximum = 100,
66 		.fuzz = 0,
67 		.flat = 0,
68 		.resolution = 100,
69 	};
70 
71 	evdev = libevdev_new();
72 	litest_assert_notnull(evdev);
73 	libevdev_set_name(evdev, name);
74 
75 	va_start(args, name);
76 
77 	while ((type = va_arg(args, unsigned int)) != (unsigned int)-1 &&
78 	       (code = va_arg(args, unsigned int)) != (unsigned int)-1) {
79 		const struct input_absinfo *a = NULL;
80 		if (type == EV_ABS)
81 			a = &abs;
82 		libevdev_enable_event_code(evdev, type, code, a);
83 	}
84 
85 	va_end(args);
86 
87 	rc = libevdev_uinput_create_from_device(evdev,
88 						LIBEVDEV_UINPUT_OPEN_MANAGED,
89 						&uinput);
90 	litest_assert_int_eq(rc, 0);
91 	libevdev_free(evdev);
92 
93 	return uinput;
94 }
95 
START_TEST(event_conversion_device_notify)96 START_TEST(event_conversion_device_notify)
97 {
98 	struct libevdev_uinput *uinput;
99 	struct libinput *li;
100 	struct libinput_event *event;
101 	int device_added = 0, device_removed = 0;
102 
103 	uinput = create_simple_test_device("litest test device",
104 					   EV_REL, REL_X,
105 					   EV_REL, REL_Y,
106 					   EV_KEY, BTN_LEFT,
107 					   EV_KEY, BTN_MIDDLE,
108 					   EV_KEY, BTN_LEFT,
109 					   -1, -1);
110 	li = libinput_path_create_context(&simple_interface, NULL);
111 	litest_restore_log_handler(li); /* use the default litest handler */
112 	libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
113 
114 	libinput_dispatch(li);
115 	libinput_suspend(li);
116 	libinput_resume(li);
117 
118 	while ((event = libinput_get_event(li))) {
119 		enum libinput_event_type type;
120 		type = libinput_event_get_type(event);
121 
122 		if (type == LIBINPUT_EVENT_DEVICE_ADDED ||
123 		    type == LIBINPUT_EVENT_DEVICE_REMOVED) {
124 			struct libinput_event_device_notify *dn;
125 			struct libinput_event *base;
126 			dn = libinput_event_get_device_notify_event(event);
127 			base = libinput_event_device_notify_get_base_event(dn);
128 			ck_assert(event == base);
129 
130 			if (type == LIBINPUT_EVENT_DEVICE_ADDED)
131 				device_added++;
132 			else if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
133 				device_removed++;
134 
135 			litest_disable_log_handler(li);
136 			ck_assert(libinput_event_get_pointer_event(event) == NULL);
137 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
138 			ck_assert(libinput_event_get_touch_event(event) == NULL);
139 			ck_assert(libinput_event_get_gesture_event(event) == NULL);
140 			ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
141 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
142 			ck_assert(libinput_event_get_switch_event(event) == NULL);
143 			litest_restore_log_handler(li);
144 		}
145 
146 		libinput_event_destroy(event);
147 	}
148 
149 	libinput_unref(li);
150 	libevdev_uinput_destroy(uinput);
151 
152 	ck_assert_int_gt(device_added, 0);
153 	ck_assert_int_gt(device_removed, 0);
154 }
155 END_TEST
156 
START_TEST(event_conversion_pointer)157 START_TEST(event_conversion_pointer)
158 {
159 	struct litest_device *dev = litest_current_device();
160 	struct libinput *li = dev->libinput;
161 	struct libinput_event *event;
162 	int motion = 0, button = 0;
163 
164 	/* Queue at least two relative motion events as the first one may
165 	 * be absorbed by the pointer acceleration filter. */
166 	litest_event(dev, EV_REL, REL_X, -1);
167 	litest_event(dev, EV_REL, REL_Y, -1);
168 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
169 	litest_event(dev, EV_REL, REL_X, -1);
170 	litest_event(dev, EV_REL, REL_Y, -1);
171 	litest_event(dev, EV_KEY, BTN_LEFT, 1);
172 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
173 
174 	libinput_dispatch(li);
175 
176 	while ((event = libinput_get_event(li))) {
177 		enum libinput_event_type type;
178 		type = libinput_event_get_type(event);
179 
180 		if (type == LIBINPUT_EVENT_POINTER_MOTION ||
181 		    type == LIBINPUT_EVENT_POINTER_BUTTON) {
182 			struct libinput_event_pointer *p;
183 			struct libinput_event *base;
184 			p = libinput_event_get_pointer_event(event);
185 			base = libinput_event_pointer_get_base_event(p);
186 			ck_assert(event == base);
187 
188 			if (type == LIBINPUT_EVENT_POINTER_MOTION)
189 				motion++;
190 			else if (type == LIBINPUT_EVENT_POINTER_BUTTON)
191 				button++;
192 
193 			litest_disable_log_handler(li);
194 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
195 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
196 			ck_assert(libinput_event_get_touch_event(event) == NULL);
197 			ck_assert(libinput_event_get_gesture_event(event) == NULL);
198 			ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
199 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
200 			ck_assert(libinput_event_get_switch_event(event) == NULL);
201 			litest_restore_log_handler(li);
202 		}
203 		libinput_event_destroy(event);
204 	}
205 
206 	ck_assert_int_gt(motion, 0);
207 	ck_assert_int_gt(button, 0);
208 }
209 END_TEST
210 
START_TEST(event_conversion_pointer_abs)211 START_TEST(event_conversion_pointer_abs)
212 {
213 	struct litest_device *dev = litest_current_device();
214 	struct libinput *li = dev->libinput;
215 	struct libinput_event *event;
216 	int motion = 0, button = 0;
217 
218 	litest_event(dev, EV_ABS, ABS_X, 10);
219 	litest_event(dev, EV_ABS, ABS_Y, 50);
220 	litest_event(dev, EV_KEY, BTN_LEFT, 1);
221 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
222 	litest_event(dev, EV_ABS, ABS_X, 30);
223 	litest_event(dev, EV_ABS, ABS_Y, 30);
224 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
225 
226 	libinput_dispatch(li);
227 
228 	while ((event = libinput_get_event(li))) {
229 		enum libinput_event_type type;
230 		type = libinput_event_get_type(event);
231 
232 		if (type == LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE ||
233 		    type == LIBINPUT_EVENT_POINTER_BUTTON) {
234 			struct libinput_event_pointer *p;
235 			struct libinput_event *base;
236 			p = libinput_event_get_pointer_event(event);
237 			base = libinput_event_pointer_get_base_event(p);
238 			ck_assert(event == base);
239 
240 			if (type == LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE)
241 				motion++;
242 			else if (type == LIBINPUT_EVENT_POINTER_BUTTON)
243 				button++;
244 
245 			litest_disable_log_handler(li);
246 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
247 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
248 			ck_assert(libinput_event_get_touch_event(event) == NULL);
249 			ck_assert(libinput_event_get_gesture_event(event) == NULL);
250 			ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
251 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
252 			ck_assert(libinput_event_get_switch_event(event) == NULL);
253 			litest_restore_log_handler(li);
254 		}
255 		libinput_event_destroy(event);
256 	}
257 
258 	ck_assert_int_gt(motion, 0);
259 	ck_assert_int_gt(button, 0);
260 }
261 END_TEST
262 
START_TEST(event_conversion_key)263 START_TEST(event_conversion_key)
264 {
265 	struct litest_device *dev = litest_current_device();
266 	struct libinput *li = dev->libinput;
267 	struct libinput_event *event;
268 	int key = 0;
269 
270 	litest_event(dev, EV_KEY, KEY_A, 1);
271 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
272 	litest_event(dev, EV_KEY, KEY_A, 0);
273 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
274 
275 	libinput_dispatch(li);
276 
277 	while ((event = libinput_get_event(li))) {
278 		enum libinput_event_type type;
279 		type = libinput_event_get_type(event);
280 
281 		if (type == LIBINPUT_EVENT_KEYBOARD_KEY) {
282 			struct libinput_event_keyboard *k;
283 			struct libinput_event *base;
284 			k = libinput_event_get_keyboard_event(event);
285 			base = libinput_event_keyboard_get_base_event(k);
286 			ck_assert(event == base);
287 
288 			key++;
289 
290 			litest_disable_log_handler(li);
291 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
292 			ck_assert(libinput_event_get_pointer_event(event) == NULL);
293 			ck_assert(libinput_event_get_touch_event(event) == NULL);
294 			ck_assert(libinput_event_get_gesture_event(event) == NULL);
295 			ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
296 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
297 			ck_assert(libinput_event_get_switch_event(event) == NULL);
298 			litest_restore_log_handler(li);
299 		}
300 		libinput_event_destroy(event);
301 	}
302 
303 	ck_assert_int_gt(key, 0);
304 }
305 END_TEST
306 
START_TEST(event_conversion_touch)307 START_TEST(event_conversion_touch)
308 {
309 	struct litest_device *dev = litest_current_device();
310 	struct libinput *li = dev->libinput;
311 	struct libinput_event *event;
312 	int touch = 0;
313 
314 	libinput_dispatch(li);
315 
316 	litest_event(dev, EV_KEY, BTN_TOOL_FINGER, 1);
317 	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
318 	litest_event(dev, EV_ABS, ABS_X, 10);
319 	litest_event(dev, EV_ABS, ABS_Y, 10);
320 	litest_event(dev, EV_ABS, ABS_MT_SLOT, 0);
321 	litest_event(dev, EV_ABS, ABS_MT_TRACKING_ID, 1);
322 	litest_event(dev, EV_ABS, ABS_MT_POSITION_X, 10);
323 	litest_event(dev, EV_ABS, ABS_MT_POSITION_Y, 10);
324 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
325 
326 	libinput_dispatch(li);
327 
328 	while ((event = libinput_get_event(li))) {
329 		enum libinput_event_type type;
330 		type = libinput_event_get_type(event);
331 
332 		if (type >= LIBINPUT_EVENT_TOUCH_DOWN &&
333 		    type <= LIBINPUT_EVENT_TOUCH_FRAME) {
334 			struct libinput_event_touch *t;
335 			struct libinput_event *base;
336 			t = libinput_event_get_touch_event(event);
337 			base = libinput_event_touch_get_base_event(t);
338 			ck_assert(event == base);
339 
340 			touch++;
341 
342 			litest_disable_log_handler(li);
343 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
344 			ck_assert(libinput_event_get_pointer_event(event) == NULL);
345 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
346 			ck_assert(libinput_event_get_gesture_event(event) == NULL);
347 			ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
348 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
349 			ck_assert(libinput_event_get_switch_event(event) == NULL);
350 			litest_restore_log_handler(li);
351 		}
352 		libinput_event_destroy(event);
353 	}
354 
355 	ck_assert_int_gt(touch, 0);
356 }
357 END_TEST
358 
START_TEST(event_conversion_gesture)359 START_TEST(event_conversion_gesture)
360 {
361 	struct litest_device *dev = litest_current_device();
362 	struct libinput *li = dev->libinput;
363 	struct libinput_event *event;
364 	int gestures = 0;
365 	int i;
366 
367 	libinput_dispatch(li);
368 
369 	litest_touch_down(dev, 0, 70, 30);
370 	litest_touch_down(dev, 1, 30, 70);
371 	for (i = 0; i < 8; i++) {
372 		litest_push_event_frame(dev);
373 		litest_touch_move(dev, 0, 70 - i * 5, 30 + i * 5);
374 		litest_touch_move(dev, 1, 30 + i * 5, 70 - i * 5);
375 		litest_pop_event_frame(dev);
376 		libinput_dispatch(li);
377 	}
378 
379 	while ((event = libinput_get_event(li))) {
380 		enum libinput_event_type type;
381 		type = libinput_event_get_type(event);
382 
383 		if (type >= LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN &&
384 		    type <= LIBINPUT_EVENT_GESTURE_PINCH_END) {
385 			struct libinput_event_gesture *g;
386 			struct libinput_event *base;
387 			g = libinput_event_get_gesture_event(event);
388 			base = libinput_event_gesture_get_base_event(g);
389 			ck_assert(event == base);
390 
391 			gestures++;
392 
393 			litest_disable_log_handler(li);
394 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
395 			ck_assert(libinput_event_get_pointer_event(event) == NULL);
396 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
397 			ck_assert(libinput_event_get_touch_event(event) == NULL);
398 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
399 			ck_assert(libinput_event_get_switch_event(event) == NULL);
400 			litest_restore_log_handler(li);
401 		}
402 		libinput_event_destroy(event);
403 	}
404 
405 	ck_assert_int_gt(gestures, 0);
406 }
407 END_TEST
408 
START_TEST(event_conversion_tablet)409 START_TEST(event_conversion_tablet)
410 {
411 	struct litest_device *dev = litest_current_device();
412 	struct libinput *li = dev->libinput;
413 	struct libinput_event *event;
414 	int events = 0;
415 	struct axis_replacement axes[] = {
416 		{ ABS_DISTANCE, 10 },
417 		{ -1, -1 }
418 	};
419 
420 	litest_tablet_proximity_in(dev, 50, 50, axes);
421 	litest_tablet_motion(dev, 60, 50, axes);
422 	litest_button_click(dev, BTN_STYLUS, true);
423 	litest_button_click(dev, BTN_STYLUS, false);
424 
425 	libinput_dispatch(li);
426 
427 	while ((event = libinput_get_event(li))) {
428 		enum libinput_event_type type;
429 		type = libinput_event_get_type(event);
430 
431 		if (type >= LIBINPUT_EVENT_TABLET_TOOL_AXIS &&
432 		    type <= LIBINPUT_EVENT_TABLET_TOOL_BUTTON) {
433 			struct libinput_event_tablet_tool *t;
434 			struct libinput_event *base;
435 			t = libinput_event_get_tablet_tool_event(event);
436 			base = libinput_event_tablet_tool_get_base_event(t);
437 			ck_assert(event == base);
438 
439 			events++;
440 
441 			litest_disable_log_handler(li);
442 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
443 			ck_assert(libinput_event_get_pointer_event(event) == NULL);
444 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
445 			ck_assert(libinput_event_get_touch_event(event) == NULL);
446 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
447 			ck_assert(libinput_event_get_switch_event(event) == NULL);
448 			litest_restore_log_handler(li);
449 		}
450 		libinput_event_destroy(event);
451 	}
452 
453 	ck_assert_int_gt(events, 0);
454 }
455 END_TEST
456 
START_TEST(event_conversion_tablet_pad)457 START_TEST(event_conversion_tablet_pad)
458 {
459 	struct litest_device *dev = litest_current_device();
460 	struct libinput *li = dev->libinput;
461 	struct libinput_event *event;
462 	int events = 0;
463 
464 	litest_button_click(dev, BTN_0, true);
465 	litest_pad_ring_start(dev, 10);
466 	litest_pad_ring_end(dev);
467 
468 	libinput_dispatch(li);
469 
470 	while ((event = libinput_get_event(li))) {
471 		enum libinput_event_type type;
472 		type = libinput_event_get_type(event);
473 
474 		if (type >= LIBINPUT_EVENT_TABLET_PAD_BUTTON &&
475 		    type <= LIBINPUT_EVENT_TABLET_PAD_STRIP) {
476 			struct libinput_event_tablet_pad *p;
477 			struct libinput_event *base;
478 
479 			p = libinput_event_get_tablet_pad_event(event);
480 			base = libinput_event_tablet_pad_get_base_event(p);
481 			ck_assert(event == base);
482 
483 			events++;
484 
485 			litest_disable_log_handler(li);
486 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
487 			ck_assert(libinput_event_get_pointer_event(event) == NULL);
488 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
489 			ck_assert(libinput_event_get_touch_event(event) == NULL);
490 			ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
491 			ck_assert(libinput_event_get_switch_event(event) == NULL);
492 			litest_restore_log_handler(li);
493 		}
494 		libinput_event_destroy(event);
495 	}
496 
497 	ck_assert_int_gt(events, 0);
498 }
499 END_TEST
500 
START_TEST(event_conversion_switch)501 START_TEST(event_conversion_switch)
502 {
503 	struct litest_device *dev = litest_current_device();
504 	struct libinput *li = dev->libinput;
505 	struct libinput_event *event;
506 	int sw = 0;
507 
508 	litest_switch_action(dev,
509 			     LIBINPUT_SWITCH_LID,
510 			     LIBINPUT_SWITCH_STATE_ON);
511 	litest_switch_action(dev,
512 			     LIBINPUT_SWITCH_LID,
513 			     LIBINPUT_SWITCH_STATE_OFF);
514 	libinput_dispatch(li);
515 
516 	while ((event = libinput_get_event(li))) {
517 		enum libinput_event_type type;
518 		type = libinput_event_get_type(event);
519 
520 		if (type == LIBINPUT_EVENT_SWITCH_TOGGLE) {
521 			struct libinput_event_switch *s;
522 			struct libinput_event *base;
523 			s = libinput_event_get_switch_event(event);
524 			base = libinput_event_switch_get_base_event(s);
525 			ck_assert(event == base);
526 
527 			sw++;
528 
529 			litest_disable_log_handler(li);
530 			ck_assert(libinput_event_get_device_notify_event(event) == NULL);
531 			ck_assert(libinput_event_get_keyboard_event(event) == NULL);
532 			ck_assert(libinput_event_get_pointer_event(event) == NULL);
533 			ck_assert(libinput_event_get_touch_event(event) == NULL);
534 			ck_assert(libinput_event_get_gesture_event(event) == NULL);
535 			ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
536 			ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
537 			litest_restore_log_handler(li);
538 		}
539 		libinput_event_destroy(event);
540 	}
541 
542 	ck_assert_int_gt(sw, 0);
543 }
544 END_TEST
545 
START_TEST(bitfield_helpers)546 START_TEST(bitfield_helpers)
547 {
548 	/* This value has a bit set on all of the word boundaries we want to
549 	 * test: 0, 1, 7, 8, 31, 32, and 33
550 	 */
551 	unsigned char read_bitfield[] = { 0x83, 0x1, 0x0, 0x80, 0x3 };
552 	unsigned char write_bitfield[ARRAY_LENGTH(read_bitfield)] = {0};
553 	size_t i;
554 
555 	/* Now check that the bitfield we wrote to came out to be the same as
556 	 * the bitfield we were writing from */
557 	for (i = 0; i < ARRAY_LENGTH(read_bitfield) * 8; i++) {
558 		switch (i) {
559 		case 0:
560 		case 1:
561 		case 7:
562 		case 8:
563 		case 31:
564 		case 32:
565 		case 33:
566 			ck_assert(bit_is_set(read_bitfield, i));
567 			set_bit(write_bitfield, i);
568 			break;
569 		default:
570 			ck_assert(!bit_is_set(read_bitfield, i));
571 			clear_bit(write_bitfield, i);
572 			break;
573 		}
574 	}
575 
576 	ck_assert_int_eq(memcmp(read_bitfield,
577 				write_bitfield,
578 				sizeof(read_bitfield)),
579 			 0);
580 }
581 END_TEST
582 
START_TEST(context_ref_counting)583 START_TEST(context_ref_counting)
584 {
585 	struct libinput *li;
586 
587 	/* These tests rely on valgrind to detect memory leak and use after
588 	 * free errors. */
589 
590 	li = libinput_path_create_context(&simple_interface, NULL);
591 	ck_assert_notnull(li);
592 	ck_assert_ptr_eq(libinput_unref(li), NULL);
593 
594 	li = libinput_path_create_context(&simple_interface, NULL);
595 	ck_assert_notnull(li);
596 	ck_assert_ptr_eq(libinput_ref(li), li);
597 	ck_assert_ptr_eq(libinput_unref(li), li);
598 	ck_assert_ptr_eq(libinput_unref(li), NULL);
599 }
600 END_TEST
601 
START_TEST(config_status_string)602 START_TEST(config_status_string)
603 {
604 	const char *strs[3];
605 	const char *invalid;
606 	size_t i, j;
607 
608 	strs[0] = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_SUCCESS);
609 	strs[1] = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
610 	strs[2] = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_INVALID);
611 
612 	for (i = 0; i < ARRAY_LENGTH(strs) - 1; i++)
613 		for (j = i + 1; j < ARRAY_LENGTH(strs); j++)
614 			ck_assert_str_ne(strs[i], strs[j]);
615 
616 	invalid = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_INVALID + 1);
617 	ck_assert(invalid == NULL);
618 	invalid = libinput_config_status_to_str(LIBINPUT_CONFIG_STATUS_SUCCESS - 1);
619 	ck_assert(invalid == NULL);
620 }
621 END_TEST
622 
START_TEST(matrix_helpers)623 START_TEST(matrix_helpers)
624 {
625 	struct matrix m1, m2, m3;
626 	float f[6] = { 1, 2, 3, 4, 5, 6 };
627 	int x, y;
628 	int row, col;
629 
630 	matrix_init_identity(&m1);
631 
632 	for (row = 0; row < 3; row++) {
633 		for (col = 0; col < 3; col++) {
634 			ck_assert_int_eq(m1.val[row][col],
635 					 (row == col) ? 1 : 0);
636 		}
637 	}
638 	ck_assert(matrix_is_identity(&m1));
639 
640 	matrix_from_farray6(&m2, f);
641 	ck_assert_int_eq(m2.val[0][0], 1);
642 	ck_assert_int_eq(m2.val[0][1], 2);
643 	ck_assert_int_eq(m2.val[0][2], 3);
644 	ck_assert_int_eq(m2.val[1][0], 4);
645 	ck_assert_int_eq(m2.val[1][1], 5);
646 	ck_assert_int_eq(m2.val[1][2], 6);
647 	ck_assert_int_eq(m2.val[2][0], 0);
648 	ck_assert_int_eq(m2.val[2][1], 0);
649 	ck_assert_int_eq(m2.val[2][2], 1);
650 
651 	x = 100;
652 	y = 5;
653 	matrix_mult_vec(&m1, &x, &y);
654 	ck_assert_int_eq(x, 100);
655 	ck_assert_int_eq(y, 5);
656 
657 	matrix_mult(&m3, &m1, &m1);
658 	ck_assert(matrix_is_identity(&m3));
659 
660 	matrix_init_scale(&m2, 2, 4);
661 	ck_assert_int_eq(m2.val[0][0], 2);
662 	ck_assert_int_eq(m2.val[0][1], 0);
663 	ck_assert_int_eq(m2.val[0][2], 0);
664 	ck_assert_int_eq(m2.val[1][0], 0);
665 	ck_assert_int_eq(m2.val[1][1], 4);
666 	ck_assert_int_eq(m2.val[1][2], 0);
667 	ck_assert_int_eq(m2.val[2][0], 0);
668 	ck_assert_int_eq(m2.val[2][1], 0);
669 	ck_assert_int_eq(m2.val[2][2], 1);
670 
671 	matrix_mult_vec(&m2, &x, &y);
672 	ck_assert_int_eq(x, 200);
673 	ck_assert_int_eq(y, 20);
674 
675 	matrix_init_translate(&m2, 10, 100);
676 	ck_assert_int_eq(m2.val[0][0], 1);
677 	ck_assert_int_eq(m2.val[0][1], 0);
678 	ck_assert_int_eq(m2.val[0][2], 10);
679 	ck_assert_int_eq(m2.val[1][0], 0);
680 	ck_assert_int_eq(m2.val[1][1], 1);
681 	ck_assert_int_eq(m2.val[1][2], 100);
682 	ck_assert_int_eq(m2.val[2][0], 0);
683 	ck_assert_int_eq(m2.val[2][1], 0);
684 	ck_assert_int_eq(m2.val[2][2], 1);
685 
686 	matrix_mult_vec(&m2, &x, &y);
687 	ck_assert_int_eq(x, 210);
688 	ck_assert_int_eq(y, 120);
689 
690 	matrix_to_farray6(&m2, f);
691 	ck_assert_int_eq(f[0], 1);
692 	ck_assert_int_eq(f[1], 0);
693 	ck_assert_int_eq(f[2], 10);
694 	ck_assert_int_eq(f[3], 0);
695 	ck_assert_int_eq(f[4], 1);
696 	ck_assert_int_eq(f[5], 100);
697 }
698 END_TEST
699 
START_TEST(ratelimit_helpers)700 START_TEST(ratelimit_helpers)
701 {
702 	struct ratelimit rl;
703 	unsigned int i, j;
704 
705 	/* 10 attempts every 100ms */
706 	ratelimit_init(&rl, ms2us(500), 10);
707 
708 	for (j = 0; j < 3; ++j) {
709 		/* a burst of 9 attempts must succeed */
710 		for (i = 0; i < 9; ++i) {
711 			ck_assert_int_eq(ratelimit_test(&rl),
712 					 RATELIMIT_PASS);
713 		}
714 
715 		/* the 10th attempt reaches the threshold */
716 		ck_assert_int_eq(ratelimit_test(&rl), RATELIMIT_THRESHOLD);
717 
718 		/* ..then further attempts must fail.. */
719 		ck_assert_int_eq(ratelimit_test(&rl), RATELIMIT_EXCEEDED);
720 
721 		/* ..regardless of how often we try. */
722 		for (i = 0; i < 100; ++i) {
723 			ck_assert_int_eq(ratelimit_test(&rl),
724 					 RATELIMIT_EXCEEDED);
725 		}
726 
727 		/* ..even after waiting 20ms */
728 		msleep(100);
729 		for (i = 0; i < 100; ++i) {
730 			ck_assert_int_eq(ratelimit_test(&rl),
731 					 RATELIMIT_EXCEEDED);
732 		}
733 
734 		/* but after 500ms the counter is reset */
735 		msleep(450); /* +50ms to account for time drifts */
736 	}
737 }
738 END_TEST
739 
740 struct parser_test {
741 	char *tag;
742 	int expected_value;
743 };
744 
START_TEST(dpi_parser)745 START_TEST(dpi_parser)
746 {
747 	struct parser_test tests[] = {
748 		{ "450 *1800 3200", 1800 },
749 		{ "*450 1800 3200", 450 },
750 		{ "450 1800 *3200", 3200 },
751 		{ "450 1800 3200", 3200 },
752 		{ "450 1800 failboat", 0 },
753 		{ "450 1800 *failboat", 0 },
754 		{ "0 450 1800 *3200", 0 },
755 		{ "450@37 1800@12 *3200@6", 3200 },
756 		{ "450@125 1800@125   *3200@125  ", 3200 },
757 		{ "450@125 *1800@125  3200@125", 1800 },
758 		{ "*this @string fails", 0 },
759 		{ "12@34 *45@", 0 },
760 		{ "12@a *45@", 0 },
761 		{ "12@a *45@25", 0 },
762 		{ "                                      * 12, 450, 800", 0 },
763 		{ "                                      *12, 450, 800", 12 },
764 		{ "*12, *450, 800", 12 },
765 		{ "*-23412, 450, 800", 0 },
766 		{ "112@125, 450@125, 800@125, 900@-125", 0 },
767 		{ "", 0 },
768 		{ "   ", 0 },
769 		{ "* ", 0 },
770 		{ NULL, 0 }
771 	};
772 	int i, dpi;
773 
774 	for (i = 0; tests[i].tag != NULL; i++) {
775 		dpi = parse_mouse_dpi_property(tests[i].tag);
776 		ck_assert_int_eq(dpi, tests[i].expected_value);
777 	}
778 
779 	dpi = parse_mouse_dpi_property(NULL);
780 	ck_assert_int_eq(dpi, 0);
781 }
782 END_TEST
783 
START_TEST(wheel_click_parser)784 START_TEST(wheel_click_parser)
785 {
786 	struct parser_test tests[] = {
787 		{ "1", 1 },
788 		{ "10", 10 },
789 		{ "-12", -12 },
790 		{ "360", 360 },
791 
792 		{ "0", 0 },
793 		{ "-0", 0 },
794 		{ "a", 0 },
795 		{ "10a", 0 },
796 		{ "10-", 0 },
797 		{ "sadfasfd", 0 },
798 		{ "361", 0 },
799 		{ NULL, 0 }
800 	};
801 
802 	int i, angle;
803 
804 	for (i = 0; tests[i].tag != NULL; i++) {
805 		angle = parse_mouse_wheel_click_angle_property(tests[i].tag);
806 		ck_assert_int_eq(angle, tests[i].expected_value);
807 	}
808 }
809 END_TEST
810 
START_TEST(wheel_click_count_parser)811 START_TEST(wheel_click_count_parser)
812 {
813 	struct parser_test tests[] = {
814 		{ "1", 1 },
815 		{ "10", 10 },
816 		{ "-12", -12 },
817 		{ "360", 360 },
818 
819 		{ "0", 0 },
820 		{ "-0", 0 },
821 		{ "a", 0 },
822 		{ "10a", 0 },
823 		{ "10-", 0 },
824 		{ "sadfasfd", 0 },
825 		{ "361", 0 },
826 		{ NULL, 0 }
827 	};
828 
829 	int i, angle;
830 
831 	for (i = 0; tests[i].tag != NULL; i++) {
832 		angle = parse_mouse_wheel_click_count_property(tests[i].tag);
833 		ck_assert_int_eq(angle, tests[i].expected_value);
834 	}
835 
836 	angle = parse_mouse_wheel_click_count_property(NULL);
837 	ck_assert_int_eq(angle, 0);
838 }
839 END_TEST
840 
START_TEST(dimension_prop_parser)841 START_TEST(dimension_prop_parser)
842 {
843 	struct parser_test_dimension {
844 		char *tag;
845 		bool success;
846 		int x, y;
847 	} tests[] = {
848 		{ "10x10", true, 10, 10 },
849 		{ "1x20", true, 1, 20 },
850 		{ "1x8000", true, 1, 8000 },
851 		{ "238492x428210", true, 238492, 428210 },
852 		{ "0x0", false, 0, 0 },
853 		{ "-10x10", false, 0, 0 },
854 		{ "-1", false, 0, 0 },
855 		{ "1x-99", false, 0, 0 },
856 		{ "0", false, 0, 0 },
857 		{ "100", false, 0, 0 },
858 		{ "", false, 0, 0 },
859 		{ "abd", false, 0, 0 },
860 		{ "xabd", false, 0, 0 },
861 		{ "0xaf", false, 0, 0 },
862 		{ "0x0x", false, 0, 0 },
863 		{ "x10", false, 0, 0 },
864 		{ NULL, false, 0, 0 }
865 	};
866 	int i;
867 	size_t x, y;
868 	bool success;
869 
870 	for (i = 0; tests[i].tag != NULL; i++) {
871 		x = y = 0xad;
872 		success = parse_dimension_property(tests[i].tag, &x, &y);
873 		ck_assert(success == tests[i].success);
874 		if (success) {
875 			ck_assert_int_eq(x, tests[i].x);
876 			ck_assert_int_eq(y, tests[i].y);
877 		} else {
878 			ck_assert_int_eq(x, 0xad);
879 			ck_assert_int_eq(y, 0xad);
880 		}
881 	}
882 
883 	success = parse_dimension_property(NULL, &x, &y);
884 	ck_assert(success == false);
885 }
886 END_TEST
887 
START_TEST(reliability_prop_parser)888 START_TEST(reliability_prop_parser)
889 {
890 	struct parser_test_reliability {
891 		char *tag;
892 		bool success;
893 		enum switch_reliability reliability;
894 	} tests[] = {
895 		{ "reliable", true, RELIABILITY_RELIABLE },
896 		{ "unreliable", false, 0 },
897 		{ "", false, 0 },
898 		{ "0", false, 0 },
899 		{ "1", false, 0 },
900 		{ NULL, false, 0, }
901 	};
902 	enum switch_reliability r;
903 	bool success;
904 	int i;
905 
906 	for (i = 0; tests[i].tag != NULL; i++) {
907 		r = 0xaf;
908 		success = parse_switch_reliability_property(tests[i].tag, &r);
909 		ck_assert(success == tests[i].success);
910 		if (success)
911 			ck_assert_int_eq(r, tests[i].reliability);
912 		else
913 			ck_assert_int_eq(r, 0xaf);
914 	}
915 
916 	success = parse_switch_reliability_property(NULL, &r);
917 	ck_assert(success == true);
918 	ck_assert_int_eq(r, RELIABILITY_UNKNOWN);
919 
920 	success = parse_switch_reliability_property("foo", NULL);
921 	ck_assert(success == false);
922 }
923 END_TEST
924 
START_TEST(calibration_prop_parser)925 START_TEST(calibration_prop_parser)
926 {
927 #define DEFAULT_VALUES { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 }
928 	const float untouched[6] = DEFAULT_VALUES;
929 	struct parser_test_calibration {
930 		char *prop;
931 		bool success;
932 		float values[6];
933 	} tests[] = {
934 		{ "", false, DEFAULT_VALUES },
935 		{ "banana", false, DEFAULT_VALUES },
936 		{ "1 2 3 a 5 6", false, DEFAULT_VALUES },
937 		{ "2", false, DEFAULT_VALUES },
938 		{ "2 3 4 5 6", false, DEFAULT_VALUES },
939 		{ "1 2 3 4 5 6", true, DEFAULT_VALUES },
940 		{ "6.00012 3.244 4.238 5.2421 6.0134 8.860", true,
941 			{ 6.00012, 3.244, 4.238, 5.2421, 6.0134, 8.860 }},
942 		{ "0xff 2 3 4 5 6", false, DEFAULT_VALUES },
943 		{ NULL, false, DEFAULT_VALUES }
944 	};
945 	bool success;
946 	float calibration[6];
947 	int rc;
948 	int i;
949 
950 	for (i = 0; tests[i].prop != NULL; i++) {
951 		memcpy(calibration, untouched, sizeof(calibration));
952 
953 		success = parse_calibration_property(tests[i].prop,
954 						     calibration);
955 		ck_assert_int_eq(success, tests[i].success);
956 		if (success)
957 			rc = memcmp(tests[i].values,
958 				    calibration,
959 				    sizeof(calibration));
960 		else
961 			rc = memcmp(untouched,
962 				    calibration,
963 				    sizeof(calibration));
964 		ck_assert_int_eq(rc, 0);
965 	}
966 
967 	memcpy(calibration, untouched, sizeof(calibration));
968 
969 	success = parse_calibration_property(NULL, calibration);
970 	ck_assert(success == false);
971 	rc = memcmp(untouched, calibration, sizeof(calibration));
972 	ck_assert_int_eq(rc, 0);
973 }
974 END_TEST
975 
START_TEST(range_prop_parser)976 START_TEST(range_prop_parser)
977 {
978 	struct parser_test_range {
979 		char *tag;
980 		bool success;
981 		int hi, lo;
982 	} tests[] = {
983 		{ "10:8", true, 10, 8 },
984 		{ "100:-1", true, 100, -1 },
985 		{ "-203813:-502023", true, -203813, -502023 },
986 		{ "238492:28210", true, 238492, 28210 },
987 		{ "none", true, 0, 0 },
988 		{ "0:0", false, 0, 0 },
989 		{ "", false, 0, 0 },
990 		{ "abcd", false, 0, 0 },
991 		{ "10:30:10", false, 0, 0 },
992 		{ NULL, false, 0, 0 }
993 	};
994 	int i;
995 	int hi, lo;
996 	bool success;
997 
998 	for (i = 0; tests[i].tag != NULL; i++) {
999 		hi = lo = 0xad;
1000 		success = parse_range_property(tests[i].tag, &hi, &lo);
1001 		ck_assert(success == tests[i].success);
1002 		if (success) {
1003 			ck_assert_int_eq(hi, tests[i].hi);
1004 			ck_assert_int_eq(lo, tests[i].lo);
1005 		} else {
1006 			ck_assert_int_eq(hi, 0xad);
1007 			ck_assert_int_eq(lo, 0xad);
1008 		}
1009 	}
1010 
1011 	success = parse_range_property(NULL, NULL, NULL);
1012 	ck_assert(success == false);
1013 }
1014 END_TEST
1015 
START_TEST(evcode_prop_parser)1016 START_TEST(evcode_prop_parser)
1017 {
1018 	struct parser_test_tuple {
1019 		const char *prop;
1020 		bool success;
1021 		size_t ntuples;
1022 		int tuples[20];
1023 	} tests[] = {
1024 		{ "EV_KEY", true, 1, {EV_KEY, 0xffff} },
1025 		{ "EV_ABS;", true, 1, {EV_ABS, 0xffff} },
1026 		{ "ABS_X;", true, 1, {EV_ABS, ABS_X} },
1027 		{ "SW_TABLET_MODE;", true, 1, {EV_SW, SW_TABLET_MODE} },
1028 		{ "EV_SW", true, 1, {EV_SW, 0xffff} },
1029 		{ "ABS_Y", true, 1, {EV_ABS, ABS_Y} },
1030 		{ "EV_ABS:0x00", true, 1, {EV_ABS, ABS_X} },
1031 		{ "EV_ABS:01", true, 1, {EV_ABS, ABS_Y} },
1032 		{ "ABS_TILT_X;ABS_TILT_Y;", true, 2,
1033 			{ EV_ABS, ABS_TILT_X,
1034 			  EV_ABS, ABS_TILT_Y} },
1035 		{ "BTN_TOOL_DOUBLETAP;EV_KEY;KEY_A", true, 3,
1036 			{ EV_KEY, BTN_TOOL_DOUBLETAP,
1037 			  EV_KEY, 0xffff,
1038 			  EV_KEY, KEY_A } },
1039 		{ "REL_Y;ABS_Z;BTN_STYLUS", true, 3,
1040 			{ EV_REL, REL_Y,
1041 			  EV_ABS, ABS_Z,
1042 			  EV_KEY, BTN_STYLUS } },
1043 		{ "REL_Y;EV_KEY:0x123;BTN_STYLUS", true, 3,
1044 			{ EV_REL, REL_Y,
1045 			  EV_KEY, 0x123,
1046 			  EV_KEY, BTN_STYLUS } },
1047 		{ .prop = "", .success = false },
1048 		{ .prop = "EV_FOO", .success = false },
1049 		{ .prop = "EV_KEY;EV_FOO", .success = false },
1050 		{ .prop = "BTN_STYLUS;EV_FOO", .success = false },
1051 		{ .prop = "BTN_UNKNOWN", .success = false },
1052 		{ .prop = "BTN_UNKNOWN;EV_KEY", .success = false },
1053 		{ .prop = "PR_UNKNOWN", .success = false },
1054 		{ .prop = "BTN_STYLUS;PR_UNKNOWN;ABS_X", .success = false },
1055 		{ .prop = "EV_REL:0xffff", .success = false },
1056 		{ .prop = "EV_REL:0x123.", .success = false },
1057 		{ .prop = "EV_REL:ffff", .success = false },
1058 		{ .prop = "EV_REL:blah", .success = false },
1059 		{ .prop = "KEY_A:0x11", .success = false },
1060 		{ .prop = "EV_KEY:0x11 ", .success = false },
1061 		{ .prop = "EV_KEY:0x11not", .success = false },
1062 		{ .prop = "none", .success = false },
1063 		{ .prop = NULL },
1064 	};
1065 	struct parser_test_tuple *t;
1066 
1067 	for (int i = 0; tests[i].prop; i++) {
1068 		bool success;
1069 		size_t nevents = 32;
1070 		struct input_event events[nevents];
1071 
1072 		t = &tests[i];
1073 		success = parse_evcode_property(t->prop, events, &nevents);
1074 		ck_assert(success == t->success);
1075 		if (!success)
1076 			continue;
1077 
1078 		ck_assert_int_eq(nevents, t->ntuples);
1079 		for (size_t j = 0; j < nevents; j++) {
1080 			int type, code;
1081 
1082 			type = events[j].type;
1083 			code = events[j].code;
1084 			ck_assert_int_eq(t->tuples[j * 2], type);
1085 			ck_assert_int_eq(t->tuples[j * 2 + 1], code);
1086 		}
1087 	}
1088 }
1089 END_TEST
1090 
START_TEST(time_conversion)1091 START_TEST(time_conversion)
1092 {
1093 	ck_assert_int_eq(us(10), 10);
1094 	ck_assert_int_eq(ns2us(10000), 10);
1095 	ck_assert_int_eq(ms2us(10), 10000);
1096 	ck_assert_int_eq(s2us(1), 1000000);
1097 	ck_assert_int_eq(us2ms(10000), 10);
1098 }
1099 END_TEST
1100 
1101 struct atoi_test {
1102 	char *str;
1103 	bool success;
1104 	int val;
1105 };
1106 
START_TEST(safe_atoi_test)1107 START_TEST(safe_atoi_test)
1108 {
1109 	struct atoi_test tests[] = {
1110 		{ "10", true, 10 },
1111 		{ "20", true, 20 },
1112 		{ "-1", true, -1 },
1113 		{ "2147483647", true, 2147483647 },
1114 		{ "-2147483648", true, -2147483648 },
1115 		{ "4294967295", false, 0 },
1116 		{ "0x0", false, 0 },
1117 		{ "-10x10", false, 0 },
1118 		{ "1x-99", false, 0 },
1119 		{ "", false, 0 },
1120 		{ "abd", false, 0 },
1121 		{ "xabd", false, 0 },
1122 		{ "0xaf", false, 0 },
1123 		{ "0x0x", false, 0 },
1124 		{ "x10", false, 0 },
1125 		{ NULL, false, 0 }
1126 	};
1127 	int v;
1128 	bool success;
1129 
1130 	for (int i = 0; tests[i].str != NULL; i++) {
1131 		v = 0xad;
1132 		success = safe_atoi(tests[i].str, &v);
1133 		ck_assert(success == tests[i].success);
1134 		if (success)
1135 			ck_assert_int_eq(v, tests[i].val);
1136 		else
1137 			ck_assert_int_eq(v, 0xad);
1138 	}
1139 }
1140 END_TEST
1141 
START_TEST(safe_atoi_base_16_test)1142 START_TEST(safe_atoi_base_16_test)
1143 {
1144 	struct atoi_test tests[] = {
1145 		{ "10", true, 0x10 },
1146 		{ "20", true, 0x20 },
1147 		{ "-1", true, -1 },
1148 		{ "0x10", true, 0x10 },
1149 		{ "0xff", true, 0xff },
1150 		{ "abc", true, 0xabc },
1151 		{ "-10", true, -0x10 },
1152 		{ "0x0", true, 0 },
1153 		{ "0", true, 0 },
1154 		{ "0x-99", false, 0 },
1155 		{ "0xak", false, 0 },
1156 		{ "0x", false, 0 },
1157 		{ "x10", false, 0 },
1158 		{ NULL, false, 0 }
1159 	};
1160 
1161 	int v;
1162 	bool success;
1163 
1164 	for (int i = 0; tests[i].str != NULL; i++) {
1165 		v = 0xad;
1166 		success = safe_atoi_base(tests[i].str, &v, 16);
1167 		ck_assert(success == tests[i].success);
1168 		if (success)
1169 			ck_assert_int_eq(v, tests[i].val);
1170 		else
1171 			ck_assert_int_eq(v, 0xad);
1172 	}
1173 }
1174 END_TEST
1175 
START_TEST(safe_atoi_base_8_test)1176 START_TEST(safe_atoi_base_8_test)
1177 {
1178 	struct atoi_test tests[] = {
1179 		{ "7", true, 07 },
1180 		{ "10", true, 010 },
1181 		{ "20", true, 020 },
1182 		{ "-1", true, -1 },
1183 		{ "010", true, 010 },
1184 		{ "0ff", false, 0 },
1185 		{ "abc", false, 0},
1186 		{ "0xabc", false, 0},
1187 		{ "-10", true, -010 },
1188 		{ "0", true, 0 },
1189 		{ "00", true, 0 },
1190 		{ "0x0", false, 0 },
1191 		{ "0x-99", false, 0 },
1192 		{ "0xak", false, 0 },
1193 		{ "0x", false, 0 },
1194 		{ "x10", false, 0 },
1195 		{ NULL, false, 0 }
1196 	};
1197 
1198 	int v;
1199 	bool success;
1200 
1201 	for (int i = 0; tests[i].str != NULL; i++) {
1202 		v = 0xad;
1203 		success = safe_atoi_base(tests[i].str, &v, 8);
1204 		ck_assert(success == tests[i].success);
1205 		if (success)
1206 			ck_assert_int_eq(v, tests[i].val);
1207 		else
1208 			ck_assert_int_eq(v, 0xad);
1209 	}
1210 }
1211 END_TEST
1212 
1213 struct atou_test {
1214 	char *str;
1215 	bool success;
1216 	unsigned int val;
1217 };
1218 
START_TEST(safe_atou_test)1219 START_TEST(safe_atou_test)
1220 {
1221 	struct atou_test tests[] = {
1222 		{ "10", true, 10 },
1223 		{ "20", true, 20 },
1224 		{ "-1", false, 0 },
1225 		{ "2147483647", true, 2147483647 },
1226 		{ "-2147483648", false, 0},
1227 		{ "0x0", false, 0 },
1228 		{ "-10x10", false, 0 },
1229 		{ "1x-99", false, 0 },
1230 		{ "", false, 0 },
1231 		{ "abd", false, 0 },
1232 		{ "xabd", false, 0 },
1233 		{ "0xaf", false, 0 },
1234 		{ "0x0x", false, 0 },
1235 		{ "x10", false, 0 },
1236 		{ NULL, false, 0 }
1237 	};
1238 	unsigned int v;
1239 	bool success;
1240 
1241 	for (int i = 0; tests[i].str != NULL; i++) {
1242 		v = 0xad;
1243 		success = safe_atou(tests[i].str, &v);
1244 		ck_assert(success == tests[i].success);
1245 		if (success)
1246 			ck_assert_int_eq(v, tests[i].val);
1247 		else
1248 			ck_assert_int_eq(v, 0xad);
1249 	}
1250 }
1251 END_TEST
1252 
START_TEST(safe_atou_base_16_test)1253 START_TEST(safe_atou_base_16_test)
1254 {
1255 	struct atou_test tests[] = {
1256 		{ "10", true, 0x10 },
1257 		{ "20", true, 0x20 },
1258 		{ "-1", false, 0 },
1259 		{ "0x10", true, 0x10 },
1260 		{ "0xff", true, 0xff },
1261 		{ "abc", true, 0xabc },
1262 		{ "-10", false, 0 },
1263 		{ "0x0", true, 0 },
1264 		{ "0", true, 0 },
1265 		{ "0x-99", false, 0 },
1266 		{ "0xak", false, 0 },
1267 		{ "0x", false, 0 },
1268 		{ "x10", false, 0 },
1269 		{ NULL, false, 0 }
1270 	};
1271 
1272 	unsigned int v;
1273 	bool success;
1274 
1275 	for (int i = 0; tests[i].str != NULL; i++) {
1276 		v = 0xad;
1277 		success = safe_atou_base(tests[i].str, &v, 16);
1278 		ck_assert(success == tests[i].success);
1279 		if (success)
1280 			ck_assert_int_eq(v, tests[i].val);
1281 		else
1282 			ck_assert_int_eq(v, 0xad);
1283 	}
1284 }
1285 END_TEST
1286 
START_TEST(safe_atou_base_8_test)1287 START_TEST(safe_atou_base_8_test)
1288 {
1289 	struct atou_test tests[] = {
1290 		{ "7", true, 07 },
1291 		{ "10", true, 010 },
1292 		{ "20", true, 020 },
1293 		{ "-1", false, 0 },
1294 		{ "010", true, 010 },
1295 		{ "0ff", false, 0 },
1296 		{ "abc", false, 0},
1297 		{ "0xabc", false, 0},
1298 		{ "-10", false, 0 },
1299 		{ "0", true, 0 },
1300 		{ "00", true, 0 },
1301 		{ "0x0", false, 0 },
1302 		{ "0x-99", false, 0 },
1303 		{ "0xak", false, 0 },
1304 		{ "0x", false, 0 },
1305 		{ "x10", false, 0 },
1306 		{ NULL, false, 0 }
1307 	};
1308 
1309 	unsigned int v;
1310 	bool success;
1311 
1312 	for (int i = 0; tests[i].str != NULL; i++) {
1313 		v = 0xad;
1314 		success = safe_atou_base(tests[i].str, &v, 8);
1315 		ck_assert(success == tests[i].success);
1316 		if (success)
1317 			ck_assert_int_eq(v, tests[i].val);
1318 		else
1319 			ck_assert_int_eq(v, 0xad);
1320 	}
1321 }
1322 END_TEST
1323 
START_TEST(safe_atod_test)1324 START_TEST(safe_atod_test)
1325 {
1326 	struct atod_test {
1327 		char *str;
1328 		bool success;
1329 		double val;
1330 	} tests[] = {
1331 		{ "10", true, 10 },
1332 		{ "20", true, 20 },
1333 		{ "-1", true, -1 },
1334 		{ "2147483647", true, 2147483647 },
1335 		{ "-2147483648", true, -2147483648 },
1336 		{ "4294967295", true, 4294967295 },
1337 		{ "0x0", false, 0 },
1338 		{ "0x10", false, 0 },
1339 		{ "0xaf", false, 0 },
1340 		{ "x80", false, 0 },
1341 		{ "0.0", true, 0.0 },
1342 		{ "0.1", true, 0.1 },
1343 		{ "1.2", true, 1.2 },
1344 		{ "-324.9", true, -324.9 },
1345 		{ "9324.9", true, 9324.9 },
1346 		{ "NAN", false, 0 },
1347 		{ "INFINITY", false, 0 },
1348 		{ "-10x10", false, 0 },
1349 		{ "1x-99", false, 0 },
1350 		{ "", false, 0 },
1351 		{ "abd", false, 0 },
1352 		{ "xabd", false, 0 },
1353 		{ "0x0x", false, 0 },
1354 		{ NULL, false, 0 }
1355 	};
1356 	double v;
1357 	bool success;
1358 
1359 	for (int i = 0; tests[i].str != NULL; i++) {
1360 		v = 0xad;
1361 		success = safe_atod(tests[i].str, &v);
1362 		ck_assert(success == tests[i].success);
1363 		if (success)
1364 			ck_assert_int_eq(v, tests[i].val);
1365 		else
1366 			ck_assert_int_eq(v, 0xad);
1367 	}
1368 }
1369 END_TEST
1370 
START_TEST(strsplit_test)1371 START_TEST(strsplit_test)
1372 {
1373 	struct strsplit_test {
1374 		const char *string;
1375 		const char *delim;
1376 		const char *results[10];
1377 	} tests[] = {
1378 		{ "one two three", " ", { "one", "two", "three", NULL } },
1379 		{ "one", " ", { "one", NULL } },
1380 		{ "one two ", " ", { "one", "two", NULL } },
1381 		{ "one  two", " ", { "one", "two", NULL } },
1382 		{ " one two", " ", { "one", "two", NULL } },
1383 		{ "one", "\t \r", { "one", NULL } },
1384 		{ "one two three", " t", { "one", "wo", "hree", NULL } },
1385 		{ " one two three", "te", { " on", " ", "wo ", "hr", NULL } },
1386 		{ "one", "ne", { "o", NULL } },
1387 		{ "onene", "ne", { "o", NULL } },
1388 		{ NULL, NULL, { NULL }}
1389 	};
1390 	struct strsplit_test *t = tests;
1391 
1392 	while (t->string) {
1393 		char **strv;
1394 		int idx = 0;
1395 		strv = strv_from_string(t->string, t->delim);
1396 		while (t->results[idx]) {
1397 			ck_assert_str_eq(t->results[idx], strv[idx]);
1398 			idx++;
1399 		}
1400 		ck_assert_ptr_eq(strv[idx], NULL);
1401 		strv_free(strv);
1402 		t++;
1403 	}
1404 
1405 	/* Special cases */
1406 	ck_assert_ptr_eq(strv_from_string("", " "), NULL);
1407 	ck_assert_ptr_eq(strv_from_string(" ", " "), NULL);
1408 	ck_assert_ptr_eq(strv_from_string("     ", " "), NULL);
1409 	ck_assert_ptr_eq(strv_from_string("oneoneone", "one"), NULL);
1410 }
1411 END_TEST
1412 
START_TEST(kvsplit_double_test)1413 START_TEST(kvsplit_double_test)
1414 {
1415 	struct kvsplit_dbl_test {
1416 		const char *string;
1417 		const char *psep;
1418 		const char *kvsep;
1419 		ssize_t nresults;
1420 		struct {
1421 			double a;
1422 			double b;
1423 		} results[32];
1424 	} tests[] = {
1425 		{ "1:2;3:4;5:6", ";", ":", 3, { {1, 2}, {3, 4}, {5, 6}}},
1426 		{ "1.0x2.3 -3.2x4.5 8.090909x-6.00", " ", "x", 3, { {1.0, 2.3}, {-3.2, 4.5}, {8.090909, -6}}},
1427 
1428 		{ "1:2", "x", ":", 1, {{1, 2}}},
1429 		{ "1:2", ":", "x", -1, {}},
1430 		{ "1:2", NULL, "x", -1, {}},
1431 		{ "1:2", "", "x", -1, {}},
1432 		{ "1:2", "x", NULL, -1, {}},
1433 		{ "1:2", "x", "", -1, {}},
1434 		{ "a:b", "x", ":", -1, {}},
1435 		{ "", " ", "x", -1, {}},
1436 		{ "1.2.3.4.5", ".", "", -1, {}},
1437 		{ NULL }
1438 	};
1439 	struct kvsplit_dbl_test *t = tests;
1440 
1441 	while (t->string) {
1442 		struct key_value_double *result = NULL;
1443 		ssize_t npairs;
1444 
1445 		npairs = kv_double_from_string(t->string,
1446 					       t->psep,
1447 					       t->kvsep,
1448 					       &result);
1449 		ck_assert_int_eq(npairs, t->nresults);
1450 
1451 		for (ssize_t i = 0; i < npairs; i++) {
1452 			ck_assert_double_eq(t->results[i].a, result[i].key);
1453 			ck_assert_double_eq(t->results[i].b, result[i].value);
1454 		}
1455 
1456 
1457 		free(result);
1458 		t++;
1459 	}
1460 }
1461 END_TEST
1462 
START_TEST(strjoin_test)1463 START_TEST(strjoin_test)
1464 {
1465 	struct strjoin_test {
1466 		char *strv[10];
1467 		const char *joiner;
1468 		const char *result;
1469 	} tests[] = {
1470 		{ { "one", "two", "three", NULL }, " ", "one two three" },
1471 		{ { "one", NULL }, "x", "one" },
1472 		{ { "one", "two", NULL }, "x", "onextwo" },
1473 		{ { "one", "two", NULL }, ",", "one,two" },
1474 		{ { "one", "two", NULL }, ", ", "one, two" },
1475 		{ { "one", "two", NULL }, "one", "oneonetwo" },
1476 		{ { "one", "two", NULL }, NULL, NULL },
1477 		{ { "", "", "", NULL }, " ", "  " },
1478 		{ { "a", "b", "c", NULL }, "", "abc" },
1479 		{ { "", "b", "c", NULL }, "x", "xbxc" },
1480 		{ { "", "", "", NULL }, "", "" },
1481 		{ { NULL }, NULL, NULL }
1482 	};
1483 	struct strjoin_test *t = tests;
1484 	struct strjoin_test nulltest = { {NULL}, "x", NULL };
1485 
1486 	while (t->strv[0]) {
1487 		char *str;
1488 		str = strv_join(t->strv, t->joiner);
1489 		if (t->result == NULL)
1490 			ck_assert(str == NULL);
1491 		else
1492 			ck_assert_str_eq(str, t->result);
1493 		free(str);
1494 		t++;
1495 	}
1496 
1497 	ck_assert(strv_join(nulltest.strv, "x") == NULL);
1498 }
1499 END_TEST
1500 
open_restricted_leak(const char * path,int flags,void * data)1501 static int open_restricted_leak(const char *path, int flags, void *data)
1502 {
1503 	return *(int*)data;
1504 }
1505 
close_restricted_leak(int fd,void * data)1506 static void close_restricted_leak(int fd, void *data)
1507 {
1508 	/* noop */
1509 }
1510 
1511 const struct libinput_interface leak_interface = {
1512 	.open_restricted = open_restricted_leak,
1513 	.close_restricted = close_restricted_leak,
1514 };
1515 
START_TEST(fd_no_event_leak)1516 START_TEST(fd_no_event_leak)
1517 {
1518 	struct libevdev_uinput *uinput;
1519 	struct libinput *li;
1520 	struct libinput_device *device;
1521 	int fd = -1;
1522 	const char *path;
1523 	struct libinput_event *event;
1524 
1525 	uinput = create_simple_test_device("litest test device",
1526 					   EV_REL, REL_X,
1527 					   EV_REL, REL_Y,
1528 					   EV_KEY, BTN_LEFT,
1529 					   EV_KEY, BTN_MIDDLE,
1530 					   EV_KEY, BTN_LEFT,
1531 					   -1, -1);
1532 	path = libevdev_uinput_get_devnode(uinput);
1533 
1534 	fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
1535 	ck_assert_int_gt(fd, -1);
1536 
1537 	li = libinput_path_create_context(&leak_interface, &fd);
1538 	litest_restore_log_handler(li); /* use the default litest handler */
1539 
1540 	/* Add the device, trigger an event, then remove it again.
1541 	 * Without it, we get a SYN_DROPPED immediately and no events.
1542 	 */
1543 	device = libinput_path_add_device(li, path);
1544 	libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1545 	libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1546 	libinput_path_remove_device(device);
1547 	libinput_dispatch(li);
1548 	litest_drain_events(li);
1549 
1550 	/* Device is removed, but fd is still open. Queue an event, add a
1551 	 * new device with the same fd, the queued event must be discarded
1552 	 * by libinput */
1553 	libevdev_uinput_write_event(uinput, EV_REL, REL_Y, 1);
1554 	libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1555 	libinput_dispatch(li);
1556 
1557 	libinput_path_add_device(li, path);
1558 	libinput_dispatch(li);
1559 	event = libinput_get_event(li);
1560 	ck_assert_int_eq(libinput_event_get_type(event),
1561 			 LIBINPUT_EVENT_DEVICE_ADDED);
1562 	libinput_event_destroy(event);
1563 
1564 	litest_assert_empty_queue(li);
1565 
1566 	close(fd);
1567 	libinput_unref(li);
1568 	libevdev_uinput_destroy(uinput);
1569 }
1570 END_TEST
1571 
START_TEST(library_version)1572 START_TEST(library_version)
1573 {
1574 	const char *version = LIBINPUT_LT_VERSION;
1575 	int C, R, A;
1576 	int rc;
1577 
1578 	rc = sscanf(version, "%d:%d:%d", &C, &R, &A);
1579 	ck_assert_int_eq(rc, 3);
1580 
1581 	ck_assert_int_ge(C, 17);
1582 	ck_assert_int_ge(R, 0);
1583 	ck_assert_int_ge(A, 7);
1584 
1585 	/* Binary compatibility broken? */
1586 	ck_assert(R != 0 || A != 0);
1587 
1588 	/* The first stable API in 0.12 had 10:0:0  */
1589 	ck_assert_int_eq(C - A, 10);
1590 }
1591 END_TEST
1592 
timer_offset_warning(struct libinput * libinput,enum libinput_log_priority priority,const char * format,va_list args)1593 static void timer_offset_warning(struct libinput *libinput,
1594 				 enum libinput_log_priority priority,
1595 				 const char *format,
1596 				 va_list args)
1597 {
1598 	int *warning_triggered = (int*)libinput_get_user_data(libinput);
1599 
1600 	if (priority == LIBINPUT_LOG_PRIORITY_ERROR &&
1601 	    strstr(format, "offset negative"))
1602 		(*warning_triggered)++;
1603 }
1604 
START_TEST(timer_offset_bug_warning)1605 START_TEST(timer_offset_bug_warning)
1606 {
1607 	struct litest_device *dev = litest_current_device();
1608 	struct libinput *li = dev->libinput;
1609 	int warning_triggered = 0;
1610 
1611 	litest_enable_tap(dev->libinput_device);
1612 	litest_drain_events(li);
1613 
1614 	litest_touch_down(dev, 0, 50, 50);
1615 	litest_touch_up(dev, 0);
1616 
1617 	litest_timeout_tap();
1618 
1619 	libinput_set_user_data(li, &warning_triggered);
1620 	libinput_log_set_handler(li, timer_offset_warning);
1621 	libinput_dispatch(li);
1622 
1623 	/* triggered for touch down and touch up */
1624 	ck_assert_int_eq(warning_triggered, 2);
1625 	litest_restore_log_handler(li);
1626 }
1627 END_TEST
1628 
START_TEST(timer_flush)1629 START_TEST(timer_flush)
1630 {
1631 	struct libinput *li;
1632 	struct litest_device *keyboard, *touchpad;
1633 
1634 	li = litest_create_context();
1635 
1636 	touchpad = litest_add_device(li, LITEST_SYNAPTICS_TOUCHPAD);
1637 	litest_enable_tap(touchpad->libinput_device);
1638 	libinput_dispatch(li);
1639 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
1640 	libinput_dispatch(li);
1641 	litest_drain_events(li);
1642 
1643 	/* make sure tapping works */
1644 	litest_touch_down(touchpad, 0, 50, 50);
1645 	litest_touch_up(touchpad, 0);
1646 	libinput_dispatch(li);
1647 	litest_timeout_tap();
1648 	libinput_dispatch(li);
1649 
1650 	litest_assert_button_event(li, BTN_LEFT,
1651 				   LIBINPUT_BUTTON_STATE_PRESSED);
1652 	litest_assert_button_event(li, BTN_LEFT,
1653 				   LIBINPUT_BUTTON_STATE_RELEASED);
1654 	litest_assert_empty_queue(li);
1655 
1656 	/* make sure dwt-tap is ignored */
1657 	litest_keyboard_key(keyboard, KEY_A, true);
1658 	litest_keyboard_key(keyboard, KEY_A, false);
1659 	libinput_dispatch(li);
1660 	litest_touch_down(touchpad, 0, 50, 50);
1661 	litest_touch_up(touchpad, 0);
1662 	libinput_dispatch(li);
1663 	litest_timeout_tap();
1664 	libinput_dispatch(li);
1665 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1666 
1667 	/* Ingore 'timer offset negative' warnings */
1668 	litest_disable_log_handler(li);
1669 
1670 	/* now mess with the timing
1671 	   - send a key event
1672 	   - expire dwt
1673 	   - send a tap
1674 	   and then call libinput_dispatch(). libinput should notice that
1675 	   the tap event came in after the timeout and thus acknowledge the
1676 	   tap.
1677 	 */
1678 	litest_keyboard_key(keyboard, KEY_A, true);
1679 	litest_keyboard_key(keyboard, KEY_A, false);
1680 	litest_timeout_dwt_long();
1681 	litest_touch_down(touchpad, 0, 50, 50);
1682 	litest_touch_up(touchpad, 0);
1683 	libinput_dispatch(li);
1684 	litest_timeout_tap();
1685 	libinput_dispatch(li);
1686 	litest_restore_log_handler(li);
1687 
1688 	litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
1689 	litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
1690 	litest_assert_button_event(li, BTN_LEFT,
1691 				   LIBINPUT_BUTTON_STATE_PRESSED);
1692 	litest_assert_button_event(li, BTN_LEFT,
1693 				   LIBINPUT_BUTTON_STATE_RELEASED);
1694 
1695 	litest_delete_device(keyboard);
1696 	litest_delete_device(touchpad);
1697 	libinput_unref(li);
1698 }
1699 END_TEST
1700 
START_TEST(list_test_insert)1701 START_TEST(list_test_insert)
1702 {
1703 	struct list_test {
1704 		int val;
1705 		struct list node;
1706 	} tests[] = {
1707 		{ .val  = 1 },
1708 		{ .val  = 2 },
1709 		{ .val  = 3 },
1710 		{ .val  = 4 },
1711 	};
1712 	struct list_test *t;
1713 	struct list head;
1714 	int val;
1715 
1716 	list_init(&head);
1717 
1718 	ARRAY_FOR_EACH(tests, t) {
1719 		list_insert(&head, &t->node);
1720 	}
1721 
1722 	val = 4;
1723 	list_for_each(t, &head, node) {
1724 		ck_assert_int_eq(t->val, val);
1725 		val--;
1726 	}
1727 
1728 	ck_assert_int_eq(val, 0);
1729 }
1730 END_TEST
1731 
START_TEST(list_test_append)1732 START_TEST(list_test_append)
1733 {
1734 	struct list_test {
1735 		int val;
1736 		struct list node;
1737 	} tests[] = {
1738 		{ .val  = 1 },
1739 		{ .val  = 2 },
1740 		{ .val  = 3 },
1741 		{ .val  = 4 },
1742 	};
1743 	struct list_test *t;
1744 	struct list head;
1745 	int val;
1746 
1747 	list_init(&head);
1748 
1749 	ARRAY_FOR_EACH(tests, t) {
1750 		list_append(&head, &t->node);
1751 	}
1752 
1753 	val = 1;
1754 	list_for_each(t, &head, node) {
1755 		ck_assert_int_eq(t->val, val);
1756 		val++;
1757 	}
1758 	ck_assert_int_eq(val, 5);
1759 }
1760 END_TEST
1761 
START_TEST(strverscmp_test)1762 START_TEST(strverscmp_test)
1763 {
1764 	ck_assert_int_eq(libinput_strverscmp("", ""), 0);
1765 	ck_assert_int_gt(libinput_strverscmp("0.0.1", ""), 0);
1766 	ck_assert_int_lt(libinput_strverscmp("", "0.0.1"), 0);
1767 	ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.0.1"), 0);
1768 	ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.0.2"), -1);
1769 	ck_assert_int_eq(libinput_strverscmp("0.0.2", "0.0.1"), 1);
1770 	ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.1.0"), -1);
1771 	ck_assert_int_eq(libinput_strverscmp("0.1.0", "0.0.1"), 1);
1772 }
1773 END_TEST
1774 
1775 
1776 
TEST_COLLECTION(misc)1777 TEST_COLLECTION(misc)
1778 {
1779 	litest_add_no_device("events:conversion", event_conversion_device_notify);
1780 	litest_add_for_device("events:conversion", event_conversion_pointer, LITEST_MOUSE);
1781 	litest_add_for_device("events:conversion", event_conversion_pointer, LITEST_MOUSE);
1782 	litest_add_for_device("events:conversion", event_conversion_pointer_abs, LITEST_XEN_VIRTUAL_POINTER);
1783 	litest_add_for_device("events:conversion", event_conversion_key, LITEST_KEYBOARD);
1784 	litest_add_for_device("events:conversion", event_conversion_touch, LITEST_WACOM_TOUCH);
1785 	litest_add_for_device("events:conversion", event_conversion_gesture, LITEST_BCM5974);
1786 	litest_add_for_device("events:conversion", event_conversion_tablet, LITEST_WACOM_CINTIQ);
1787 	litest_add_for_device("events:conversion", event_conversion_tablet_pad, LITEST_WACOM_INTUOS5_PAD);
1788 	litest_add_for_device("events:conversion", event_conversion_switch, LITEST_LID_SWITCH);
1789 	litest_add_deviceless("misc:bitfield_helpers", bitfield_helpers);
1790 
1791 	litest_add_deviceless("context:refcount", context_ref_counting);
1792 	litest_add_deviceless("config:status string", config_status_string);
1793 
1794 	litest_add_for_device("timer:offset-warning", timer_offset_bug_warning, LITEST_SYNAPTICS_TOUCHPAD);
1795 	litest_add_no_device("timer:flush", timer_flush);
1796 
1797 	litest_add_deviceless("misc:matrix", matrix_helpers);
1798 	litest_add_deviceless("misc:ratelimit", ratelimit_helpers);
1799 	litest_add_deviceless("misc:parser", dpi_parser);
1800 	litest_add_deviceless("misc:parser", wheel_click_parser);
1801 	litest_add_deviceless("misc:parser", wheel_click_count_parser);
1802 	litest_add_deviceless("misc:parser", dimension_prop_parser);
1803 	litest_add_deviceless("misc:parser", reliability_prop_parser);
1804 	litest_add_deviceless("misc:parser", calibration_prop_parser);
1805 	litest_add_deviceless("misc:parser", range_prop_parser);
1806 	litest_add_deviceless("misc:parser", evcode_prop_parser);
1807 	litest_add_deviceless("misc:parser", safe_atoi_test);
1808 	litest_add_deviceless("misc:parser", safe_atoi_base_16_test);
1809 	litest_add_deviceless("misc:parser", safe_atoi_base_8_test);
1810 	litest_add_deviceless("misc:parser", safe_atou_test);
1811 	litest_add_deviceless("misc:parser", safe_atou_base_16_test);
1812 	litest_add_deviceless("misc:parser", safe_atou_base_8_test);
1813 	litest_add_deviceless("misc:parser", safe_atod_test);
1814 	litest_add_deviceless("misc:parser", strsplit_test);
1815 	litest_add_deviceless("misc:parser", kvsplit_double_test);
1816 	litest_add_deviceless("misc:parser", strjoin_test);
1817 	litest_add_deviceless("misc:time", time_conversion);
1818 
1819 	litest_add_no_device("misc:fd", fd_no_event_leak);
1820 
1821 	litest_add_deviceless("misc:library_version", library_version);
1822 
1823 	litest_add_deviceless("misc:list", list_test_insert);
1824 	litest_add_deviceless("misc:list", list_test_append);
1825 	litest_add_deviceless("misc:versionsort", strverscmp_test);
1826 }
1827