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