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 <libudev.h>
31 #include <unistd.h>
32
33 #include "litest.h"
34 #include "libinput-util.h"
35
START_TEST(device_sendevents_config)36 START_TEST(device_sendevents_config)
37 {
38 struct litest_device *dev = litest_current_device();
39 struct libinput_device *device;
40 uint32_t modes;
41
42 device = dev->libinput_device;
43
44 modes = libinput_device_config_send_events_get_modes(device);
45 ck_assert_int_eq(modes,
46 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
47 }
48 END_TEST
49
START_TEST(device_sendevents_config_invalid)50 START_TEST(device_sendevents_config_invalid)
51 {
52 struct litest_device *dev = litest_current_device();
53 struct libinput_device *device;
54 enum libinput_config_status status;
55
56 device = dev->libinput_device;
57
58 status = libinput_device_config_send_events_set_mode(device,
59 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED | (1 << 4));
60 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
61 }
62 END_TEST
63
START_TEST(device_sendevents_config_touchpad)64 START_TEST(device_sendevents_config_touchpad)
65 {
66 struct litest_device *dev = litest_current_device();
67 struct libinput_device *device;
68 uint32_t modes, expected;
69
70 expected = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
71
72 /* The wacom devices in the test suite are external */
73 if (libevdev_get_id_vendor(dev->evdev) != VENDOR_ID_WACOM &&
74 !litest_touchpad_is_external(dev))
75 expected |=
76 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
77
78 device = dev->libinput_device;
79
80 modes = libinput_device_config_send_events_get_modes(device);
81 ck_assert_int_eq(modes, expected);
82 }
83 END_TEST
84
START_TEST(device_sendevents_config_touchpad_superset)85 START_TEST(device_sendevents_config_touchpad_superset)
86 {
87 struct litest_device *dev = litest_current_device();
88 struct libinput_device *device;
89 enum libinput_config_status status;
90 uint32_t modes;
91
92 /* The wacom devices in the test suite are external */
93 if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_WACOM ||
94 litest_touchpad_is_external(dev))
95 return;
96
97 device = dev->libinput_device;
98
99 modes = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED |
100 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
101
102 status = libinput_device_config_send_events_set_mode(device,
103 modes);
104 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
105
106 /* DISABLED supersedes the rest, expect the rest to be dropped */
107 modes = libinput_device_config_send_events_get_mode(device);
108 ck_assert_int_eq(modes, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
109 }
110 END_TEST
111
START_TEST(device_sendevents_config_default)112 START_TEST(device_sendevents_config_default)
113 {
114 struct litest_device *dev = litest_current_device();
115 struct libinput_device *device;
116 uint32_t mode;
117
118 device = dev->libinput_device;
119
120 mode = libinput_device_config_send_events_get_mode(device);
121 ck_assert_int_eq(mode,
122 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
123
124 mode = libinput_device_config_send_events_get_default_mode(device);
125 ck_assert_int_eq(mode,
126 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
127 }
128 END_TEST
129
START_TEST(device_disable)130 START_TEST(device_disable)
131 {
132 struct litest_device *dev = litest_current_device();
133 struct libinput *li = dev->libinput;
134 struct libinput_device *device;
135 enum libinput_config_status status;
136 struct libinput_event *event;
137 struct litest_device *tmp;
138
139 device = dev->libinput_device;
140
141 litest_drain_events(li);
142
143 status = libinput_device_config_send_events_set_mode(device,
144 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
145 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
146
147 /* no event from disabling */
148 litest_assert_empty_queue(li);
149
150 /* no event from disabled device */
151 litest_event(dev, EV_REL, REL_X, 10);
152 litest_event(dev, EV_SYN, SYN_REPORT, 0);
153 litest_assert_empty_queue(li);
154
155 /* create a new device so the resumed fd isn't the same as the
156 suspended one */
157 tmp = litest_add_device(li, LITEST_KEYBOARD);
158 ck_assert_notnull(tmp);
159 litest_drain_events(li);
160
161 /* no event from resuming */
162 status = libinput_device_config_send_events_set_mode(device,
163 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
164 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
165 litest_assert_empty_queue(li);
166
167 /* event from re-enabled device */
168 litest_event(dev, EV_REL, REL_X, 10);
169 litest_event(dev, EV_SYN, SYN_REPORT, 0);
170
171 libinput_dispatch(li);
172 event = libinput_get_event(li);
173 ck_assert_notnull(event);
174 ck_assert_int_eq(libinput_event_get_type(event),
175 LIBINPUT_EVENT_POINTER_MOTION);
176 libinput_event_destroy(event);
177
178 litest_delete_device(tmp);
179 }
180 END_TEST
181
START_TEST(device_disable_tablet)182 START_TEST(device_disable_tablet)
183 {
184 struct litest_device *dev = litest_current_device();
185 struct libinput *li = dev->libinput;
186 struct libinput_device *device;
187 enum libinput_config_status status;
188 struct axis_replacement axes[] = {
189 { ABS_DISTANCE, 10 },
190 { ABS_PRESSURE, 0 },
191 { -1, -1 }
192 };
193
194 device = dev->libinput_device;
195
196 litest_drain_events(li);
197
198 status = libinput_device_config_send_events_set_mode(device,
199 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
200 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
201
202 /* no event from disabling */
203 litest_assert_empty_queue(li);
204
205 litest_tablet_proximity_in(dev, 60, 60, axes);
206 for (int i = 60; i < 70; i++) {
207 litest_tablet_motion(dev, i, i, axes);
208 libinput_dispatch(li);
209 }
210 litest_tablet_proximity_out(dev);
211
212 litest_assert_empty_queue(li);
213
214 /* no event from resuming */
215 status = libinput_device_config_send_events_set_mode(device,
216 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
217 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
218 litest_assert_empty_queue(li);
219 }
220 END_TEST
221
START_TEST(device_disable_touchpad)222 START_TEST(device_disable_touchpad)
223 {
224 struct litest_device *dev = litest_current_device();
225 struct libinput *li = dev->libinput;
226 struct libinput_device *device;
227 enum libinput_config_status status;
228
229 device = dev->libinput_device;
230
231 litest_drain_events(li);
232
233 status = libinput_device_config_send_events_set_mode(device,
234 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
235 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
236
237 /* no event from disabling */
238 litest_assert_empty_queue(li);
239
240 litest_touch_down(dev, 0, 50, 50);
241 litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
242 litest_touch_up(dev, 0);
243
244 litest_assert_empty_queue(li);
245
246 /* no event from resuming */
247 status = libinput_device_config_send_events_set_mode(device,
248 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
249 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
250 litest_assert_empty_queue(li);
251 }
252 END_TEST
253
START_TEST(device_disable_touch)254 START_TEST(device_disable_touch)
255 {
256 struct litest_device *dev = litest_current_device();
257 struct libinput *li = dev->libinput;
258 struct libinput_device *device;
259 enum libinput_config_status status;
260
261 device = dev->libinput_device;
262
263 litest_drain_events(li);
264
265 status = libinput_device_config_send_events_set_mode(device,
266 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
267 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
268
269 /* no event from disabling */
270 litest_assert_empty_queue(li);
271
272 litest_touch_down(dev, 0, 50, 50);
273 litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
274 litest_touch_up(dev, 0);
275
276 litest_assert_empty_queue(li);
277
278 /* no event from resuming */
279 status = libinput_device_config_send_events_set_mode(device,
280 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
281 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
282 litest_assert_empty_queue(li);
283 }
284 END_TEST
285
START_TEST(device_disable_touch_during_touch)286 START_TEST(device_disable_touch_during_touch)
287 {
288 struct litest_device *dev = litest_current_device();
289 struct libinput *li = dev->libinput;
290 struct libinput_device *device;
291 enum libinput_config_status status;
292 struct libinput_event *event;
293
294 device = dev->libinput_device;
295
296 litest_touch_down(dev, 0, 50, 50);
297 litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
298 litest_drain_events(li);
299
300 status = libinput_device_config_send_events_set_mode(device,
301 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
302 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
303
304 /* after disabling sendevents we require a touch up */
305 libinput_dispatch(li);
306 event = libinput_get_event(li);
307 litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_CANCEL);
308 libinput_event_destroy(event);
309
310 event = libinput_get_event(li);
311 litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
312 libinput_event_destroy(event);
313
314 litest_assert_empty_queue(li);
315
316 litest_touch_move_to(dev, 0, 90, 90, 50, 50, 10);
317 litest_touch_up(dev, 0);
318
319 litest_touch_down(dev, 0, 50, 50);
320 litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10);
321 litest_touch_up(dev, 0);
322
323 litest_assert_empty_queue(li);
324
325 /* no event from resuming */
326 status = libinput_device_config_send_events_set_mode(device,
327 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
328 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
329 litest_assert_empty_queue(li);
330 }
331 END_TEST
332
START_TEST(device_disable_events_pending)333 START_TEST(device_disable_events_pending)
334 {
335 struct litest_device *dev = litest_current_device();
336 struct libinput *li = dev->libinput;
337 struct libinput_device *device;
338 enum libinput_config_status status;
339 struct libinput_event *event;
340 int i;
341
342 device = dev->libinput_device;
343
344 litest_drain_events(li);
345
346 /* put a couple of events in the queue, enough to
347 feed the ptraccel trackers */
348 for (i = 0; i < 10; i++) {
349 litest_event(dev, EV_REL, REL_X, 10);
350 litest_event(dev, EV_SYN, SYN_REPORT, 0);
351 }
352 libinput_dispatch(li);
353
354 status = libinput_device_config_send_events_set_mode(device,
355 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
356 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
357
358 /* expect above events */
359 litest_wait_for_event(li);
360 while ((event = libinput_get_event(li)) != NULL) {
361 ck_assert_int_eq(libinput_event_get_type(event),
362 LIBINPUT_EVENT_POINTER_MOTION);
363 libinput_event_destroy(event);
364 }
365 }
366 END_TEST
367
START_TEST(device_double_disable)368 START_TEST(device_double_disable)
369 {
370 struct litest_device *dev = litest_current_device();
371 struct libinput *li = dev->libinput;
372 struct libinput_device *device;
373 enum libinput_config_status status;
374
375 device = dev->libinput_device;
376
377 litest_drain_events(li);
378
379 status = libinput_device_config_send_events_set_mode(device,
380 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
381 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
382
383 status = libinput_device_config_send_events_set_mode(device,
384 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
385 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
386
387 litest_assert_empty_queue(li);
388 }
389 END_TEST
390
START_TEST(device_double_enable)391 START_TEST(device_double_enable)
392 {
393 struct litest_device *dev = litest_current_device();
394 struct libinput *li = dev->libinput;
395 struct libinput_device *device;
396 enum libinput_config_status status;
397
398 device = dev->libinput_device;
399
400 litest_drain_events(li);
401
402 status = libinput_device_config_send_events_set_mode(device,
403 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
404 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
405
406 status = libinput_device_config_send_events_set_mode(device,
407 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
408 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
409
410 litest_assert_empty_queue(li);
411 }
412 END_TEST
413
START_TEST(device_reenable_syspath_changed)414 START_TEST(device_reenable_syspath_changed)
415 {
416 struct libinput *li;
417 struct litest_device *litest_device;
418 struct libinput_device *device1;
419 enum libinput_config_status status;
420 struct libinput_event *event;
421
422 li = litest_create_context();
423 litest_device = litest_add_device(li, LITEST_MOUSE);
424 device1 = litest_device->libinput_device;
425
426 libinput_device_ref(device1);
427 status = libinput_device_config_send_events_set_mode(device1,
428 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
429 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
430
431 litest_drain_events(li);
432
433 litest_delete_device(litest_device);
434 litest_drain_events(li);
435
436 litest_device = litest_add_device(li, LITEST_MOUSE);
437
438 status = libinput_device_config_send_events_set_mode(device1,
439 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
440 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
441
442 /* can't really check for much here, other than that if we pump
443 events through libinput, none of them should be from the first
444 device */
445 litest_event(litest_device, EV_REL, REL_X, 1);
446 litest_event(litest_device, EV_REL, REL_Y, 1);
447 litest_event(litest_device, EV_SYN, SYN_REPORT, 0);
448
449 libinput_dispatch(li);
450 while ((event = libinput_get_event(li))) {
451 ck_assert(libinput_event_get_device(event) != device1);
452 libinput_event_destroy(event);
453 }
454
455 litest_delete_device(litest_device);
456 libinput_device_unref(device1);
457 litest_destroy_context(li);
458 }
459 END_TEST
460
START_TEST(device_reenable_device_removed)461 START_TEST(device_reenable_device_removed)
462 {
463 struct libinput *li;
464 struct litest_device *litest_device;
465 struct libinput_device *device;
466 enum libinput_config_status status;
467
468 li = litest_create_context();
469 litest_device = litest_add_device(li, LITEST_MOUSE);
470 device = litest_device->libinput_device;
471
472 libinput_device_ref(device);
473 status = libinput_device_config_send_events_set_mode(device,
474 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
475 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
476
477 litest_drain_events(li);
478
479 litest_delete_device(litest_device);
480 litest_drain_events(li);
481
482 status = libinput_device_config_send_events_set_mode(device,
483 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
484 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
485
486 /* can't really check for much here, this really just exercises the
487 code path. */
488 litest_assert_empty_queue(li);
489
490 libinput_device_unref(device);
491 litest_destroy_context(li);
492 }
493 END_TEST
494
START_TEST(device_disable_release_buttons)495 START_TEST(device_disable_release_buttons)
496 {
497 struct litest_device *dev = litest_current_device();
498 struct libinput *li = dev->libinput;
499 struct libinput_device *device;
500 struct libinput_event *event;
501 struct libinput_event_pointer *ptrevent;
502 enum libinput_config_status status;
503
504 device = dev->libinput_device;
505
506 litest_button_click_debounced(dev, li, BTN_LEFT, true);
507 litest_drain_events(li);
508
509 status = libinput_device_config_send_events_set_mode(device,
510 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
511 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
512
513 litest_wait_for_event(li);
514 event = libinput_get_event(li);
515
516 ck_assert_int_eq(libinput_event_get_type(event),
517 LIBINPUT_EVENT_POINTER_BUTTON);
518 ptrevent = libinput_event_get_pointer_event(event);
519 ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
520 BTN_LEFT);
521 ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
522 LIBINPUT_BUTTON_STATE_RELEASED);
523
524 libinput_event_destroy(event);
525 litest_assert_empty_queue(li);
526 }
527 END_TEST
528
START_TEST(device_disable_release_keys)529 START_TEST(device_disable_release_keys)
530 {
531 struct litest_device *dev = litest_current_device();
532 struct libinput *li = dev->libinput;
533 struct libinput_device *device;
534 struct libinput_event *event;
535 struct libinput_event_keyboard *kbdevent;
536 enum libinput_config_status status;
537
538 device = dev->libinput_device;
539
540 litest_keyboard_key(dev, KEY_A, true);
541 litest_drain_events(li);
542
543 status = libinput_device_config_send_events_set_mode(device,
544 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
545 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
546
547 litest_wait_for_event(li);
548 event = libinput_get_event(li);
549
550 ck_assert_int_eq(libinput_event_get_type(event),
551 LIBINPUT_EVENT_KEYBOARD_KEY);
552 kbdevent = libinput_event_get_keyboard_event(event);
553 ck_assert_int_eq(libinput_event_keyboard_get_key(kbdevent),
554 KEY_A);
555 ck_assert_int_eq(libinput_event_keyboard_get_key_state(kbdevent),
556 LIBINPUT_KEY_STATE_RELEASED);
557
558 libinput_event_destroy(event);
559 litest_assert_empty_queue(li);
560 }
561 END_TEST
562
START_TEST(device_disable_release_tap)563 START_TEST(device_disable_release_tap)
564 {
565 struct litest_device *dev = litest_current_device();
566 struct libinput *li = dev->libinput;
567 struct libinput_device *device;
568 enum libinput_config_status status;
569
570 device = dev->libinput_device;
571
572 libinput_device_config_tap_set_enabled(device,
573 LIBINPUT_CONFIG_TAP_ENABLED);
574
575 litest_drain_events(li);
576
577 litest_touch_down(dev, 0, 50, 50);
578 litest_touch_up(dev, 0);
579
580 libinput_dispatch(li);
581
582 status = libinput_device_config_send_events_set_mode(device,
583 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
584 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
585 /* tap happened before suspending, so we still expect the event */
586
587 litest_timeout_tap();
588
589 litest_assert_button_event(li,
590 BTN_LEFT,
591 LIBINPUT_BUTTON_STATE_PRESSED);
592 litest_assert_button_event(li,
593 BTN_LEFT,
594 LIBINPUT_BUTTON_STATE_RELEASED);
595
596 litest_assert_empty_queue(li);
597
598 /* resume, make sure we don't get anything */
599 status = libinput_device_config_send_events_set_mode(device,
600 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
601 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
602 libinput_dispatch(li);
603 litest_assert_empty_queue(li);
604
605 }
606 END_TEST
607
START_TEST(device_disable_release_tap_n_drag)608 START_TEST(device_disable_release_tap_n_drag)
609 {
610 struct litest_device *dev = litest_current_device();
611 struct libinput *li = dev->libinput;
612 struct libinput_device *device;
613 enum libinput_config_status status;
614
615 device = dev->libinput_device;
616
617 libinput_device_config_tap_set_enabled(device,
618 LIBINPUT_CONFIG_TAP_ENABLED);
619
620 litest_drain_events(li);
621
622 litest_touch_down(dev, 0, 50, 50);
623 litest_touch_up(dev, 0);
624 litest_touch_down(dev, 0, 50, 50);
625 libinput_dispatch(li);
626 litest_timeout_tap();
627 libinput_dispatch(li);
628
629 status = libinput_device_config_send_events_set_mode(device,
630 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
631 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
632
633 libinput_dispatch(li);
634 litest_touch_up(dev, 0);
635
636 litest_assert_button_event(li,
637 BTN_LEFT,
638 LIBINPUT_BUTTON_STATE_PRESSED);
639 litest_assert_button_event(li,
640 BTN_LEFT,
641 LIBINPUT_BUTTON_STATE_RELEASED);
642
643 litest_assert_empty_queue(li);
644 }
645 END_TEST
646
START_TEST(device_disable_release_softbutton)647 START_TEST(device_disable_release_softbutton)
648 {
649 struct litest_device *dev = litest_current_device();
650 struct libinput *li = dev->libinput;
651 struct libinput_device *device;
652 enum libinput_config_status status;
653
654 device = dev->libinput_device;
655
656 litest_drain_events(li);
657
658 litest_touch_down(dev, 0, 90, 90);
659 litest_button_click_debounced(dev, li, BTN_LEFT, true);
660
661 /* make sure softbutton works */
662 litest_assert_button_event(li,
663 BTN_RIGHT,
664 LIBINPUT_BUTTON_STATE_PRESSED);
665 /* disable */
666 status = libinput_device_config_send_events_set_mode(device,
667 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
668 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
669
670 litest_assert_button_event(li,
671 BTN_RIGHT,
672 LIBINPUT_BUTTON_STATE_RELEASED);
673
674 litest_assert_empty_queue(li);
675
676 litest_button_click_debounced(dev, li, BTN_LEFT, false);
677 litest_touch_up(dev, 0);
678
679 litest_assert_empty_queue(li);
680
681 /* resume, make sure we don't get anything */
682 status = libinput_device_config_send_events_set_mode(device,
683 LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
684 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
685 libinput_dispatch(li);
686 litest_assert_empty_queue(li);
687
688 }
689 END_TEST
690
START_TEST(device_disable_topsoftbutton)691 START_TEST(device_disable_topsoftbutton)
692 {
693 struct litest_device *dev = litest_current_device();
694 struct litest_device *trackpoint;
695 struct libinput *li = dev->libinput;
696 struct libinput_device *device;
697 enum libinput_config_status status;
698
699 struct libinput_event *event;
700 struct libinput_event_pointer *ptrevent;
701
702 device = dev->libinput_device;
703
704 trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
705
706 status = libinput_device_config_send_events_set_mode(device,
707 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
708 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
709 litest_drain_events(li);
710
711 litest_touch_down(dev, 0, 90, 10);
712 litest_button_click_debounced(dev, li, BTN_LEFT, true);
713 litest_button_click_debounced(dev, li, BTN_LEFT, false);
714 litest_touch_up(dev, 0);
715
716 litest_wait_for_event(li);
717 event = libinput_get_event(li);
718 ck_assert_int_eq(libinput_event_get_type(event),
719 LIBINPUT_EVENT_POINTER_BUTTON);
720 ck_assert_ptr_eq(libinput_event_get_device(event),
721 trackpoint->libinput_device);
722 ptrevent = libinput_event_get_pointer_event(event);
723 ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
724 BTN_RIGHT);
725 ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
726 LIBINPUT_BUTTON_STATE_PRESSED);
727 libinput_event_destroy(event);
728
729 event = libinput_get_event(li);
730 ck_assert_int_eq(libinput_event_get_type(event),
731 LIBINPUT_EVENT_POINTER_BUTTON);
732 ck_assert_ptr_eq(libinput_event_get_device(event),
733 trackpoint->libinput_device);
734 ptrevent = libinput_event_get_pointer_event(event);
735 ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent),
736 BTN_RIGHT);
737 ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent),
738 LIBINPUT_BUTTON_STATE_RELEASED);
739 libinput_event_destroy(event);
740
741 litest_assert_empty_queue(li);
742
743 litest_delete_device(trackpoint);
744 }
745 END_TEST
746
START_TEST(device_ids)747 START_TEST(device_ids)
748 {
749 struct litest_device *dev = litest_current_device();
750 const char *name;
751 unsigned int pid, vid;
752
753 name = libevdev_get_name(dev->evdev);
754 pid = libevdev_get_id_product(dev->evdev);
755 vid = libevdev_get_id_vendor(dev->evdev);
756
757 ck_assert_str_eq(name,
758 libinput_device_get_name(dev->libinput_device));
759 ck_assert_int_eq(pid,
760 libinput_device_get_id_product(dev->libinput_device));
761 ck_assert_int_eq(vid,
762 libinput_device_get_id_vendor(dev->libinput_device));
763 }
764 END_TEST
765
START_TEST(device_get_udev_handle)766 START_TEST(device_get_udev_handle)
767 {
768 struct litest_device *dev = litest_current_device();
769 struct udev_device *udev_device;
770
771 udev_device = libinput_device_get_udev_device(dev->libinput_device);
772 ck_assert_notnull(udev_device);
773 udev_device_unref(udev_device);
774 }
775 END_TEST
776
START_TEST(device_context)777 START_TEST(device_context)
778 {
779 struct litest_device *dev = litest_current_device();
780 struct libinput_seat *seat;
781
782 ck_assert(dev->libinput == libinput_device_get_context(dev->libinput_device));
783 seat = libinput_device_get_seat(dev->libinput_device);
784 ck_assert(dev->libinput == libinput_seat_get_context(seat));
785 }
786 END_TEST
787
START_TEST(device_user_data)788 START_TEST(device_user_data)
789 {
790 struct litest_device *dev = litest_current_device();
791 struct libinput_device *device = dev->libinput_device;
792 void *userdata = &dev; /* not referenced */
793
794 ck_assert(libinput_device_get_user_data(device) == NULL);
795 libinput_device_set_user_data(device, userdata);
796 ck_assert_ptr_eq(libinput_device_get_user_data(device), userdata);
797 libinput_device_set_user_data(device, NULL);
798 ck_assert(libinput_device_get_user_data(device) == NULL);
799 }
800 END_TEST
801
START_TEST(device_group_get)802 START_TEST(device_group_get)
803 {
804 struct litest_device *dev = litest_current_device();
805 struct libinput_device_group *group;
806
807 int userdata = 10;
808
809 group = libinput_device_get_device_group(dev->libinput_device);
810 ck_assert_notnull(group);
811
812 libinput_device_group_ref(group);
813
814 libinput_device_group_set_user_data(group, &userdata);
815 ck_assert_ptr_eq(&userdata,
816 libinput_device_group_get_user_data(group));
817
818 libinput_device_group_unref(group);
819 }
820 END_TEST
821
START_TEST(device_group_ref)822 START_TEST(device_group_ref)
823 {
824 struct libinput *li = litest_create_context();
825 struct litest_device *dev = litest_add_device(li,
826 LITEST_MOUSE);
827 struct libinput_device *device = dev->libinput_device;
828 struct libinput_device_group *group;
829
830 group = libinput_device_get_device_group(device);
831 ck_assert_notnull(group);
832 libinput_device_group_ref(group);
833
834 libinput_device_ref(device);
835 litest_drain_events(li);
836 litest_delete_device(dev);
837 litest_drain_events(li);
838
839 /* make sure the device is dead but the group is still around */
840 ck_assert(libinput_device_unref(device) == NULL);
841
842 libinput_device_group_ref(group);
843 ck_assert_notnull(libinput_device_group_unref(group));
844 ck_assert(libinput_device_group_unref(group) == NULL);
845
846 litest_destroy_context(li);
847 }
848 END_TEST
849
START_TEST(device_group_leak)850 START_TEST(device_group_leak)
851 {
852 struct libinput *li;
853 struct libinput_device *device;
854 struct libevdev_uinput *uinput;
855 struct libinput_device_group *group;
856
857 uinput = litest_create_uinput_device("test device", NULL,
858 EV_KEY, BTN_LEFT,
859 EV_KEY, BTN_RIGHT,
860 EV_REL, REL_X,
861 EV_REL, REL_Y,
862 -1);
863
864 li = litest_create_context();
865 device = libinput_path_add_device(li,
866 libevdev_uinput_get_devnode(uinput));
867
868 group = libinput_device_get_device_group(device);
869 libinput_device_group_ref(group);
870
871 libinput_path_remove_device(device);
872
873 libevdev_uinput_destroy(uinput);
874 litest_destroy_context(li);
875
876 /* the device group leaks, check valgrind */
877 }
878 END_TEST
879
START_TEST(abs_device_no_absx)880 START_TEST(abs_device_no_absx)
881 {
882 struct libevdev_uinput *uinput;
883 struct libinput *li;
884 struct libinput_device *device;
885
886 uinput = litest_create_uinput_device("test device", NULL,
887 EV_KEY, BTN_LEFT,
888 EV_KEY, BTN_RIGHT,
889 EV_ABS, ABS_Y,
890 -1);
891 li = litest_create_context();
892 litest_disable_log_handler(li);
893 device = libinput_path_add_device(li,
894 libevdev_uinput_get_devnode(uinput));
895 litest_restore_log_handler(li);
896 ck_assert(device == NULL);
897 litest_destroy_context(li);
898
899 libevdev_uinput_destroy(uinput);
900 }
901 END_TEST
902
START_TEST(abs_device_no_absy)903 START_TEST(abs_device_no_absy)
904 {
905 struct libevdev_uinput *uinput;
906 struct libinput *li;
907 struct libinput_device *device;
908
909 uinput = litest_create_uinput_device("test device", NULL,
910 EV_KEY, BTN_LEFT,
911 EV_KEY, BTN_RIGHT,
912 EV_ABS, ABS_X,
913 -1);
914 li = litest_create_context();
915 litest_disable_log_handler(li);
916 device = libinput_path_add_device(li,
917 libevdev_uinput_get_devnode(uinput));
918 litest_restore_log_handler(li);
919 ck_assert(device == NULL);
920 litest_destroy_context(li);
921
922 libevdev_uinput_destroy(uinput);
923 }
924 END_TEST
925
START_TEST(abs_mt_device_no_absy)926 START_TEST(abs_mt_device_no_absy)
927 {
928 struct libevdev_uinput *uinput;
929 struct libinput *li;
930 struct libinput_device *device;
931
932 uinput = litest_create_uinput_device("test device", NULL,
933 EV_KEY, BTN_LEFT,
934 EV_KEY, BTN_RIGHT,
935 EV_ABS, ABS_X,
936 EV_ABS, ABS_Y,
937 EV_ABS, ABS_MT_SLOT,
938 EV_ABS, ABS_MT_POSITION_X,
939 -1);
940 li = litest_create_context();
941 litest_disable_log_handler(li);
942 device = libinput_path_add_device(li,
943 libevdev_uinput_get_devnode(uinput));
944 litest_restore_log_handler(li);
945 ck_assert(device == NULL);
946 litest_destroy_context(li);
947
948 libevdev_uinput_destroy(uinput);
949 }
950 END_TEST
951
START_TEST(abs_mt_device_no_absx)952 START_TEST(abs_mt_device_no_absx)
953 {
954 struct libevdev_uinput *uinput;
955 struct libinput *li;
956 struct libinput_device *device;
957
958 uinput = litest_create_uinput_device("test device", NULL,
959 EV_KEY, BTN_LEFT,
960 EV_KEY, BTN_RIGHT,
961 EV_ABS, ABS_X,
962 EV_ABS, ABS_Y,
963 EV_ABS, ABS_MT_SLOT,
964 EV_ABS, ABS_MT_POSITION_Y,
965 -1);
966 li = litest_create_context();
967 litest_disable_log_handler(li);
968 device = libinput_path_add_device(li,
969 libevdev_uinput_get_devnode(uinput));
970 litest_restore_log_handler(li);
971 ck_assert(device == NULL);
972 litest_destroy_context(li);
973
974 libevdev_uinput_destroy(uinput);
975 }
976 END_TEST
977
978 static void
assert_device_ignored(struct libinput * li,struct input_absinfo * absinfo)979 assert_device_ignored(struct libinput *li, struct input_absinfo *absinfo)
980 {
981 struct libevdev_uinput *uinput;
982 struct libinput_device *device;
983
984 uinput = litest_create_uinput_abs_device("test device", NULL,
985 absinfo,
986 EV_KEY, BTN_LEFT,
987 EV_KEY, BTN_RIGHT,
988 -1);
989 device = libinput_path_add_device(li,
990 libevdev_uinput_get_devnode(uinput));
991 litest_assert_ptr_null(device);
992 libevdev_uinput_destroy(uinput);
993 }
994
START_TEST(abs_device_no_range)995 START_TEST(abs_device_no_range)
996 {
997 struct libinput *li;
998 int code = _i; /* looped test */
999 /* set x/y so libinput doesn't just reject for missing axes */
1000 struct input_absinfo absinfo[] = {
1001 { ABS_X, 0, 10, 0, 0, 0 },
1002 { ABS_Y, 0, 10, 0, 0, 0 },
1003 { code, 0, 0, 0, 0, 0 },
1004 { -1, -1, -1, -1, -1, -1 }
1005 };
1006
1007 li = litest_create_context();
1008 litest_disable_log_handler(li);
1009
1010 assert_device_ignored(li, absinfo);
1011
1012 litest_restore_log_handler(li);
1013 litest_destroy_context(li);
1014 }
1015 END_TEST
1016
START_TEST(abs_mt_device_no_range)1017 START_TEST(abs_mt_device_no_range)
1018 {
1019 struct libinput *li;
1020 int code = _i; /* looped test */
1021 /* set x/y so libinput doesn't just reject for missing axes */
1022 struct input_absinfo absinfo[] = {
1023 { ABS_X, 0, 10, 0, 0, 0 },
1024 { ABS_Y, 0, 10, 0, 0, 0 },
1025 { ABS_MT_SLOT, 0, 10, 0, 0, 0 },
1026 { ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1027 { ABS_MT_POSITION_X, 0, 10, 0, 0, 0 },
1028 { ABS_MT_POSITION_Y, 0, 10, 0, 0, 0 },
1029 { code, 0, 0, 0, 0, 0 },
1030 { -1, -1, -1, -1, -1, -1 }
1031 };
1032
1033 li = litest_create_context();
1034 litest_disable_log_handler(li);
1035
1036 if (code != ABS_MT_TOOL_TYPE &&
1037 code != ABS_MT_TRACKING_ID) /* kernel overrides it */
1038 assert_device_ignored(li, absinfo);
1039
1040 litest_restore_log_handler(li);
1041 litest_destroy_context(li);
1042 }
1043 END_TEST
1044
START_TEST(abs_device_missing_res)1045 START_TEST(abs_device_missing_res)
1046 {
1047 struct libinput *li;
1048 struct input_absinfo absinfo[] = {
1049 { ABS_X, 0, 10, 0, 0, 10 },
1050 { ABS_Y, 0, 10, 0, 0, 0 },
1051 { -1, -1, -1, -1, -1, -1 }
1052 };
1053
1054 li = litest_create_context();
1055 litest_disable_log_handler(li);
1056
1057 assert_device_ignored(li, absinfo);
1058
1059 absinfo[0].resolution = 0;
1060 absinfo[1].resolution = 20;
1061
1062 assert_device_ignored(li, absinfo);
1063
1064 litest_restore_log_handler(li);
1065 litest_destroy_context(li);
1066 }
1067 END_TEST
1068
START_TEST(abs_mt_device_missing_res)1069 START_TEST(abs_mt_device_missing_res)
1070 {
1071 struct libinput *li;
1072 struct input_absinfo absinfo[] = {
1073 { ABS_X, 0, 10, 0, 0, 10 },
1074 { ABS_Y, 0, 10, 0, 0, 10 },
1075 { ABS_MT_SLOT, 0, 2, 0, 0, 0 },
1076 { ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1077 { ABS_MT_POSITION_X, 0, 10, 0, 0, 10 },
1078 { ABS_MT_POSITION_Y, 0, 10, 0, 0, 0 },
1079 { -1, -1, -1, -1, -1, -1 }
1080 };
1081
1082 li = litest_create_context();
1083 litest_disable_log_handler(li);
1084 assert_device_ignored(li, absinfo);
1085
1086 absinfo[4].resolution = 0;
1087 absinfo[5].resolution = 20;
1088
1089 assert_device_ignored(li, absinfo);
1090
1091 litest_restore_log_handler(li);
1092 litest_destroy_context(li);
1093
1094 }
1095 END_TEST
1096
START_TEST(ignore_joystick)1097 START_TEST(ignore_joystick)
1098 {
1099 struct libinput *li;
1100 struct libevdev_uinput *uinput;
1101 struct libinput_device *device;
1102 struct input_absinfo absinfo[] = {
1103 { ABS_X, 0, 10, 0, 0, 10 },
1104 { ABS_Y, 0, 10, 0, 0, 10 },
1105 { ABS_RX, 0, 10, 0, 0, 10 },
1106 { ABS_RY, 0, 10, 0, 0, 10 },
1107 { ABS_THROTTLE, 0, 2, 0, 0, 0 },
1108 { ABS_RUDDER, 0, 255, 0, 0, 0 },
1109 { -1, -1, -1, -1, -1, -1 }
1110 };
1111
1112 li = litest_create_context();
1113 litest_disable_log_handler(li);
1114 litest_drain_events(li);
1115
1116 uinput = litest_create_uinput_abs_device("joystick test device", NULL,
1117 absinfo,
1118 EV_KEY, BTN_TRIGGER,
1119 EV_KEY, BTN_A,
1120 -1);
1121 device = libinput_path_add_device(li,
1122 libevdev_uinput_get_devnode(uinput));
1123 litest_assert_ptr_null(device);
1124 libevdev_uinput_destroy(uinput);
1125 litest_restore_log_handler(li);
1126 litest_destroy_context(li);
1127 }
1128 END_TEST
1129
START_TEST(device_wheel_only)1130 START_TEST(device_wheel_only)
1131 {
1132 struct litest_device *dev = litest_current_device();
1133 struct libinput_device *device = dev->libinput_device;
1134
1135 ck_assert(libinput_device_has_capability(device,
1136 LIBINPUT_DEVICE_CAP_POINTER));
1137 }
1138 END_TEST
1139
START_TEST(device_accelerometer)1140 START_TEST(device_accelerometer)
1141 {
1142 struct libinput *li;
1143 struct libevdev_uinput *uinput;
1144 struct libinput_device *device;
1145
1146 struct input_absinfo absinfo[] = {
1147 { ABS_X, 0, 10, 0, 0, 10 },
1148 { ABS_Y, 0, 10, 0, 0, 10 },
1149 { ABS_Z, 0, 10, 0, 0, 10 },
1150 { -1, -1, -1, -1, -1, -1 }
1151 };
1152
1153 li = litest_create_context();
1154 litest_disable_log_handler(li);
1155
1156 uinput = litest_create_uinput_abs_device("test device", NULL,
1157 absinfo,
1158 -1);
1159 device = libinput_path_add_device(li,
1160 libevdev_uinput_get_devnode(uinput));
1161 litest_assert_ptr_null(device);
1162 libevdev_uinput_destroy(uinput);
1163 litest_restore_log_handler(li);
1164 litest_destroy_context(li);
1165 }
1166 END_TEST
1167
START_TEST(device_udev_tag_wacom_tablet)1168 START_TEST(device_udev_tag_wacom_tablet)
1169 {
1170 struct litest_device *dev = litest_current_device();
1171 struct libinput_device *device = dev->libinput_device;
1172 struct udev_device *d;
1173 const char *prop;
1174
1175 d = libinput_device_get_udev_device(device);
1176 prop = udev_device_get_property_value(d,
1177 "ID_INPUT_TABLET");
1178
1179 ck_assert_notnull(prop);
1180 udev_device_unref(d);
1181 }
1182 END_TEST
1183
START_TEST(device_nonpointer_rel)1184 START_TEST(device_nonpointer_rel)
1185 {
1186 struct libevdev_uinput *uinput;
1187 struct libinput *li;
1188 struct libinput_device *device;
1189 int i;
1190
1191 uinput = litest_create_uinput_device("test device",
1192 NULL,
1193 EV_KEY, KEY_A,
1194 EV_KEY, KEY_B,
1195 EV_REL, REL_X,
1196 EV_REL, REL_Y,
1197 -1);
1198 li = litest_create_context();
1199 device = libinput_path_add_device(li,
1200 libevdev_uinput_get_devnode(uinput));
1201 ck_assert_notnull(device);
1202
1203 litest_disable_log_handler(li);
1204 for (i = 0; i < 100; i++) {
1205 libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1206 libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1207 libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1208 libinput_dispatch(li);
1209 }
1210 litest_restore_log_handler(li);
1211
1212 litest_destroy_context(li);
1213 libevdev_uinput_destroy(uinput);
1214 }
1215 END_TEST
1216
START_TEST(device_touchpad_rel)1217 START_TEST(device_touchpad_rel)
1218 {
1219 struct libevdev_uinput *uinput;
1220 struct libinput *li;
1221 struct libinput_device *device;
1222 const struct input_absinfo abs[] = {
1223 { ABS_X, 0, 10, 0, 0, 10 },
1224 { ABS_Y, 0, 10, 0, 0, 10 },
1225 { ABS_MT_SLOT, 0, 2, 0, 0, 0 },
1226 { ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1227 { ABS_MT_POSITION_X, 0, 10, 0, 0, 10 },
1228 { ABS_MT_POSITION_Y, 0, 10, 0, 0, 10 },
1229 { -1, -1, -1, -1, -1, -1 }
1230 };
1231 int i;
1232
1233 uinput = litest_create_uinput_abs_device("test device",
1234 NULL, abs,
1235 EV_KEY, BTN_TOOL_FINGER,
1236 EV_KEY, BTN_TOUCH,
1237 EV_REL, REL_X,
1238 EV_REL, REL_Y,
1239 -1);
1240 li = litest_create_context();
1241 device = libinput_path_add_device(li,
1242 libevdev_uinput_get_devnode(uinput));
1243 ck_assert_notnull(device);
1244
1245 for (i = 0; i < 100; i++) {
1246 libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1247 libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1248 libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1249 libinput_dispatch(li);
1250 }
1251
1252 litest_destroy_context(li);
1253 libevdev_uinput_destroy(uinput);
1254 }
1255 END_TEST
1256
START_TEST(device_touch_rel)1257 START_TEST(device_touch_rel)
1258 {
1259 struct libevdev_uinput *uinput;
1260 struct libinput *li;
1261 struct libinput_device *device;
1262 const struct input_absinfo abs[] = {
1263 { ABS_X, 0, 10, 0, 0, 10 },
1264 { ABS_Y, 0, 10, 0, 0, 10 },
1265 { ABS_MT_SLOT, 0, 2, 0, 0, 0 },
1266 { ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 },
1267 { ABS_MT_POSITION_X, 0, 10, 0, 0, 10 },
1268 { ABS_MT_POSITION_Y, 0, 10, 0, 0, 10 },
1269 { -1, -1, -1, -1, -1, -1 }
1270 };
1271 int i;
1272
1273 uinput = litest_create_uinput_abs_device("test device",
1274 NULL, abs,
1275 EV_KEY, BTN_TOUCH,
1276 EV_REL, REL_X,
1277 EV_REL, REL_Y,
1278 -1);
1279 li = litest_create_context();
1280 device = libinput_path_add_device(li,
1281 libevdev_uinput_get_devnode(uinput));
1282 ck_assert_notnull(device);
1283
1284 litest_disable_log_handler(li);
1285 for (i = 0; i < 100; i++) {
1286 libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1287 libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1288 libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1289 libinput_dispatch(li);
1290 }
1291 litest_restore_log_handler(li);
1292
1293 litest_destroy_context(li);
1294 libevdev_uinput_destroy(uinput);
1295 }
1296 END_TEST
1297
START_TEST(device_abs_rel)1298 START_TEST(device_abs_rel)
1299 {
1300 struct libevdev_uinput *uinput;
1301 struct libinput *li;
1302 struct libinput_device *device;
1303 const struct input_absinfo abs[] = {
1304 { ABS_X, 0, 10, 0, 0, 10 },
1305 { ABS_Y, 0, 10, 0, 0, 10 },
1306 { -1, -1, -1, -1, -1, -1 }
1307 };
1308 int i;
1309
1310 uinput = litest_create_uinput_abs_device("test device",
1311 NULL, abs,
1312 EV_KEY, BTN_TOUCH,
1313 EV_KEY, BTN_LEFT,
1314 EV_REL, REL_X,
1315 EV_REL, REL_Y,
1316 -1);
1317 li = litest_create_context();
1318 device = libinput_path_add_device(li,
1319 libevdev_uinput_get_devnode(uinput));
1320 ck_assert_notnull(device);
1321
1322 for (i = 0; i < 100; i++) {
1323 libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
1324 libevdev_uinput_write_event(uinput, EV_REL, REL_Y, -1);
1325 libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
1326 libinput_dispatch(li);
1327 }
1328
1329 litest_destroy_context(li);
1330 libevdev_uinput_destroy(uinput);
1331 }
1332 END_TEST
1333
START_TEST(device_quirks_no_abs_mt_y)1334 START_TEST(device_quirks_no_abs_mt_y)
1335 {
1336 struct litest_device *dev = litest_current_device();
1337 struct libinput *li = dev->libinput;
1338 struct libinput_event *event;
1339 struct libinput_event_pointer *pev;
1340 bool hi_res_event_found, low_res_event_found;
1341 int code, i;
1342
1343 hi_res_event_found = false;
1344 low_res_event_found = false;
1345
1346 litest_drain_events(li);
1347
1348 litest_event(dev, EV_REL, REL_HWHEEL, 1);
1349 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1350 libinput_dispatch(li);
1351
1352 /* both high and low scroll end events must be sent */
1353 for (i = 0; i < 2; i++) {
1354 event = libinput_get_event(li);
1355 pev = litest_is_axis_event(event,
1356 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
1357 LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
1358 LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
1359
1360 if (litest_is_high_res_axis_event(event)) {
1361 litest_assert(!hi_res_event_found);
1362 hi_res_event_found = true;
1363 } else {
1364 litest_assert(!low_res_event_found);
1365 low_res_event_found = true;
1366 }
1367
1368 libinput_event_destroy(libinput_event_pointer_get_base_event(pev));
1369 }
1370
1371 litest_assert(low_res_event_found);
1372 litest_assert(hi_res_event_found);
1373
1374 for (code = ABS_MISC + 1; code < ABS_MAX; code++) {
1375 litest_event(dev, EV_ABS, code, 1);
1376 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1377 litest_assert_empty_queue(li);
1378 }
1379
1380 }
1381 END_TEST
1382
START_TEST(device_quirks_cyborg_rat_mode_button)1383 START_TEST(device_quirks_cyborg_rat_mode_button)
1384 {
1385 struct litest_device *dev = litest_current_device();
1386 struct libinput_device *device = dev->libinput_device;
1387 struct libinput *li = dev->libinput;
1388
1389 ck_assert(!libinput_device_pointer_has_button(device, 0x118));
1390 ck_assert(!libinput_device_pointer_has_button(device, 0x119));
1391 ck_assert(!libinput_device_pointer_has_button(device, 0x11a));
1392
1393 litest_drain_events(li);
1394
1395 litest_event(dev, EV_KEY, 0x118, 0);
1396 litest_event(dev, EV_KEY, 0x119, 1);
1397 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1398
1399 litest_assert_empty_queue(li);
1400
1401 litest_event(dev, EV_KEY, 0x119, 0);
1402 litest_event(dev, EV_KEY, 0x11a, 1);
1403 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1404
1405 litest_assert_empty_queue(li);
1406
1407 litest_event(dev, EV_KEY, 0x11a, 0);
1408 litest_event(dev, EV_KEY, 0x118, 1);
1409 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1410
1411 litest_assert_empty_queue(li);
1412 }
1413 END_TEST
1414
START_TEST(device_quirks_apple_magicmouse)1415 START_TEST(device_quirks_apple_magicmouse)
1416 {
1417 struct litest_device *dev = litest_current_device();
1418 struct libinput *li = dev->libinput;
1419
1420 litest_drain_events(li);
1421
1422 /* ensure we get no events from the touch */
1423 litest_touch_down(dev, 0, 50, 50);
1424 litest_touch_move_to(dev, 0, 50, 50, 80, 80, 10);
1425 litest_touch_up(dev, 0);
1426 litest_assert_empty_queue(li);
1427 }
1428 END_TEST
1429
START_TEST(device_quirks_logitech_marble_mouse)1430 START_TEST(device_quirks_logitech_marble_mouse)
1431 {
1432 struct litest_device *dev = litest_current_device();
1433 struct libinput *li = dev->libinput;
1434
1435 litest_drain_events(li);
1436
1437 ck_assert(!libinput_device_pointer_has_button(dev->libinput_device,
1438 BTN_MIDDLE));
1439 }
1440 END_TEST
1441
1442 char *debug_messages[64] = { NULL };
1443
1444 LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
1445 static void
debug_log_handler(struct libinput * libinput,enum libinput_log_priority priority,const char * format,va_list args)1446 debug_log_handler(struct libinput *libinput,
1447 enum libinput_log_priority priority,
1448 const char *format,
1449 va_list args)
1450 {
1451 char *message, **dmsg;
1452 int n;
1453
1454 if (priority != LIBINPUT_LOG_PRIORITY_DEBUG)
1455 return;
1456
1457 n = xvasprintf(&message, format, args);
1458 litest_assert_int_gt(n, 0);
1459
1460 ARRAY_FOR_EACH(debug_messages, dmsg) {
1461 if (*dmsg == NULL) {
1462 *dmsg = message;
1463 return;
1464 }
1465 }
1466
1467 litest_abort_msg("Out of space for debug messages");
1468 }
1469
START_TEST(device_quirks)1470 START_TEST(device_quirks)
1471 {
1472 struct libinput *li;
1473 struct litest_device *dev;
1474 struct libinput_device *device;
1475 char **message;
1476 bool disable_key_f1 = false,
1477 enable_btn_left = false;
1478 #if HAVE_LIBEVDEV_DISABLE_PROPERTY
1479 bool disable_pointingstick = false,
1480 enable_buttonpad = false;
1481 #endif
1482
1483 li = litest_create_context();
1484 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG);
1485 libinput_log_set_handler(li, debug_log_handler);
1486 dev = litest_add_device(li, LITEST_KEYBOARD_QUIRKED);
1487 device = dev->libinput_device;
1488
1489 ck_assert(libinput_device_pointer_has_button(device,
1490 BTN_LEFT));
1491 ck_assert(libinput_device_pointer_has_button(dev->libinput_device,
1492 BTN_RIGHT));
1493 ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1494 KEY_F1));
1495 ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1496 KEY_F2));
1497 ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1498 KEY_F3));
1499
1500 /* Scrape the debug messages for confirmation that our quirks are
1501 * triggered, the above checks cannot work non-key codes */
1502 message = debug_messages;
1503 while (*message) {
1504 if (strstr(*message, "disabling EV_KEY KEY_F1"))
1505 disable_key_f1 = true;
1506 if (strstr(*message, "enabling EV_KEY BTN_LEFT"))
1507 enable_btn_left = true;
1508 #if HAVE_LIBEVDEV_DISABLE_PROPERTY
1509 if (strstr(*message, "enabling INPUT_PROP_BUTTONPAD"))
1510 enable_buttonpad = true;
1511 if (strstr(*message, "disabling INPUT_PROP_POINTING_STICK"))
1512 disable_pointingstick = true;
1513 #endif
1514 free(*message);
1515 message++;
1516 }
1517
1518 ck_assert(disable_key_f1);
1519 ck_assert(enable_btn_left);
1520 #if HAVE_LIBEVDEV_DISABLE_PROPERTY
1521 ck_assert(enable_buttonpad);
1522 ck_assert(disable_pointingstick);
1523 #endif
1524
1525 litest_disable_log_handler(li);
1526
1527 litest_delete_device(dev);
1528 litest_destroy_context(li);
1529 }
1530 END_TEST
1531
START_TEST(device_capability_at_least_one)1532 START_TEST(device_capability_at_least_one)
1533 {
1534 struct litest_device *dev = litest_current_device();
1535 struct libinput_device *device = dev->libinput_device;
1536 enum libinput_device_capability caps[] = {
1537 LIBINPUT_DEVICE_CAP_KEYBOARD,
1538 LIBINPUT_DEVICE_CAP_POINTER,
1539 LIBINPUT_DEVICE_CAP_TOUCH,
1540 LIBINPUT_DEVICE_CAP_TABLET_TOOL,
1541 LIBINPUT_DEVICE_CAP_TABLET_PAD,
1542 LIBINPUT_DEVICE_CAP_GESTURE,
1543 LIBINPUT_DEVICE_CAP_SWITCH,
1544 };
1545 enum libinput_device_capability *cap;
1546 int ncaps = 0;
1547
1548 ARRAY_FOR_EACH(caps, cap) {
1549 if (libinput_device_has_capability(device, *cap))
1550 ncaps++;
1551 }
1552 ck_assert_int_gt(ncaps, 0);
1553
1554 }
1555 END_TEST
1556
START_TEST(device_capability_check_invalid)1557 START_TEST(device_capability_check_invalid)
1558 {
1559 struct litest_device *dev = litest_current_device();
1560 struct libinput_device *device = dev->libinput_device;
1561
1562 ck_assert(!libinput_device_has_capability(device, -1));
1563 ck_assert(!libinput_device_has_capability(device, 7));
1564 ck_assert(!libinput_device_has_capability(device, 0xffff));
1565
1566 }
1567 END_TEST
1568
START_TEST(device_capability_nocaps_ignored)1569 START_TEST(device_capability_nocaps_ignored)
1570 {
1571 struct libevdev_uinput *uinput;
1572 struct libinput *li;
1573 struct libinput_device *device;
1574
1575 /* SW_PEN_INSERTED isn't handled in libinput so the device is
1576 * processed but ends up without seat capabilities and is ignored.
1577 */
1578 uinput = litest_create_uinput_device("test device", NULL,
1579 EV_SW, SW_PEN_INSERTED,
1580 -1);
1581 li = litest_create_context();
1582 device = libinput_path_add_device(li,
1583 libevdev_uinput_get_devnode(uinput));
1584 litest_assert_ptr_null(device);
1585
1586 litest_destroy_context(li);
1587 libevdev_uinput_destroy(uinput);
1588 }
1589 END_TEST
1590
START_TEST(device_has_size)1591 START_TEST(device_has_size)
1592 {
1593 struct litest_device *dev = litest_current_device();
1594 struct libinput_device *device = dev->libinput_device;
1595 double w, h;
1596 int rc;
1597
1598 rc = libinput_device_get_size(device, &w, &h);
1599 ck_assert_int_eq(rc, 0);
1600 /* This matches the current set of test devices but may fail if
1601 * newer ones are added */
1602 ck_assert_double_gt(w, 40);
1603 ck_assert_double_gt(h, 20);
1604 }
1605 END_TEST
1606
START_TEST(device_has_no_size)1607 START_TEST(device_has_no_size)
1608 {
1609 struct litest_device *dev = litest_current_device();
1610 struct libinput_device *device = dev->libinput_device;
1611 double w = 45, h = 67;
1612 int rc;
1613
1614 rc = libinput_device_get_size(device, &w, &h);
1615 ck_assert_int_eq(rc, -1);
1616 ck_assert_double_eq(w, 45);
1617 ck_assert_double_eq(h, 67);
1618 }
1619 END_TEST
1620
START_TEST(device_get_output)1621 START_TEST(device_get_output)
1622 {
1623 struct litest_device *dev = litest_current_device();
1624 struct libinput_device *device = dev->libinput_device;
1625 const char *output_name;
1626
1627 output_name = libinput_device_get_output_name(device);
1628 ck_assert_str_eq(output_name, "myOutput");
1629 }
1630 END_TEST
1631
START_TEST(device_no_output)1632 START_TEST(device_no_output)
1633 {
1634 struct litest_device *dev = litest_current_device();
1635 struct libinput_device *device = dev->libinput_device;
1636 const char *output_name;
1637
1638 output_name = libinput_device_get_output_name(device);
1639 ck_assert(output_name == NULL);
1640 }
1641 END_TEST
1642
START_TEST(device_seat_phys_name)1643 START_TEST(device_seat_phys_name)
1644 {
1645 struct litest_device *dev = litest_current_device();
1646 struct libinput_device *device = dev->libinput_device;
1647 struct libinput_seat *seat = libinput_device_get_seat(device);
1648 const char *seat_name;
1649
1650 seat_name = libinput_seat_get_physical_name(seat);
1651 ck_assert(streq(seat_name, "seat0"));
1652 }
1653 END_TEST
1654
START_TEST(device_button_down_remove)1655 START_TEST(device_button_down_remove)
1656 {
1657 struct litest_device *lidev = litest_current_device();
1658 struct litest_device *dev;
1659 struct libinput *li;
1660
1661 for (int code = 0; code < KEY_MAX; code++) {
1662 struct libinput_event *event;
1663 struct libinput_event_pointer *p;
1664 bool have_down = false,
1665 have_up = false;
1666 const char *keyname;
1667 int button_down = 0, button_up = 0;
1668
1669 keyname = libevdev_event_code_get_name(EV_KEY, code);
1670 if (!keyname ||
1671 !strneq(keyname, "BTN_", 4) ||
1672 strneq(keyname, "BTN_TOOL_", 9))
1673 continue;
1674
1675 if (!libevdev_has_event_code(lidev->evdev, EV_KEY, code))
1676 continue;
1677
1678 li = litest_create_context();
1679 dev = litest_add_device(li, lidev->which);
1680 litest_drain_events(li);
1681
1682 /* Clickpads require a touch down to trigger the button
1683 * press */
1684 if (libevdev_has_property(lidev->evdev, INPUT_PROP_BUTTONPAD)) {
1685 litest_touch_down(dev, 0, 20, 90);
1686 libinput_dispatch(li);
1687 }
1688
1689 litest_event(dev, EV_KEY, code, 1);
1690 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1691 libinput_dispatch(li);
1692
1693 litest_delete_device(dev);
1694 libinput_dispatch(li);
1695
1696 while ((event = libinput_get_event(li))) {
1697 if (libinput_event_get_type(event) !=
1698 LIBINPUT_EVENT_POINTER_BUTTON) {
1699 libinput_event_destroy(event);
1700 continue;
1701 }
1702
1703 p = libinput_event_get_pointer_event(event);
1704 if (libinput_event_pointer_get_button_state(p)) {
1705 ck_assert(button_down == 0);
1706 button_down = libinput_event_pointer_get_button(p);
1707 } else {
1708 ck_assert(button_up == 0);
1709 button_up = libinput_event_pointer_get_button(p);
1710 ck_assert_int_eq(button_down, button_up);
1711 }
1712 libinput_event_destroy(event);
1713 }
1714
1715 litest_destroy_context(li);
1716 ck_assert_int_eq(have_down, have_up);
1717 }
1718 }
1719 END_TEST
1720
TEST_COLLECTION(device)1721 TEST_COLLECTION(device)
1722 {
1723 struct range abs_range = { 0, ABS_MISC };
1724 struct range abs_mt_range = { ABS_MT_SLOT + 1, ABS_CNT };
1725
1726 litest_add(device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD|LITEST_TABLET);
1727 litest_add(device_sendevents_config_invalid, LITEST_ANY, LITEST_TABLET);
1728 litest_add(device_sendevents_config_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
1729 litest_add(device_sendevents_config_touchpad_superset, LITEST_TOUCHPAD, LITEST_TABLET);
1730 litest_add(device_sendevents_config_default, LITEST_ANY, LITEST_TABLET);
1731 litest_add(device_disable, LITEST_RELATIVE, LITEST_TABLET);
1732 litest_add(device_disable_tablet, LITEST_TABLET, LITEST_ANY);
1733 litest_add(device_disable_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
1734 litest_add(device_disable_touch, LITEST_TOUCH, LITEST_ANY);
1735 litest_add(device_disable_touch_during_touch, LITEST_TOUCH, LITEST_ANY);
1736 litest_add(device_disable_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1737 litest_add(device_disable_touch_during_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1738 litest_add(device_disable_events_pending, LITEST_RELATIVE, LITEST_TOUCHPAD|LITEST_TABLET);
1739 litest_add(device_double_disable, LITEST_ANY, LITEST_TABLET);
1740 litest_add(device_double_enable, LITEST_ANY, LITEST_TABLET);
1741 litest_add_no_device(device_reenable_syspath_changed);
1742 litest_add_no_device(device_reenable_device_removed);
1743 litest_add_for_device(device_disable_release_buttons, LITEST_MOUSE);
1744 litest_add_for_device(device_disable_release_keys, LITEST_KEYBOARD);
1745 litest_add(device_disable_release_tap, LITEST_TOUCHPAD, LITEST_ANY);
1746 litest_add(device_disable_release_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY);
1747 litest_add(device_disable_release_softbutton, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
1748 litest_add(device_disable_topsoftbutton, LITEST_TOPBUTTONPAD, LITEST_ANY);
1749 litest_add(device_ids, LITEST_ANY, LITEST_ANY);
1750 litest_add_for_device(device_context, LITEST_SYNAPTICS_CLICKPAD_X220);
1751 litest_add_for_device(device_user_data, LITEST_SYNAPTICS_CLICKPAD_X220);
1752
1753 litest_add(device_get_udev_handle, LITEST_ANY, LITEST_ANY);
1754
1755 litest_add(device_group_get, LITEST_ANY, LITEST_ANY);
1756 litest_add_no_device(device_group_ref);
1757 litest_add_no_device(device_group_leak);
1758
1759 litest_add_no_device(abs_device_no_absx);
1760 litest_add_no_device(abs_device_no_absy);
1761 litest_add_no_device(abs_mt_device_no_absx);
1762 litest_add_no_device(abs_mt_device_no_absy);
1763 litest_add_ranged_no_device(abs_device_no_range, &abs_range);
1764 litest_add_ranged_no_device(abs_mt_device_no_range, &abs_mt_range);
1765 litest_add_no_device(abs_device_missing_res);
1766 litest_add_no_device(abs_mt_device_missing_res);
1767 litest_add_no_device(ignore_joystick);
1768
1769 litest_add(device_wheel_only, LITEST_WHEEL, LITEST_RELATIVE|LITEST_ABSOLUTE|LITEST_TABLET);
1770 litest_add_no_device(device_accelerometer);
1771
1772 litest_add(device_udev_tag_wacom_tablet, LITEST_TABLET, LITEST_TOTEM);
1773
1774 litest_add_no_device(device_nonpointer_rel);
1775 litest_add_no_device(device_touchpad_rel);
1776 litest_add_no_device(device_touch_rel);
1777 litest_add_no_device(device_abs_rel);
1778
1779 litest_add_for_device(device_quirks_no_abs_mt_y, LITEST_ANKER_MOUSE_KBD);
1780 litest_add_for_device(device_quirks_cyborg_rat_mode_button, LITEST_CYBORG_RAT);
1781 litest_add_for_device(device_quirks_apple_magicmouse, LITEST_MAGICMOUSE);
1782 litest_add_for_device(device_quirks_logitech_marble_mouse, LITEST_LOGITECH_TRACKBALL);
1783 litest_add_no_device(device_quirks);
1784
1785 litest_add(device_capability_at_least_one, LITEST_ANY, LITEST_ANY);
1786 litest_add(device_capability_check_invalid, LITEST_ANY, LITEST_ANY);
1787 litest_add_no_device(device_capability_nocaps_ignored);
1788
1789 litest_add(device_has_size, LITEST_TOUCHPAD, LITEST_ANY);
1790 litest_add(device_has_size, LITEST_TABLET, LITEST_ANY);
1791 litest_add(device_has_no_size, LITEST_ANY,
1792 LITEST_TOUCHPAD|LITEST_TABLET|LITEST_TOUCH|LITEST_ABSOLUTE|LITEST_SINGLE_TOUCH|LITEST_TOTEM);
1793
1794 litest_add_for_device(device_get_output, LITEST_CALIBRATED_TOUCHSCREEN);
1795 litest_add(device_no_output, LITEST_RELATIVE, LITEST_ANY);
1796 litest_add(device_no_output, LITEST_KEYS, LITEST_ANY);
1797
1798 litest_add(device_seat_phys_name, LITEST_ANY, LITEST_ANY);
1799
1800 litest_add(device_button_down_remove, LITEST_BUTTON, LITEST_ANY);
1801 }
1802