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_TESTnull36 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_TESTnull50 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 | bit(4));
60 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
61 }
62 END_TEST
63
START_TESTnull64 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_TESTnull85 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_TESTnull112 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_TESTnull130 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_TESTnull182 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_TESTnull222 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_TESTnull254 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_TESTnull286 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_TESTnull333 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_TESTnull368 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_TESTnull391 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_TESTnull414 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_TESTnull461 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_TESTnull495 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_TESTnull529 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_TESTnull563 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_TESTnull608 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_TESTnull647 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_TESTnull691 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_TESTnull747 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_TESTnull766 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_TESTnull777 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_TESTnull788 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_TESTnull802 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_TESTnull822 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_TESTnull850 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_TESTnull880 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_TESTnull903 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_TESTnull926 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_TESTnull952 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_TESTnull995 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_TESTnull1017 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_TESTnull1045 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_TESTnull1069 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_TESTnull1097 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_TESTnull1130 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_TESTnull1140 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_TESTnull1168 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_TESTnull1184 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_TESTnull1217 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_TESTnull1257 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_TESTnull1298 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_TESTnull1334 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_TESTnull1383 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_TESTnull1415 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_TESTnull1430 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;
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_TESTnull1470 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 enable_direct = false,
1482 disable_direct = false,
1483 enable_semi_mt = false,
1484 disable_semi_mt = false;
1485 #endif
1486
1487 li = litest_create_context();
1488 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG);
1489 libinput_log_set_handler(li, debug_log_handler);
1490 dev = litest_add_device(li, LITEST_KEYBOARD_QUIRKED);
1491 device = dev->libinput_device;
1492
1493 ck_assert(libinput_device_pointer_has_button(device,
1494 BTN_LEFT));
1495 ck_assert(libinput_device_pointer_has_button(dev->libinput_device,
1496 BTN_RIGHT));
1497 ck_assert(!libinput_device_pointer_has_button(device,
1498 BTN_MIDDLE));
1499 ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1500 KEY_F1));
1501 ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1502 KEY_F2));
1503 ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
1504 KEY_F3));
1505
1506 /* Scrape the debug messages for confirmation that our quirks are
1507 * triggered, the above checks cannot work non-key codes */
1508 message = debug_messages;
1509 while (*message) {
1510 if (strstr(*message, "disabling EV_KEY KEY_F1"))
1511 disable_key_f1 = true;
1512 if (strstr(*message, "enabling EV_KEY BTN_LEFT"))
1513 enable_btn_left = true;
1514 #if HAVE_LIBEVDEV_DISABLE_PROPERTY
1515 if (strstr(*message, "enabling INPUT_PROP_BUTTONPAD"))
1516 enable_buttonpad = true;
1517 if (strstr(*message, "disabling INPUT_PROP_POINTING_STICK"))
1518 disable_pointingstick = true;
1519 if (strstr(*message, "enabling INPUT_PROP_DIRECT")) {
1520 ck_assert(!disable_direct);
1521 enable_direct = true;
1522 }
1523 if (strstr(*message, "disabling INPUT_PROP_DIRECT")) {
1524 ck_assert(enable_direct);
1525 disable_direct = true;
1526 }
1527 if (strstr(*message, "enabling INPUT_PROP_SEMI_MT")) {
1528 ck_assert(disable_semi_mt);
1529 enable_semi_mt = true;
1530 }
1531 if (strstr(*message, "disabling INPUT_PROP_SEMI_MT")) {
1532 ck_assert(!enable_semi_mt);
1533 disable_semi_mt = true;
1534 }
1535 #endif
1536 free(*message);
1537 message++;
1538 }
1539
1540 ck_assert(disable_key_f1);
1541 ck_assert(enable_btn_left);
1542 #if HAVE_LIBEVDEV_DISABLE_PROPERTY
1543 ck_assert(enable_buttonpad);
1544 ck_assert(disable_pointingstick);
1545 ck_assert(enable_direct);
1546 ck_assert(disable_direct);
1547 ck_assert(enable_semi_mt);
1548 ck_assert(disable_semi_mt);
1549 #endif
1550
1551 litest_disable_log_handler(li);
1552
1553 litest_delete_device(dev);
1554 litest_destroy_context(li);
1555 }
1556 END_TEST
1557
START_TESTnull1558 START_TEST(device_capability_at_least_one)
1559 {
1560 struct litest_device *dev = litest_current_device();
1561 struct libinput_device *device = dev->libinput_device;
1562 enum libinput_device_capability caps[] = {
1563 LIBINPUT_DEVICE_CAP_KEYBOARD,
1564 LIBINPUT_DEVICE_CAP_POINTER,
1565 LIBINPUT_DEVICE_CAP_TOUCH,
1566 LIBINPUT_DEVICE_CAP_TABLET_TOOL,
1567 LIBINPUT_DEVICE_CAP_TABLET_PAD,
1568 LIBINPUT_DEVICE_CAP_GESTURE,
1569 LIBINPUT_DEVICE_CAP_SWITCH,
1570 };
1571 int ncaps = 0;
1572
1573 ARRAY_FOR_EACH(caps, cap) {
1574 if (libinput_device_has_capability(device, *cap))
1575 ncaps++;
1576 }
1577 ck_assert_int_gt(ncaps, 0);
1578
1579 }
1580 END_TEST
1581
START_TESTnull1582 START_TEST(device_capability_check_invalid)
1583 {
1584 struct litest_device *dev = litest_current_device();
1585 struct libinput_device *device = dev->libinput_device;
1586
1587 ck_assert(!libinput_device_has_capability(device, -1));
1588 ck_assert(!libinput_device_has_capability(device, 7));
1589 ck_assert(!libinput_device_has_capability(device, 0xffff));
1590
1591 }
1592 END_TEST
1593
START_TESTnull1594 START_TEST(device_capability_nocaps_ignored)
1595 {
1596 struct libevdev_uinput *uinput;
1597 struct libinput *li;
1598 struct libinput_device *device;
1599
1600 /* SW_PEN_INSERTED isn't handled in libinput so the device is
1601 * processed but ends up without seat capabilities and is ignored.
1602 */
1603 uinput = litest_create_uinput_device("test device", NULL,
1604 EV_SW, SW_PEN_INSERTED,
1605 -1);
1606 li = litest_create_context();
1607 device = libinput_path_add_device(li,
1608 libevdev_uinput_get_devnode(uinput));
1609 litest_assert_ptr_null(device);
1610
1611 litest_destroy_context(li);
1612 libevdev_uinput_destroy(uinput);
1613 }
1614 END_TEST
1615
START_TESTnull1616 START_TEST(device_has_size)
1617 {
1618 struct litest_device *dev = litest_current_device();
1619 struct libinput_device *device = dev->libinput_device;
1620 double w, h;
1621 int rc;
1622
1623 rc = libinput_device_get_size(device, &w, &h);
1624 ck_assert_int_eq(rc, 0);
1625 /* This matches the current set of test devices but may fail if
1626 * newer ones are added */
1627 ck_assert_double_gt(w, 30);
1628 ck_assert_double_gt(h, 20);
1629 }
1630 END_TEST
1631
START_TESTnull1632 START_TEST(device_has_no_size)
1633 {
1634 struct litest_device *dev = litest_current_device();
1635 struct libinput_device *device = dev->libinput_device;
1636 double w = 45, h = 67;
1637 int rc;
1638
1639 rc = libinput_device_get_size(device, &w, &h);
1640 ck_assert_int_eq(rc, -1);
1641 ck_assert_double_eq(w, 45);
1642 ck_assert_double_eq(h, 67);
1643 }
1644 END_TEST
1645
START_TESTnull1646 START_TEST(device_get_output)
1647 {
1648 struct litest_device *dev = litest_current_device();
1649 struct libinput_device *device = dev->libinput_device;
1650 const char *output_name;
1651
1652 output_name = libinput_device_get_output_name(device);
1653 ck_assert_str_eq(output_name, "myOutput");
1654 }
1655 END_TEST
1656
START_TESTnull1657 START_TEST(device_no_output)
1658 {
1659 struct litest_device *dev = litest_current_device();
1660 struct libinput_device *device = dev->libinput_device;
1661 const char *output_name;
1662
1663 output_name = libinput_device_get_output_name(device);
1664 ck_assert(output_name == NULL);
1665 }
1666 END_TEST
1667
START_TESTnull1668 START_TEST(device_seat_phys_name)
1669 {
1670 struct litest_device *dev = litest_current_device();
1671 struct libinput_device *device = dev->libinput_device;
1672 struct libinput_seat *seat = libinput_device_get_seat(device);
1673 const char *seat_name;
1674
1675 seat_name = libinput_seat_get_physical_name(seat);
1676 ck_assert(streq(seat_name, "seat0"));
1677 }
1678 END_TEST
1679
START_TESTnull1680 START_TEST(device_button_down_remove)
1681 {
1682 struct litest_device *lidev = litest_current_device();
1683 struct litest_device *dev;
1684 struct libinput *li;
1685
1686 for (int code = 0; code < KEY_MAX; code++) {
1687 struct libinput_event *event;
1688 struct libinput_event_pointer *p;
1689 bool have_down = false,
1690 have_up = false;
1691 const char *keyname;
1692 int button_down = 0, button_up = 0;
1693
1694 keyname = libevdev_event_code_get_name(EV_KEY, code);
1695 if (!keyname ||
1696 !strneq(keyname, "BTN_", 4) ||
1697 strneq(keyname, "BTN_TOOL_", 9))
1698 continue;
1699
1700 if (!libevdev_has_event_code(lidev->evdev, EV_KEY, code))
1701 continue;
1702
1703 li = litest_create_context();
1704 dev = litest_add_device(li, lidev->which);
1705 litest_drain_events(li);
1706
1707 /* Clickpads require a touch down to trigger the button
1708 * press */
1709 if (libevdev_has_property(lidev->evdev, INPUT_PROP_BUTTONPAD)) {
1710 litest_touch_down(dev, 0, 20, 90);
1711 libinput_dispatch(li);
1712 }
1713
1714 litest_event(dev, EV_KEY, code, 1);
1715 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1716 libinput_dispatch(li);
1717
1718 litest_delete_device(dev);
1719 libinput_dispatch(li);
1720
1721 while ((event = libinput_get_event(li))) {
1722 if (libinput_event_get_type(event) !=
1723 LIBINPUT_EVENT_POINTER_BUTTON) {
1724 libinput_event_destroy(event);
1725 continue;
1726 }
1727
1728 p = libinput_event_get_pointer_event(event);
1729 if (libinput_event_pointer_get_button_state(p)) {
1730 ck_assert(button_down == 0);
1731 button_down = libinput_event_pointer_get_button(p);
1732 } else {
1733 ck_assert(button_up == 0);
1734 button_up = libinput_event_pointer_get_button(p);
1735 ck_assert_int_eq(button_down, button_up);
1736 }
1737 libinput_event_destroy(event);
1738 }
1739
1740 litest_destroy_context(li);
1741 ck_assert_int_eq(have_down, have_up);
1742 }
1743 }
1744 END_TEST
1745
TEST_COLLECTIONnull1746 TEST_COLLECTION(device)
1747 {
1748 struct range abs_range = { 0, ABS_MISC };
1749 struct range abs_mt_range = { ABS_MT_SLOT + 1, ABS_CNT };
1750
1751 litest_add(device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD|LITEST_TABLET);
1752 litest_add(device_sendevents_config_invalid, LITEST_ANY, LITEST_TABLET);
1753 litest_add(device_sendevents_config_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
1754 litest_add(device_sendevents_config_touchpad_superset, LITEST_TOUCHPAD, LITEST_TABLET);
1755 litest_add(device_sendevents_config_default, LITEST_ANY, LITEST_TABLET);
1756 litest_add(device_disable, LITEST_RELATIVE, LITEST_TABLET);
1757 litest_add(device_disable_tablet, LITEST_TABLET, LITEST_ANY);
1758 litest_add(device_disable_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
1759 litest_add(device_disable_touch, LITEST_TOUCH, LITEST_ANY);
1760 litest_add(device_disable_touch_during_touch, LITEST_TOUCH, LITEST_ANY);
1761 litest_add(device_disable_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1762 litest_add(device_disable_touch_during_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
1763 litest_add(device_disable_events_pending, LITEST_RELATIVE, LITEST_TOUCHPAD|LITEST_TABLET);
1764 litest_add(device_double_disable, LITEST_ANY, LITEST_TABLET);
1765 litest_add(device_double_enable, LITEST_ANY, LITEST_TABLET);
1766 litest_add_no_device(device_reenable_syspath_changed);
1767 litest_add_no_device(device_reenable_device_removed);
1768 litest_add_for_device(device_disable_release_buttons, LITEST_MOUSE);
1769 litest_add_for_device(device_disable_release_keys, LITEST_KEYBOARD);
1770 litest_add(device_disable_release_tap, LITEST_TOUCHPAD, LITEST_ANY);
1771 litest_add(device_disable_release_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY);
1772 litest_add(device_disable_release_softbutton, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
1773 litest_add(device_disable_topsoftbutton, LITEST_TOPBUTTONPAD, LITEST_ANY);
1774 litest_add(device_ids, LITEST_ANY, LITEST_ANY);
1775 litest_add_for_device(device_context, LITEST_SYNAPTICS_CLICKPAD_X220);
1776 litest_add_for_device(device_user_data, LITEST_SYNAPTICS_CLICKPAD_X220);
1777
1778 litest_add(device_get_udev_handle, LITEST_ANY, LITEST_ANY);
1779
1780 litest_add(device_group_get, LITEST_ANY, LITEST_ANY);
1781 litest_add_no_device(device_group_ref);
1782 litest_add_no_device(device_group_leak);
1783
1784 litest_add_no_device(abs_device_no_absx);
1785 litest_add_no_device(abs_device_no_absy);
1786 litest_add_no_device(abs_mt_device_no_absx);
1787 litest_add_no_device(abs_mt_device_no_absy);
1788 litest_add_ranged_no_device(abs_device_no_range, &abs_range);
1789 litest_add_ranged_no_device(abs_mt_device_no_range, &abs_mt_range);
1790 litest_add_no_device(abs_device_missing_res);
1791 litest_add_no_device(abs_mt_device_missing_res);
1792 litest_add_no_device(ignore_joystick);
1793
1794 litest_add(device_wheel_only, LITEST_WHEEL, LITEST_RELATIVE|LITEST_ABSOLUTE|LITEST_TABLET);
1795 litest_add_no_device(device_accelerometer);
1796
1797 litest_add(device_udev_tag_wacom_tablet, LITEST_TABLET, LITEST_TOTEM);
1798
1799 litest_add_no_device(device_nonpointer_rel);
1800 litest_add_no_device(device_touchpad_rel);
1801 litest_add_no_device(device_touch_rel);
1802 litest_add_no_device(device_abs_rel);
1803
1804 litest_add_for_device(device_quirks_no_abs_mt_y, LITEST_ANKER_MOUSE_KBD);
1805 litest_add_for_device(device_quirks_cyborg_rat_mode_button, LITEST_CYBORG_RAT);
1806 litest_add_for_device(device_quirks_apple_magicmouse, LITEST_MAGICMOUSE);
1807 litest_add_for_device(device_quirks_logitech_marble_mouse, LITEST_LOGITECH_TRACKBALL);
1808 litest_add_no_device(device_quirks);
1809
1810 litest_add(device_capability_at_least_one, LITEST_ANY, LITEST_ANY);
1811 litest_add(device_capability_check_invalid, LITEST_ANY, LITEST_ANY);
1812 litest_add_no_device(device_capability_nocaps_ignored);
1813
1814 litest_add(device_has_size, LITEST_TOUCHPAD, LITEST_ANY);
1815 litest_add(device_has_size, LITEST_TABLET, LITEST_ANY);
1816 litest_add(device_has_no_size, LITEST_ANY,
1817 LITEST_TOUCHPAD|LITEST_TABLET|LITEST_TOUCH|LITEST_ABSOLUTE|LITEST_SINGLE_TOUCH|LITEST_TOTEM);
1818
1819 litest_add_for_device(device_get_output, LITEST_CALIBRATED_TOUCHSCREEN);
1820 litest_add(device_no_output, LITEST_RELATIVE, LITEST_ANY);
1821 litest_add(device_no_output, LITEST_KEYS, LITEST_ANY);
1822
1823 litest_add(device_seat_phys_name, LITEST_ANY, LITEST_ANY);
1824
1825 litest_add(device_button_down_remove, LITEST_BUTTON, LITEST_ANY);
1826 }
1827