1 /*
2 * Copyright © 2013 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <config.h>
25
26 #include <stdio.h>
27 #include <check.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <libinput.h>
31 #include <math.h>
32 #include <unistd.h>
33
34 #include "libinput-util.h"
35 #include "litest.h"
36
37 static void
test_relative_event(struct litest_device * dev,int dx,int dy)38 test_relative_event(struct litest_device *dev, int dx, int dy)
39 {
40 struct libinput *li = dev->libinput;
41 struct libinput_event_pointer *ptrev;
42 struct libinput_event *event;
43 double ev_dx, ev_dy;
44 double expected_dir;
45 double expected_length;
46 double actual_dir;
47 double actual_length;
48
49 litest_event(dev, EV_REL, REL_X, dx);
50 litest_event(dev, EV_REL, REL_Y, dy);
51 litest_event(dev, EV_SYN, SYN_REPORT, 0);
52
53 libinput_dispatch(li);
54
55 event = libinput_get_event(li);
56 ptrev = litest_is_motion_event(event);
57
58 expected_length = sqrt(4 * dx*dx + 4 * dy*dy);
59 expected_dir = atan2(dx, dy);
60
61 ev_dx = libinput_event_pointer_get_dx(ptrev);
62 ev_dy = libinput_event_pointer_get_dy(ptrev);
63 actual_length = sqrt(ev_dx*ev_dx + ev_dy*ev_dy);
64 actual_dir = atan2(ev_dx, ev_dy);
65
66 /* Check the length of the motion vector (tolerate 1.0 indifference). */
67 litest_assert(fabs(expected_length) >= actual_length);
68
69 /* Check the direction of the motion vector (tolerate 2π/4 radians
70 * indifference). */
71 litest_assert(fabs(expected_dir - actual_dir) < M_PI_2);
72
73 libinput_event_destroy(event);
74
75 litest_drain_events(dev->libinput);
76 }
77
78 static void
disable_button_scrolling(struct litest_device * device)79 disable_button_scrolling(struct litest_device *device)
80 {
81 struct libinput_device *dev = device->libinput_device;
82 enum libinput_config_status status,
83 expected;
84
85 status = libinput_device_config_scroll_set_method(dev,
86 LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
87
88 expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
89 litest_assert_int_eq(status, expected);
90 }
91
START_TEST(pointer_motion_relative)92 START_TEST(pointer_motion_relative)
93 {
94 struct litest_device *dev = litest_current_device();
95
96 /* send a single event, the first movement
97 is always decelerated by 0.3 */
98 litest_event(dev, EV_REL, REL_X, 1);
99 litest_event(dev, EV_REL, REL_Y, 0);
100 litest_event(dev, EV_SYN, SYN_REPORT, 0);
101 libinput_dispatch(dev->libinput);
102
103 litest_drain_events(dev->libinput);
104
105 test_relative_event(dev, 1, 0);
106 test_relative_event(dev, 1, 1);
107 test_relative_event(dev, 1, -1);
108 test_relative_event(dev, 0, 1);
109
110 test_relative_event(dev, -1, 0);
111 test_relative_event(dev, -1, 1);
112 test_relative_event(dev, -1, -1);
113 test_relative_event(dev, 0, -1);
114 }
115 END_TEST
116
START_TEST(pointer_motion_relative_zero)117 START_TEST(pointer_motion_relative_zero)
118 {
119 struct litest_device *dev = litest_current_device();
120 struct libinput *li = dev->libinput;
121 int i;
122
123 /* NOTE: this test does virtually nothing. The kernel should not
124 * allow 0/0 events to be passed to userspace. If it ever happens,
125 * let's hope this test fails if we do the wrong thing.
126 */
127 litest_drain_events(li);
128
129 for (i = 0; i < 5; i++) {
130 litest_event(dev, EV_REL, REL_X, 0);
131 litest_event(dev, EV_REL, REL_Y, 0);
132 litest_event(dev, EV_SYN, SYN_REPORT, 0);
133 libinput_dispatch(li);
134 }
135 litest_assert_empty_queue(li);
136
137 /* send a single event, the first movement
138 is always decelerated by 0.3 */
139 litest_event(dev, EV_REL, REL_X, 1);
140 litest_event(dev, EV_REL, REL_Y, 0);
141 litest_event(dev, EV_SYN, SYN_REPORT, 0);
142 libinput_dispatch(li);
143
144 libinput_event_destroy(libinput_get_event(li));
145 litest_assert_empty_queue(li);
146
147 for (i = 0; i < 5; i++) {
148 litest_event(dev, EV_REL, REL_X, 0);
149 litest_event(dev, EV_REL, REL_Y, 0);
150 litest_event(dev, EV_SYN, SYN_REPORT, 0);
151 libinput_dispatch(dev->libinput);
152 }
153 litest_assert_empty_queue(li);
154
155 }
156 END_TEST
157
START_TEST(pointer_motion_relative_min_decel)158 START_TEST(pointer_motion_relative_min_decel)
159 {
160 struct litest_device *dev = litest_current_device();
161 struct libinput *li = dev->libinput;
162 struct libinput_event_pointer *ptrev;
163 struct libinput_event *event;
164 double evx, evy;
165 int dx, dy;
166 int cardinal = _i; /* ranged test */
167 double len;
168
169 int deltas[8][2] = {
170 /* N, NE, E, ... */
171 { 0, 1 },
172 { 1, 1 },
173 { 1, 0 },
174 { 1, -1 },
175 { 0, -1 },
176 { -1, -1 },
177 { -1, 0 },
178 { -1, 1 },
179 };
180
181 litest_drain_events(dev->libinput);
182
183 dx = deltas[cardinal][0];
184 dy = deltas[cardinal][1];
185
186 litest_event(dev, EV_REL, REL_X, dx);
187 litest_event(dev, EV_REL, REL_Y, dy);
188 litest_event(dev, EV_SYN, SYN_REPORT, 0);
189 libinput_dispatch(li);
190
191 event = libinput_get_event(li);
192 ptrev = litest_is_motion_event(event);
193 evx = libinput_event_pointer_get_dx(ptrev);
194 evy = libinput_event_pointer_get_dy(ptrev);
195
196 ck_assert((evx == 0.0) == (dx == 0));
197 ck_assert((evy == 0.0) == (dy == 0));
198
199 len = hypot(evx, evy);
200 ck_assert(fabs(len) >= 0.3);
201
202 libinput_event_destroy(event);
203 }
204 END_TEST
205
206 static void
test_absolute_event(struct litest_device * dev,double x,double y)207 test_absolute_event(struct litest_device *dev, double x, double y)
208 {
209 struct libinput *li = dev->libinput;
210 struct libinput_event *event;
211 struct libinput_event_pointer *ptrev;
212 double ex, ey;
213 enum libinput_event_type type = LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE;
214
215 litest_touch_down(dev, 0, x, y);
216 libinput_dispatch(li);
217
218 event = libinput_get_event(li);
219 litest_assert_notnull(event);
220 litest_assert_int_eq(libinput_event_get_type(event), type);
221
222 ptrev = libinput_event_get_pointer_event(event);
223 litest_assert(ptrev != NULL);
224
225 ex = libinput_event_pointer_get_absolute_x_transformed(ptrev, 100);
226 ey = libinput_event_pointer_get_absolute_y_transformed(ptrev, 100);
227 litest_assert_int_eq((int)(ex + 0.5), (int)x);
228 litest_assert_int_eq((int)(ey + 0.5), (int)y);
229
230 libinput_event_destroy(event);
231 }
232
START_TEST(pointer_motion_absolute)233 START_TEST(pointer_motion_absolute)
234 {
235 struct litest_device *dev = litest_current_device();
236
237 litest_drain_events(dev->libinput);
238
239 test_absolute_event(dev, 0, 100);
240 test_absolute_event(dev, 100, 0);
241 test_absolute_event(dev, 50, 50);
242 }
243 END_TEST
244
START_TEST(pointer_absolute_initial_state)245 START_TEST(pointer_absolute_initial_state)
246 {
247 struct litest_device *dev = litest_current_device();
248 struct libinput *libinput1, *libinput2;
249 struct libinput_event *ev1, *ev2;
250 struct libinput_event_pointer *p1, *p2;
251 int axis = _i; /* looped test */
252
253 libinput1 = dev->libinput;
254 litest_touch_down(dev, 0, 40, 60);
255 litest_touch_up(dev, 0);
256
257 /* device is now on some x/y value */
258 litest_drain_events(libinput1);
259
260 libinput2 = litest_create_context();
261 libinput_path_add_device(libinput2,
262 libevdev_uinput_get_devnode(dev->uinput));
263 litest_drain_events(libinput2);
264
265 if (axis == ABS_X)
266 litest_touch_down(dev, 0, 40, 70);
267 else
268 litest_touch_down(dev, 0, 70, 60);
269 litest_touch_up(dev, 0);
270
271 litest_wait_for_event(libinput1);
272 litest_wait_for_event(libinput2);
273
274 while (libinput_next_event_type(libinput1)) {
275 ev1 = libinput_get_event(libinput1);
276 ev2 = libinput_get_event(libinput2);
277
278 ck_assert_int_eq(libinput_event_get_type(ev1),
279 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
280 ck_assert_int_eq(libinput_event_get_type(ev1),
281 libinput_event_get_type(ev2));
282
283 p1 = libinput_event_get_pointer_event(ev1);
284 p2 = libinput_event_get_pointer_event(ev2);
285
286 ck_assert_int_eq(libinput_event_pointer_get_absolute_x(p1),
287 libinput_event_pointer_get_absolute_x(p2));
288 ck_assert_int_eq(libinput_event_pointer_get_absolute_y(p1),
289 libinput_event_pointer_get_absolute_y(p2));
290
291 libinput_event_destroy(ev1);
292 libinput_event_destroy(ev2);
293 }
294
295 libinput_unref(libinput2);
296 }
297 END_TEST
298
299 static void
test_unaccel_event(struct litest_device * dev,int dx,int dy)300 test_unaccel_event(struct litest_device *dev, int dx, int dy)
301 {
302 struct libinput *li = dev->libinput;
303 struct libinput_event *event;
304 struct libinput_event_pointer *ptrev;
305 double ev_dx, ev_dy;
306
307 litest_event(dev, EV_REL, REL_X, dx);
308 litest_event(dev, EV_REL, REL_Y, dy);
309 litest_event(dev, EV_SYN, SYN_REPORT, 0);
310
311 libinput_dispatch(li);
312
313 event = libinput_get_event(li);
314 ptrev = litest_is_motion_event(event);
315
316 ev_dx = libinput_event_pointer_get_dx_unaccelerated(ptrev);
317 ev_dy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
318
319 litest_assert_int_eq(dx, ev_dx);
320 litest_assert_int_eq(dy, ev_dy);
321
322 libinput_event_destroy(event);
323
324 litest_drain_events(dev->libinput);
325 }
326
START_TEST(pointer_motion_unaccel)327 START_TEST(pointer_motion_unaccel)
328 {
329 struct litest_device *dev = litest_current_device();
330
331 litest_drain_events(dev->libinput);
332
333 test_unaccel_event(dev, 10, 0);
334 test_unaccel_event(dev, 10, 10);
335 test_unaccel_event(dev, 10, -10);
336 test_unaccel_event(dev, 0, 10);
337
338 test_unaccel_event(dev, -10, 0);
339 test_unaccel_event(dev, -10, 10);
340 test_unaccel_event(dev, -10, -10);
341 test_unaccel_event(dev, 0, -10);
342 }
343 END_TEST
344
345 static void
test_button_event(struct litest_device * dev,unsigned int button,int state)346 test_button_event(struct litest_device *dev, unsigned int button, int state)
347 {
348 struct libinput *li = dev->libinput;
349
350 litest_button_click_debounced(dev, li, button, state);
351 litest_event(dev, EV_SYN, SYN_REPORT, 0);
352
353 litest_assert_button_event(li, button,
354 state ? LIBINPUT_BUTTON_STATE_PRESSED :
355 LIBINPUT_BUTTON_STATE_RELEASED);
356 }
357
START_TEST(pointer_button)358 START_TEST(pointer_button)
359 {
360 struct litest_device *dev = litest_current_device();
361
362 disable_button_scrolling(dev);
363
364 litest_drain_events(dev->libinput);
365
366 test_button_event(dev, BTN_LEFT, 1);
367 test_button_event(dev, BTN_LEFT, 0);
368
369 /* press it twice for good measure */
370 test_button_event(dev, BTN_LEFT, 1);
371 test_button_event(dev, BTN_LEFT, 0);
372
373 if (libinput_device_pointer_has_button(dev->libinput_device,
374 BTN_RIGHT)) {
375 test_button_event(dev, BTN_RIGHT, 1);
376 test_button_event(dev, BTN_RIGHT, 0);
377 }
378
379 /* Skip middle button test on trackpoints (used for scrolling) */
380 if (libinput_device_pointer_has_button(dev->libinput_device,
381 BTN_MIDDLE)) {
382 test_button_event(dev, BTN_MIDDLE, 1);
383 test_button_event(dev, BTN_MIDDLE, 0);
384 }
385 }
386 END_TEST
387
START_TEST(pointer_button_auto_release)388 START_TEST(pointer_button_auto_release)
389 {
390 struct libinput *libinput;
391 struct litest_device *dev;
392 struct libinput_event *event;
393 enum libinput_event_type type;
394 struct libinput_event_pointer *pevent;
395 struct {
396 int code;
397 int released;
398 } buttons[] = {
399 { .code = BTN_LEFT, },
400 { .code = BTN_MIDDLE, },
401 { .code = BTN_EXTRA, },
402 { .code = BTN_SIDE, },
403 { .code = BTN_BACK, },
404 { .code = BTN_FORWARD, },
405 { .code = BTN_4, },
406 };
407 int events[2 * (ARRAY_LENGTH(buttons) + 1)];
408 unsigned i;
409 int button;
410 int valid_code;
411
412 /* Enable all tested buttons on the device */
413 for (i = 0; i < 2 * ARRAY_LENGTH(buttons);) {
414 button = buttons[i / 2].code;
415 events[i++] = EV_KEY;
416 events[i++] = button;
417 }
418 events[i++] = -1;
419 events[i++] = -1;
420
421 libinput = litest_create_context();
422 dev = litest_add_device_with_overrides(libinput,
423 LITEST_MOUSE,
424 "Generic mouse",
425 NULL, NULL, events);
426
427 litest_drain_events(libinput);
428
429 /* Send pressed events, without releasing */
430 for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
431 test_button_event(dev, buttons[i].code, 1);
432 }
433
434 litest_drain_events(libinput);
435
436 /* "Disconnect" device */
437 litest_delete_device(dev);
438
439 /* Mark all released buttons until device is removed */
440 while (1) {
441 event = libinput_get_event(libinput);
442 ck_assert_notnull(event);
443 type = libinput_event_get_type(event);
444
445 if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
446 libinput_event_destroy(event);
447 break;
448 }
449
450 ck_assert_int_eq(type, LIBINPUT_EVENT_POINTER_BUTTON);
451 pevent = libinput_event_get_pointer_event(event);
452 ck_assert_int_eq(libinput_event_pointer_get_button_state(pevent),
453 LIBINPUT_BUTTON_STATE_RELEASED);
454 button = libinput_event_pointer_get_button(pevent);
455
456 valid_code = 0;
457 for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
458 if (buttons[i].code == button) {
459 ck_assert_int_eq(buttons[i].released, 0);
460 buttons[i].released = 1;
461 valid_code = 1;
462 }
463 }
464 ck_assert_int_eq(valid_code, 1);
465 libinput_event_destroy(event);
466 }
467
468 /* Check that all pressed buttons has been released. */
469 for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
470 ck_assert_int_eq(buttons[i].released, 1);
471 }
472
473 libinput_unref(libinput);
474 }
475 END_TEST
476
START_TEST(pointer_button_has_no_button)477 START_TEST(pointer_button_has_no_button)
478 {
479 struct litest_device *dev = litest_current_device();
480 struct libinput_device *device = dev->libinput_device;
481 unsigned int code;
482
483 ck_assert(!libinput_device_has_capability(device,
484 LIBINPUT_DEVICE_CAP_POINTER));
485
486 for (code = BTN_LEFT; code < KEY_OK; code++)
487 ck_assert_int_eq(-1,
488 libinput_device_pointer_has_button(device, code));
489 }
490 END_TEST
491
START_TEST(pointer_recover_from_lost_button_count)492 START_TEST(pointer_recover_from_lost_button_count)
493 {
494 struct litest_device *dev = litest_current_device();
495 struct libinput *li = dev->libinput;
496 struct libevdev *evdev = dev->evdev;
497
498 disable_button_scrolling(dev);
499
500 litest_drain_events(dev->libinput);
501
502 litest_button_click_debounced(dev, li, BTN_LEFT, 1);
503
504 litest_assert_button_event(li,
505 BTN_LEFT,
506 LIBINPUT_BUTTON_STATE_PRESSED);
507
508 /* Grab for the release to make libinput lose count */
509 libevdev_grab(evdev, LIBEVDEV_GRAB);
510 litest_button_click_debounced(dev, li, BTN_LEFT, 0);
511 libevdev_grab(evdev, LIBEVDEV_UNGRAB);
512
513 litest_assert_empty_queue(li);
514
515 litest_button_click_debounced(dev, li, BTN_LEFT, 1);
516 litest_assert_empty_queue(li);
517
518 litest_button_click_debounced(dev, li, BTN_LEFT, 0);
519 litest_assert_button_event(li,
520 BTN_LEFT,
521 LIBINPUT_BUTTON_STATE_RELEASED);
522 litest_assert_empty_queue(li);
523 }
524 END_TEST
525
526 static inline double
wheel_click_count(struct litest_device * dev,int which)527 wheel_click_count(struct litest_device *dev, int which)
528 {
529 struct udev_device *d;
530 const char *prop = NULL;
531 int count;
532 double angle = 0.0;
533
534 d = libinput_device_get_udev_device(dev->libinput_device);
535 litest_assert_ptr_notnull(d);
536
537 if (which == REL_HWHEEL)
538 prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL");
539 if (!prop)
540 prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_COUNT");
541 if (!prop)
542 goto out;
543
544 count = parse_mouse_wheel_click_count_property(prop);
545 litest_assert_int_ne(count, 0);
546 angle = 360.0/count;
547
548 out:
549 udev_device_unref(d);
550 return angle;
551 }
552
553 static inline double
wheel_click_angle(struct litest_device * dev,int which)554 wheel_click_angle(struct litest_device *dev, int which)
555 {
556 struct udev_device *d;
557 const char *prop = NULL;
558 const int default_angle = 15;
559 double angle;
560
561 angle = wheel_click_count(dev, which);
562 if (angle != 0.0)
563 return angle;
564
565 angle = default_angle;
566 d = libinput_device_get_udev_device(dev->libinput_device);
567 litest_assert_ptr_notnull(d);
568
569 if (which == REL_HWHEEL)
570 prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL");
571 if (!prop)
572 prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_ANGLE");
573 if (!prop)
574 goto out;
575
576 angle = parse_mouse_wheel_click_angle_property(prop);
577 if (angle == 0.0)
578 angle = default_angle;
579
580 out:
581 udev_device_unref(d);
582 return angle;
583 }
584
585 static enum libinput_pointer_axis_source
wheel_source(struct litest_device * dev,int which)586 wheel_source(struct litest_device *dev, int which)
587 {
588 struct udev_device *d;
589 bool is_tilt = false;
590
591 d = libinput_device_get_udev_device(dev->libinput_device);
592 litest_assert_ptr_notnull(d);
593
594 switch(which) {
595 case REL_WHEEL:
596 is_tilt = !!udev_device_get_property_value(d, "MOUSE_WHEEL_TILT_VERTICAL");
597 break;
598 case REL_HWHEEL:
599 is_tilt = !!udev_device_get_property_value(d, "MOUSE_WHEEL_TILT_HORIZONTAL");
600 break;
601 default:
602 litest_abort_msg("Invalid source axis %d\n", which);
603 break;
604 }
605
606 udev_device_unref(d);
607 return is_tilt ?
608 LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT :
609 LIBINPUT_POINTER_AXIS_SOURCE_WHEEL;
610 }
611
612 static void
test_wheel_event(struct litest_device * dev,int which,int amount)613 test_wheel_event(struct litest_device *dev, int which, int amount)
614 {
615 struct libinput *li = dev->libinput;
616 struct libinput_event *event;
617 struct libinput_event_pointer *ptrev;
618 enum libinput_pointer_axis axis;
619 enum libinput_pointer_axis_source source;
620
621 double scroll_step, expected, discrete;
622
623 scroll_step = wheel_click_angle(dev, which);
624 source = wheel_source(dev, which);
625 expected = amount * scroll_step;
626 discrete = amount;
627
628 if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device)) {
629 expected *= -1;
630 discrete *= -1;
631 }
632
633 /* mouse scroll wheels are 'upside down' */
634 if (which == REL_WHEEL)
635 amount *= -1;
636 litest_event(dev, EV_REL, which, amount);
637 litest_event(dev, EV_SYN, SYN_REPORT, 0);
638
639 libinput_dispatch(li);
640
641 axis = (which == REL_WHEEL) ?
642 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL :
643 LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
644
645 event = libinput_get_event(li);
646 ptrev = litest_is_axis_event(event, axis, source);
647
648 litest_assert_double_eq(
649 libinput_event_pointer_get_axis_value(ptrev, axis),
650 expected);
651 litest_assert_double_eq(
652 libinput_event_pointer_get_axis_value_discrete(ptrev, axis),
653 discrete);
654 libinput_event_destroy(event);
655 }
656
START_TEST(pointer_scroll_wheel)657 START_TEST(pointer_scroll_wheel)
658 {
659 struct litest_device *dev = litest_current_device();
660
661 litest_drain_events(dev->libinput);
662
663 /* make sure we hit at least one of the below two conditions */
664 ck_assert(libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL) ||
665 libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL));
666
667 if (libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL)) {
668 test_wheel_event(dev, REL_WHEEL, -1);
669 test_wheel_event(dev, REL_WHEEL, 1);
670
671 test_wheel_event(dev, REL_WHEEL, -5);
672 test_wheel_event(dev, REL_WHEEL, 6);
673 }
674
675 if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
676 test_wheel_event(dev, REL_HWHEEL, -1);
677 test_wheel_event(dev, REL_HWHEEL, 1);
678
679 test_wheel_event(dev, REL_HWHEEL, -5);
680 test_wheel_event(dev, REL_HWHEEL, 6);
681 }
682 }
683 END_TEST
684
START_TEST(pointer_scroll_natural_defaults)685 START_TEST(pointer_scroll_natural_defaults)
686 {
687 struct litest_device *dev = litest_current_device();
688
689 ck_assert_int_ge(libinput_device_config_scroll_has_natural_scroll(dev->libinput_device), 1);
690 ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 0);
691 ck_assert_int_eq(libinput_device_config_scroll_get_default_natural_scroll_enabled(dev->libinput_device), 0);
692 }
693 END_TEST
694
START_TEST(pointer_scroll_natural_defaults_noscroll)695 START_TEST(pointer_scroll_natural_defaults_noscroll)
696 {
697 struct litest_device *dev = litest_current_device();
698
699 if (libinput_device_config_scroll_has_natural_scroll(dev->libinput_device))
700 return;
701
702 ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 0);
703 ck_assert_int_eq(libinput_device_config_scroll_get_default_natural_scroll_enabled(dev->libinput_device), 0);
704 }
705 END_TEST
706
START_TEST(pointer_scroll_natural_enable_config)707 START_TEST(pointer_scroll_natural_enable_config)
708 {
709 struct litest_device *dev = litest_current_device();
710 enum libinput_config_status status;
711
712 status = libinput_device_config_scroll_set_natural_scroll_enabled(dev->libinput_device, 1);
713 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
714 ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 1);
715
716 status = libinput_device_config_scroll_set_natural_scroll_enabled(dev->libinput_device, 0);
717 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
718 ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 0);
719 }
720 END_TEST
721
START_TEST(pointer_scroll_natural_wheel)722 START_TEST(pointer_scroll_natural_wheel)
723 {
724 struct litest_device *dev = litest_current_device();
725 struct libinput_device *device = dev->libinput_device;
726
727 litest_drain_events(dev->libinput);
728
729 libinput_device_config_scroll_set_natural_scroll_enabled(device, 1);
730
731 /* make sure we hit at least one of the below two conditions */
732 ck_assert(libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL) ||
733 libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL));
734
735 if (libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL)) {
736 test_wheel_event(dev, REL_WHEEL, -1);
737 test_wheel_event(dev, REL_WHEEL, 1);
738
739 test_wheel_event(dev, REL_WHEEL, -5);
740 test_wheel_event(dev, REL_WHEEL, 6);
741 }
742
743 if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
744 test_wheel_event(dev, REL_HWHEEL, -1);
745 test_wheel_event(dev, REL_HWHEEL, 1);
746
747 test_wheel_event(dev, REL_HWHEEL, -5);
748 test_wheel_event(dev, REL_HWHEEL, 6);
749 }
750 }
751 END_TEST
752
START_TEST(pointer_scroll_has_axis_invalid)753 START_TEST(pointer_scroll_has_axis_invalid)
754 {
755 struct litest_device *dev = litest_current_device();
756 struct libinput *li = dev->libinput;
757 struct libinput_event *event;
758 struct libinput_event_pointer *pev;
759
760 litest_drain_events(dev->libinput);
761
762 if (!libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL))
763 return;
764
765 litest_event(dev, EV_REL, REL_WHEEL, 1);
766 litest_event(dev, EV_SYN, SYN_REPORT, 0);
767
768 libinput_dispatch(li);
769 event = libinput_get_event(li);
770 pev = litest_is_axis_event(event,
771 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
772 0);
773
774 ck_assert_int_eq(libinput_event_pointer_has_axis(pev, -1), 0);
775 ck_assert_int_eq(libinput_event_pointer_has_axis(pev, 2), 0);
776 ck_assert_int_eq(libinput_event_pointer_has_axis(pev, 3), 0);
777 ck_assert_int_eq(libinput_event_pointer_has_axis(pev, 0xffff), 0);
778 libinput_event_destroy(event);
779 }
780 END_TEST
781
START_TEST(pointer_seat_button_count)782 START_TEST(pointer_seat_button_count)
783 {
784 const int num_devices = 4;
785 struct litest_device *devices[num_devices];
786 struct libinput *libinput;
787 struct libinput_event *ev;
788 struct libinput_event_pointer *tev;
789 int i;
790 int seat_button_count = 0;
791 int expected_seat_button_count = 0;
792 char device_name[255];
793
794 libinput = litest_create_context();
795 for (i = 0; i < num_devices; ++i) {
796 sprintf(device_name, "litest Generic mouse (%d)", i);
797 devices[i] = litest_add_device_with_overrides(libinput,
798 LITEST_MOUSE,
799 device_name,
800 NULL, NULL, NULL);
801 }
802
803 for (i = 0; i < num_devices; ++i)
804 litest_button_click_debounced(devices[i],
805 libinput,
806 BTN_LEFT,
807 true);
808
809 libinput_dispatch(libinput);
810 while ((ev = libinput_get_event(libinput))) {
811 if (libinput_event_get_type(ev) !=
812 LIBINPUT_EVENT_POINTER_BUTTON) {
813 libinput_event_destroy(ev);
814 libinput_dispatch(libinput);
815 continue;
816 }
817
818 tev = libinput_event_get_pointer_event(ev);
819 ck_assert_notnull(tev);
820 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
821 BTN_LEFT);
822 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
823 LIBINPUT_BUTTON_STATE_PRESSED);
824
825 ++expected_seat_button_count;
826 seat_button_count =
827 libinput_event_pointer_get_seat_button_count(tev);
828 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
829
830 libinput_event_destroy(ev);
831 libinput_dispatch(libinput);
832 }
833
834 ck_assert_int_eq(seat_button_count, num_devices);
835
836 for (i = 0; i < num_devices; ++i)
837 litest_button_click_debounced(devices[i],
838 libinput,
839 BTN_LEFT,
840 false);
841
842 libinput_dispatch(libinput);
843 while ((ev = libinput_get_event(libinput))) {
844 if (libinput_event_get_type(ev) !=
845 LIBINPUT_EVENT_POINTER_BUTTON) {
846 libinput_event_destroy(ev);
847 libinput_dispatch(libinput);
848 continue;
849 }
850
851 tev = libinput_event_get_pointer_event(ev);
852 ck_assert_notnull(tev);
853 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
854 BTN_LEFT);
855 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
856 LIBINPUT_BUTTON_STATE_RELEASED);
857
858 --expected_seat_button_count;
859 seat_button_count =
860 libinput_event_pointer_get_seat_button_count(tev);
861 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
862
863 libinput_event_destroy(ev);
864 libinput_dispatch(libinput);
865 }
866
867 ck_assert_int_eq(seat_button_count, 0);
868
869 for (i = 0; i < num_devices; ++i)
870 litest_delete_device(devices[i]);
871 libinput_unref(libinput);
872 }
873 END_TEST
874
START_TEST(pointer_no_calibration)875 START_TEST(pointer_no_calibration)
876 {
877 struct litest_device *dev = litest_current_device();
878 struct libinput_device *d = dev->libinput_device;
879 enum libinput_config_status status;
880 int rc;
881 float calibration[6] = {0};
882
883 rc = libinput_device_config_calibration_has_matrix(d);
884 ck_assert_int_eq(rc, 0);
885 rc = libinput_device_config_calibration_get_matrix(d, calibration);
886 ck_assert_int_eq(rc, 0);
887 rc = libinput_device_config_calibration_get_default_matrix(d,
888 calibration);
889 ck_assert_int_eq(rc, 0);
890
891 status = libinput_device_config_calibration_set_matrix(d,
892 calibration);
893 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
894 }
895 END_TEST
896
START_TEST(pointer_left_handed_defaults)897 START_TEST(pointer_left_handed_defaults)
898 {
899 struct litest_device *dev = litest_current_device();
900 struct libinput_device *d = dev->libinput_device;
901 int rc;
902
903 if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_APPLE &&
904 libevdev_get_id_product(dev->evdev) == PRODUCT_ID_APPLE_APPLETOUCH)
905 return;
906
907 rc = libinput_device_config_left_handed_is_available(d);
908 ck_assert_int_ne(rc, 0);
909
910 rc = libinput_device_config_left_handed_get(d);
911 ck_assert_int_eq(rc, 0);
912
913 rc = libinput_device_config_left_handed_get_default(d);
914 ck_assert_int_eq(rc, 0);
915 }
916 END_TEST
917
START_TEST(pointer_left_handed)918 START_TEST(pointer_left_handed)
919 {
920 struct litest_device *dev = litest_current_device();
921 struct libinput_device *d = dev->libinput_device;
922 struct libinput *li = dev->libinput;
923 enum libinput_config_status status;
924
925 status = libinput_device_config_left_handed_set(d, 1);
926 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
927
928 litest_drain_events(li);
929 litest_button_click_debounced(dev, li, BTN_LEFT, 1);
930 litest_button_click_debounced(dev, li, BTN_LEFT, 0);
931
932 litest_assert_button_event(li,
933 BTN_RIGHT,
934 LIBINPUT_BUTTON_STATE_PRESSED);
935 litest_assert_button_event(li,
936 BTN_RIGHT,
937 LIBINPUT_BUTTON_STATE_RELEASED);
938
939 litest_button_click_debounced(dev, li, BTN_RIGHT, 1);
940 litest_button_click_debounced(dev, li, BTN_RIGHT, 0);
941 litest_assert_button_event(li,
942 BTN_LEFT,
943 LIBINPUT_BUTTON_STATE_PRESSED);
944 litest_assert_button_event(li,
945 BTN_LEFT,
946 LIBINPUT_BUTTON_STATE_RELEASED);
947
948 if (libinput_device_pointer_has_button(d, BTN_MIDDLE)) {
949 litest_button_click_debounced(dev, li, BTN_MIDDLE, 1);
950 litest_button_click_debounced(dev, li, BTN_MIDDLE, 0);
951 litest_assert_button_event(li,
952 BTN_MIDDLE,
953 LIBINPUT_BUTTON_STATE_PRESSED);
954 litest_assert_button_event(li,
955 BTN_MIDDLE,
956 LIBINPUT_BUTTON_STATE_RELEASED);
957 }
958 }
959 END_TEST
960
START_TEST(pointer_left_handed_during_click)961 START_TEST(pointer_left_handed_during_click)
962 {
963 struct litest_device *dev = litest_current_device();
964 struct libinput_device *d = dev->libinput_device;
965 struct libinput *li = dev->libinput;
966 enum libinput_config_status status;
967
968 litest_drain_events(li);
969 litest_button_click_debounced(dev, li, BTN_LEFT, 1);
970 libinput_dispatch(li);
971
972 /* Change while button is down, expect correct release event */
973 status = libinput_device_config_left_handed_set(d, 1);
974 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
975
976 litest_button_click_debounced(dev, li, BTN_LEFT, 0);
977
978 litest_assert_button_event(li,
979 BTN_LEFT,
980 LIBINPUT_BUTTON_STATE_PRESSED);
981 litest_assert_button_event(li,
982 BTN_LEFT,
983 LIBINPUT_BUTTON_STATE_RELEASED);
984 }
985 END_TEST
986
START_TEST(pointer_left_handed_during_click_multiple_buttons)987 START_TEST(pointer_left_handed_during_click_multiple_buttons)
988 {
989 struct litest_device *dev = litest_current_device();
990 struct libinput_device *d = dev->libinput_device;
991 struct libinput *li = dev->libinput;
992 enum libinput_config_status status;
993
994 if (!libinput_device_pointer_has_button(d, BTN_MIDDLE))
995 return;
996
997 litest_disable_middleemu(dev);
998
999 litest_drain_events(li);
1000 litest_button_click_debounced(dev, li, BTN_LEFT, 1);
1001 libinput_dispatch(li);
1002
1003 status = libinput_device_config_left_handed_set(d, 1);
1004 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1005
1006 /* No left-handed until all buttons were down */
1007 litest_button_click_debounced(dev, li, BTN_RIGHT, 1);
1008 litest_button_click_debounced(dev, li, BTN_RIGHT, 0);
1009 litest_button_click_debounced(dev, li, BTN_LEFT, 0);
1010
1011 litest_assert_button_event(li,
1012 BTN_LEFT,
1013 LIBINPUT_BUTTON_STATE_PRESSED);
1014 litest_assert_button_event(li,
1015 BTN_RIGHT,
1016 LIBINPUT_BUTTON_STATE_PRESSED);
1017 litest_assert_button_event(li,
1018 BTN_RIGHT,
1019 LIBINPUT_BUTTON_STATE_RELEASED);
1020 litest_assert_button_event(li,
1021 BTN_LEFT,
1022 LIBINPUT_BUTTON_STATE_RELEASED);
1023 }
1024 END_TEST
1025
START_TEST(pointer_scroll_button)1026 START_TEST(pointer_scroll_button)
1027 {
1028 struct litest_device *dev = litest_current_device();
1029 struct libinput *li = dev->libinput;
1030
1031 /* Make left button switch to scrolling mode */
1032 libinput_device_config_scroll_set_method(dev->libinput_device,
1033 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
1034 libinput_device_config_scroll_set_button(dev->libinput_device,
1035 BTN_LEFT);
1036
1037 litest_drain_events(li);
1038
1039 litest_button_scroll(dev, BTN_LEFT, 1, 6);
1040 litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
1041 litest_button_scroll(dev, BTN_LEFT, 1, -7);
1042 litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -7);
1043 litest_button_scroll(dev, BTN_LEFT, 8, 1);
1044 litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 8);
1045 litest_button_scroll(dev, BTN_LEFT, -9, 1);
1046 litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
1047
1048 /* scroll smaller than the threshold should not generate axis events */
1049 litest_button_scroll(dev, BTN_LEFT, 1, 1);
1050
1051 litest_button_scroll(dev, BTN_LEFT, 0, 0);
1052 litest_assert_button_event(li, BTN_LEFT,
1053 LIBINPUT_BUTTON_STATE_PRESSED);
1054 litest_assert_button_event(li,
1055 BTN_LEFT,
1056 LIBINPUT_BUTTON_STATE_RELEASED);
1057 litest_assert_empty_queue(li);
1058
1059 /* Restore default scroll behavior */
1060 libinput_device_config_scroll_set_method(dev->libinput_device,
1061 libinput_device_config_scroll_get_default_method(
1062 dev->libinput_device));
1063 libinput_device_config_scroll_set_button(dev->libinput_device,
1064 libinput_device_config_scroll_get_default_button(
1065 dev->libinput_device));
1066 }
1067 END_TEST
1068
START_TEST(pointer_scroll_button_noscroll)1069 START_TEST(pointer_scroll_button_noscroll)
1070 {
1071 struct litest_device *dev = litest_current_device();
1072 struct libinput_device *device = dev->libinput_device;
1073 uint32_t methods, button;
1074 enum libinput_config_status status;
1075
1076 methods = libinput_device_config_scroll_get_method(device);
1077 ck_assert_int_eq((methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN), 0);
1078 button = libinput_device_config_scroll_get_button(device);
1079 ck_assert_int_eq(button, 0);
1080 button = libinput_device_config_scroll_get_default_button(device);
1081 ck_assert_int_eq(button, 0);
1082
1083 status = libinput_device_config_scroll_set_method(device,
1084 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
1085 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
1086 status = libinput_device_config_scroll_set_button(device, BTN_LEFT);
1087 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
1088 }
1089 END_TEST
1090
START_TEST(pointer_scroll_button_no_event_before_timeout)1091 START_TEST(pointer_scroll_button_no_event_before_timeout)
1092 {
1093 struct litest_device *device = litest_current_device();
1094 struct libinput *li = device->libinput;
1095 int i;
1096
1097 if (!libinput_device_pointer_has_button(device->libinput_device,
1098 BTN_MIDDLE))
1099 return;
1100
1101 litest_disable_middleemu(device);
1102 disable_button_scrolling(device);
1103
1104 libinput_device_config_scroll_set_method(device->libinput_device,
1105 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
1106 libinput_device_config_scroll_set_button(device->libinput_device,
1107 BTN_LEFT);
1108 litest_drain_events(li);
1109
1110 litest_button_click_debounced(device, li, BTN_LEFT, true);
1111 litest_assert_empty_queue(li);
1112
1113 for (i = 0; i < 10; i++) {
1114 litest_event(device, EV_REL, REL_Y, 1);
1115 litest_event(device, EV_SYN, SYN_REPORT, 0);
1116 }
1117 litest_assert_empty_queue(li);
1118
1119 litest_timeout_buttonscroll();
1120 libinput_dispatch(li);
1121 litest_button_click_debounced(device, li, BTN_LEFT, false);
1122
1123 litest_assert_button_event(li, BTN_LEFT,
1124 LIBINPUT_BUTTON_STATE_PRESSED);
1125 litest_assert_button_event(li,
1126 BTN_LEFT,
1127 LIBINPUT_BUTTON_STATE_RELEASED);
1128 litest_assert_empty_queue(li);
1129 }
1130 END_TEST
1131
START_TEST(pointer_scroll_button_middle_emulation)1132 START_TEST(pointer_scroll_button_middle_emulation)
1133 {
1134 struct litest_device *dev = litest_current_device();
1135 struct libinput_device *device = dev->libinput_device;
1136 struct libinput *li = dev->libinput;
1137 enum libinput_config_status status;
1138 int i;
1139
1140 status = libinput_device_config_middle_emulation_set_enabled(device,
1141 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1142
1143 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1144 return;
1145
1146 status = libinput_device_config_scroll_set_method(device,
1147 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
1148 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1149 status = libinput_device_config_scroll_set_button(device, BTN_MIDDLE);
1150 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1151
1152 litest_drain_events(li);
1153
1154 litest_button_click_debounced(dev, li, BTN_LEFT, 1);
1155 litest_button_click_debounced(dev, li, BTN_RIGHT, 1);
1156 libinput_dispatch(li);
1157 litest_timeout_buttonscroll();
1158 libinput_dispatch(li);
1159
1160 for (i = 0; i < 10; i++) {
1161 litest_event(dev, EV_REL, REL_Y, -1);
1162 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1163 }
1164
1165 libinput_dispatch(li);
1166
1167 litest_button_click_debounced(dev, li, BTN_LEFT, 0);
1168 litest_button_click_debounced(dev, li, BTN_RIGHT, 0);
1169 libinput_dispatch(li);
1170
1171 litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -1);
1172 litest_assert_empty_queue(li);
1173
1174 /* Restore default scroll behavior */
1175 libinput_device_config_scroll_set_method(dev->libinput_device,
1176 libinput_device_config_scroll_get_default_method(
1177 dev->libinput_device));
1178 libinput_device_config_scroll_set_button(dev->libinput_device,
1179 libinput_device_config_scroll_get_default_button(
1180 dev->libinput_device));
1181 }
1182 END_TEST
1183
START_TEST(pointer_scroll_nowheel_defaults)1184 START_TEST(pointer_scroll_nowheel_defaults)
1185 {
1186 struct litest_device *dev = litest_current_device();
1187 struct libinput_device *device = dev->libinput_device;
1188 enum libinput_config_scroll_method method, expected;
1189 uint32_t button;
1190
1191 /* button scrolling is only enabled if there is a
1192 middle button present */
1193 if (libinput_device_pointer_has_button(device, BTN_MIDDLE))
1194 expected = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
1195 else
1196 expected = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
1197
1198 method = libinput_device_config_scroll_get_method(device);
1199 ck_assert_int_eq(method, expected);
1200
1201 method = libinput_device_config_scroll_get_default_method(device);
1202 ck_assert_int_eq(method, expected);
1203
1204 if (method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) {
1205 button = libinput_device_config_scroll_get_button(device);
1206 ck_assert_int_eq(button, BTN_MIDDLE);
1207 button = libinput_device_config_scroll_get_default_button(device);
1208 ck_assert_int_eq(button, BTN_MIDDLE);
1209 }
1210 }
1211 END_TEST
1212
START_TEST(pointer_scroll_defaults_logitech_marble)1213 START_TEST(pointer_scroll_defaults_logitech_marble)
1214 {
1215 struct litest_device *dev = litest_current_device();
1216 struct libinput_device *device = dev->libinput_device;
1217 enum libinput_config_scroll_method method;
1218 uint32_t button;
1219
1220 method = libinput_device_config_scroll_get_method(device);
1221 ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
1222 method = libinput_device_config_scroll_get_default_method(device);
1223 ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
1224
1225 button = libinput_device_config_scroll_get_button(device);
1226 ck_assert_int_eq(button, BTN_SIDE);
1227 }
1228 END_TEST
1229
START_TEST(pointer_accel_defaults)1230 START_TEST(pointer_accel_defaults)
1231 {
1232 struct litest_device *dev = litest_current_device();
1233 struct libinput_device *device = dev->libinput_device;
1234 enum libinput_config_status status;
1235 double speed;
1236
1237 ck_assert(libinput_device_config_accel_is_available(device));
1238 ck_assert_double_eq(libinput_device_config_accel_get_default_speed(device),
1239 0.0);
1240 ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
1241 0.0);
1242
1243 for (speed = -2.0; speed < -1.0; speed += 0.2) {
1244 status = libinput_device_config_accel_set_speed(device,
1245 speed);
1246 ck_assert_int_eq(status,
1247 LIBINPUT_CONFIG_STATUS_INVALID);
1248 ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
1249 0.0);
1250 }
1251
1252 for (speed = -1.0; speed <= 1.0; speed += 0.2) {
1253 status = libinput_device_config_accel_set_speed(device,
1254 speed);
1255 ck_assert_int_eq(status,
1256 LIBINPUT_CONFIG_STATUS_SUCCESS);
1257 ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
1258 speed);
1259 }
1260
1261 for (speed = 1.2; speed <= 2.0; speed += 0.2) {
1262 status = libinput_device_config_accel_set_speed(device,
1263 speed);
1264 ck_assert_int_eq(status,
1265 LIBINPUT_CONFIG_STATUS_INVALID);
1266 ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
1267 1.0);
1268 }
1269
1270 }
1271 END_TEST
1272
START_TEST(pointer_accel_invalid)1273 START_TEST(pointer_accel_invalid)
1274 {
1275 struct litest_device *dev = litest_current_device();
1276 struct libinput_device *device = dev->libinput_device;
1277 enum libinput_config_status status;
1278
1279 ck_assert(libinput_device_config_accel_is_available(device));
1280
1281 status = libinput_device_config_accel_set_speed(device,
1282 NAN);
1283 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1284 status = libinput_device_config_accel_set_speed(device,
1285 INFINITY);
1286 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1287 }
1288 END_TEST
1289
START_TEST(pointer_accel_defaults_absolute)1290 START_TEST(pointer_accel_defaults_absolute)
1291 {
1292 struct litest_device *dev = litest_current_device();
1293 struct libinput_device *device = dev->libinput_device;
1294 enum libinput_config_status status;
1295 double speed;
1296
1297 ck_assert(!libinput_device_config_accel_is_available(device));
1298 ck_assert_double_eq(libinput_device_config_accel_get_default_speed(device),
1299 0.0);
1300 ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
1301 0.0);
1302
1303 for (speed = -2.0; speed <= 2.0; speed += 0.2) {
1304 status = libinput_device_config_accel_set_speed(device,
1305 speed);
1306 if (speed >= -1.0 && speed <= 1.0)
1307 ck_assert_int_eq(status,
1308 LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
1309 else
1310 ck_assert_int_eq(status,
1311 LIBINPUT_CONFIG_STATUS_INVALID);
1312 ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
1313 0.0);
1314 }
1315 }
1316 END_TEST
1317
START_TEST(pointer_accel_defaults_absolute_relative)1318 START_TEST(pointer_accel_defaults_absolute_relative)
1319 {
1320 struct litest_device *dev = litest_current_device();
1321 struct libinput_device *device = dev->libinput_device;
1322
1323 ck_assert(libinput_device_config_accel_is_available(device));
1324 ck_assert_double_eq(libinput_device_config_accel_get_default_speed(device),
1325 0.0);
1326 ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
1327 0.0);
1328 }
1329 END_TEST
1330
START_TEST(pointer_accel_direction_change)1331 START_TEST(pointer_accel_direction_change)
1332 {
1333 struct litest_device *dev = litest_current_device();
1334 struct libinput *li = dev->libinput;
1335 struct libinput_event *event;
1336 struct libinput_event_pointer *pev;
1337 int i;
1338 double delta;
1339
1340 litest_drain_events(li);
1341
1342 for (i = 0; i < 10; i++) {
1343 litest_event(dev, EV_REL, REL_X, -1);
1344 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1345 }
1346 litest_event(dev, EV_REL, REL_X, 1);
1347 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1348 libinput_dispatch(li);
1349
1350 event = libinput_get_event(li);
1351 do {
1352 pev = libinput_event_get_pointer_event(event);
1353
1354 delta = libinput_event_pointer_get_dx(pev);
1355 ck_assert_double_le(delta, 0.0);
1356 libinput_event_destroy(event);
1357 event = libinput_get_event(li);
1358 } while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE);
1359
1360 pev = libinput_event_get_pointer_event(event);
1361 delta = libinput_event_pointer_get_dx(pev);
1362 ck_assert_double_gt(delta, 0.0);
1363 libinput_event_destroy(event);
1364 }
1365 END_TEST
1366
START_TEST(pointer_accel_profile_defaults)1367 START_TEST(pointer_accel_profile_defaults)
1368 {
1369 struct litest_device *dev = litest_current_device();
1370 struct libinput_device *device = dev->libinput_device;
1371 enum libinput_config_status status;
1372 enum libinput_config_accel_profile profile;
1373 uint32_t profiles;
1374
1375 ck_assert(libinput_device_config_accel_is_available(device));
1376
1377 profile = libinput_device_config_accel_get_default_profile(device);
1378 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
1379
1380 profile = libinput_device_config_accel_get_profile(device);
1381 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
1382
1383 profiles = libinput_device_config_accel_get_profiles(device);
1384 ck_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
1385 ck_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
1386
1387 status = libinput_device_config_accel_set_profile(device,
1388 LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
1389 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1390 profile = libinput_device_config_accel_get_profile(device);
1391 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
1392
1393 profile = libinput_device_config_accel_get_default_profile(device);
1394 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
1395
1396 status = libinput_device_config_accel_set_profile(device,
1397 LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
1398 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1399 profile = libinput_device_config_accel_get_profile(device);
1400 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
1401 }
1402 END_TEST
1403
START_TEST(pointer_accel_profile_defaults_noprofile)1404 START_TEST(pointer_accel_profile_defaults_noprofile)
1405 {
1406 struct litest_device *dev = litest_current_device();
1407 struct libinput_device *device = dev->libinput_device;
1408 enum libinput_config_status status;
1409 enum libinput_config_accel_profile profile;
1410 uint32_t profiles;
1411
1412 ck_assert(libinput_device_config_accel_is_available(device));
1413
1414 profile = libinput_device_config_accel_get_default_profile(device);
1415 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1416
1417 profile = libinput_device_config_accel_get_profile(device);
1418 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1419
1420 profiles = libinput_device_config_accel_get_profiles(device);
1421 ck_assert_int_eq(profiles, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1422
1423 status = libinput_device_config_accel_set_profile(device,
1424 LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
1425 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
1426 profile = libinput_device_config_accel_get_profile(device);
1427 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1428
1429 status = libinput_device_config_accel_set_profile(device,
1430 LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
1431 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
1432 profile = libinput_device_config_accel_get_profile(device);
1433 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1434 }
1435 END_TEST
1436
START_TEST(pointer_accel_profile_invalid)1437 START_TEST(pointer_accel_profile_invalid)
1438 {
1439 struct litest_device *dev = litest_current_device();
1440 struct libinput_device *device = dev->libinput_device;
1441 enum libinput_config_status status;
1442
1443 ck_assert(libinput_device_config_accel_is_available(device));
1444
1445 status = libinput_device_config_accel_set_profile(device,
1446 LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1447 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1448
1449 status = libinput_device_config_accel_set_profile(device,
1450 LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE + 1);
1451 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1452
1453 status = libinput_device_config_accel_set_profile(device,
1454 LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE |LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
1455 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1456 }
1457 END_TEST
1458
START_TEST(pointer_accel_profile_noaccel)1459 START_TEST(pointer_accel_profile_noaccel)
1460 {
1461 struct litest_device *dev = litest_current_device();
1462 struct libinput_device *device = dev->libinput_device;
1463 enum libinput_config_status status;
1464 enum libinput_config_accel_profile profile;
1465
1466 ck_assert(!libinput_device_config_accel_is_available(device));
1467
1468 profile = libinput_device_config_accel_get_default_profile(device);
1469 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1470
1471 profile = libinput_device_config_accel_get_profile(device);
1472 ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1473
1474 status = libinput_device_config_accel_set_profile(device,
1475 LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
1476 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1477
1478 status = libinput_device_config_accel_set_profile(device,
1479 LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE + 1);
1480 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1481
1482 status = libinput_device_config_accel_set_profile(device,
1483 LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE |LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
1484 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1485 }
1486 END_TEST
1487
START_TEST(pointer_accel_profile_flat_motion_relative)1488 START_TEST(pointer_accel_profile_flat_motion_relative)
1489 {
1490 struct litest_device *dev = litest_current_device();
1491 struct libinput_device *device = dev->libinput_device;
1492
1493 libinput_device_config_accel_set_profile(device,
1494 LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
1495 litest_drain_events(dev->libinput);
1496
1497 test_relative_event(dev, 1, 0);
1498 test_relative_event(dev, 1, 1);
1499 test_relative_event(dev, 1, -1);
1500 test_relative_event(dev, 0, 1);
1501
1502 test_relative_event(dev, -1, 0);
1503 test_relative_event(dev, -1, 1);
1504 test_relative_event(dev, -1, -1);
1505 test_relative_event(dev, 0, -1);
1506 }
1507 END_TEST
1508
START_TEST(middlebutton)1509 START_TEST(middlebutton)
1510 {
1511 struct litest_device *device = litest_current_device();
1512 struct libinput *li = device->libinput;
1513 enum libinput_config_status status;
1514 unsigned int i;
1515 const int btn[][4] = {
1516 { BTN_LEFT, BTN_RIGHT, BTN_LEFT, BTN_RIGHT },
1517 { BTN_LEFT, BTN_RIGHT, BTN_RIGHT, BTN_LEFT },
1518 { BTN_RIGHT, BTN_LEFT, BTN_LEFT, BTN_RIGHT },
1519 { BTN_RIGHT, BTN_LEFT, BTN_RIGHT, BTN_LEFT },
1520 };
1521
1522 disable_button_scrolling(device);
1523
1524 status = libinput_device_config_middle_emulation_set_enabled(
1525 device->libinput_device,
1526 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1527 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1528 return;
1529
1530 litest_drain_events(li);
1531
1532 for (i = 0; i < ARRAY_LENGTH(btn); i++) {
1533 litest_button_click_debounced(device, li, btn[i][0], true);
1534 litest_button_click_debounced(device, li, btn[i][1], true);
1535
1536 litest_assert_button_event(li,
1537 BTN_MIDDLE,
1538 LIBINPUT_BUTTON_STATE_PRESSED);
1539 litest_assert_empty_queue(li);
1540
1541 litest_button_click_debounced(device, li, btn[i][2], false);
1542 litest_button_click_debounced(device, li, btn[i][3], false);
1543 litest_assert_button_event(li,
1544 BTN_MIDDLE,
1545 LIBINPUT_BUTTON_STATE_RELEASED);
1546 litest_assert_empty_queue(li);
1547 }
1548 }
1549 END_TEST
1550
START_TEST(middlebutton_nostart_while_down)1551 START_TEST(middlebutton_nostart_while_down)
1552 {
1553 struct litest_device *device = litest_current_device();
1554 struct libinput *li = device->libinput;
1555 enum libinput_config_status status;
1556 unsigned int i;
1557 const int btn[][4] = {
1558 { BTN_LEFT, BTN_RIGHT, BTN_LEFT, BTN_RIGHT },
1559 { BTN_LEFT, BTN_RIGHT, BTN_RIGHT, BTN_LEFT },
1560 { BTN_RIGHT, BTN_LEFT, BTN_LEFT, BTN_RIGHT },
1561 { BTN_RIGHT, BTN_LEFT, BTN_RIGHT, BTN_LEFT },
1562 };
1563
1564 if (!libinput_device_pointer_has_button(device->libinput_device,
1565 BTN_MIDDLE))
1566 return;
1567
1568 disable_button_scrolling(device);
1569
1570 status = libinput_device_config_middle_emulation_set_enabled(
1571 device->libinput_device,
1572 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1573 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1574 return;
1575
1576 litest_button_click_debounced(device, li, BTN_MIDDLE, true);
1577 litest_drain_events(li);
1578
1579 for (i = 0; i < ARRAY_LENGTH(btn); i++) {
1580 litest_button_click_debounced(device, li, btn[i][0], true);
1581 litest_assert_button_event(li,
1582 btn[i][0],
1583 LIBINPUT_BUTTON_STATE_PRESSED);
1584 litest_button_click_debounced(device, li, btn[i][1], true);
1585 litest_assert_button_event(li,
1586 btn[i][1],
1587 LIBINPUT_BUTTON_STATE_PRESSED);
1588
1589 litest_assert_empty_queue(li);
1590
1591 litest_button_click_debounced(device, li, btn[i][2], false);
1592 litest_assert_button_event(li,
1593 btn[i][2],
1594 LIBINPUT_BUTTON_STATE_RELEASED);
1595 litest_button_click_debounced(device, li, btn[i][3], false);
1596 litest_assert_button_event(li,
1597 btn[i][3],
1598 LIBINPUT_BUTTON_STATE_RELEASED);
1599 litest_assert_empty_queue(li);
1600 }
1601
1602 litest_button_click_debounced(device, li, BTN_MIDDLE, false);
1603 litest_drain_events(li);
1604 }
1605 END_TEST
1606
START_TEST(middlebutton_timeout)1607 START_TEST(middlebutton_timeout)
1608 {
1609 struct litest_device *device = litest_current_device();
1610 struct libinput *li = device->libinput;
1611 enum libinput_config_status status;
1612 unsigned int button;
1613
1614 disable_button_scrolling(device);
1615
1616 status = libinput_device_config_middle_emulation_set_enabled(
1617 device->libinput_device,
1618 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1619 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1620 return;
1621
1622 for (button = BTN_LEFT; button <= BTN_RIGHT; button++) {
1623 litest_drain_events(li);
1624 litest_button_click_debounced(device, li, button, true);
1625 litest_assert_empty_queue(li);
1626 litest_timeout_middlebutton();
1627
1628 litest_assert_button_event(li,
1629 button,
1630 LIBINPUT_BUTTON_STATE_PRESSED);
1631
1632 litest_button_click_debounced(device, li, button, false);
1633 litest_assert_button_event(li,
1634 button,
1635 LIBINPUT_BUTTON_STATE_RELEASED);
1636 litest_assert_empty_queue(li);
1637 }
1638 }
1639 END_TEST
1640
START_TEST(middlebutton_doubleclick)1641 START_TEST(middlebutton_doubleclick)
1642 {
1643 struct litest_device *device = litest_current_device();
1644 struct libinput *li = device->libinput;
1645 enum libinput_config_status status;
1646 unsigned int i;
1647 const int btn[][4] = {
1648 { BTN_LEFT, BTN_RIGHT, BTN_LEFT, BTN_RIGHT },
1649 { BTN_LEFT, BTN_RIGHT, BTN_RIGHT, BTN_LEFT },
1650 { BTN_RIGHT, BTN_LEFT, BTN_LEFT, BTN_RIGHT },
1651 { BTN_RIGHT, BTN_LEFT, BTN_RIGHT, BTN_LEFT },
1652 };
1653
1654 disable_button_scrolling(device);
1655
1656 status = libinput_device_config_middle_emulation_set_enabled(
1657 device->libinput_device,
1658 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1659 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1660 return;
1661
1662 litest_drain_events(li);
1663
1664 for (i = 0; i < ARRAY_LENGTH(btn); i++) {
1665 litest_button_click_debounced(device, li, btn[i][0], true);
1666 litest_button_click_debounced(device, li, btn[i][1], true);
1667 litest_assert_button_event(li,
1668 BTN_MIDDLE,
1669 LIBINPUT_BUTTON_STATE_PRESSED);
1670 litest_assert_empty_queue(li);
1671
1672 litest_button_click_debounced(device, li, btn[i][2], false);
1673 litest_button_click_debounced(device, li, btn[i][2], true);
1674 litest_assert_button_event(li,
1675 BTN_MIDDLE,
1676 LIBINPUT_BUTTON_STATE_RELEASED);
1677 litest_assert_button_event(li,
1678 BTN_MIDDLE,
1679 LIBINPUT_BUTTON_STATE_PRESSED);
1680 litest_button_click_debounced(device, li, btn[i][3], false);
1681
1682 litest_assert_button_event(li,
1683 BTN_MIDDLE,
1684 LIBINPUT_BUTTON_STATE_RELEASED);
1685 litest_assert_empty_queue(li);
1686 }
1687 }
1688 END_TEST
1689
START_TEST(middlebutton_middleclick)1690 START_TEST(middlebutton_middleclick)
1691 {
1692 struct litest_device *device = litest_current_device();
1693 struct libinput *li = device->libinput;
1694 enum libinput_config_status status;
1695 unsigned int button;
1696
1697 disable_button_scrolling(device);
1698
1699 if (!libinput_device_pointer_has_button(device->libinput_device,
1700 BTN_MIDDLE))
1701 return;
1702
1703 status = libinput_device_config_middle_emulation_set_enabled(
1704 device->libinput_device,
1705 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1706 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1707 return;
1708
1709 /* one button down, then middle -> release buttons */
1710 for (button = BTN_LEFT; button <= BTN_RIGHT; button++) {
1711 /* release button before middle */
1712 litest_drain_events(li);
1713 litest_button_click_debounced(device, li, button, true);
1714 litest_button_click_debounced(device, li, BTN_MIDDLE, true);
1715 litest_assert_button_event(li,
1716 button,
1717 LIBINPUT_BUTTON_STATE_PRESSED);
1718 litest_assert_button_event(li,
1719 BTN_MIDDLE,
1720 LIBINPUT_BUTTON_STATE_PRESSED);
1721 litest_assert_empty_queue(li);
1722 litest_button_click_debounced(device, li, button, false);
1723 litest_assert_button_event(li,
1724 button,
1725 LIBINPUT_BUTTON_STATE_RELEASED);
1726 litest_button_click_debounced(device, li, BTN_MIDDLE, false);
1727 litest_assert_button_event(li,
1728 BTN_MIDDLE,
1729 LIBINPUT_BUTTON_STATE_RELEASED);
1730 litest_assert_empty_queue(li);
1731
1732 /* release middle before button */
1733 litest_button_click_debounced(device, li, button, true);
1734 litest_button_click_debounced(device, li, BTN_MIDDLE, true);
1735 litest_assert_button_event(li,
1736 button,
1737 LIBINPUT_BUTTON_STATE_PRESSED);
1738 litest_assert_button_event(li,
1739 BTN_MIDDLE,
1740 LIBINPUT_BUTTON_STATE_PRESSED);
1741 litest_assert_empty_queue(li);
1742 litest_button_click_debounced(device, li, BTN_MIDDLE, false);
1743 litest_assert_button_event(li,
1744 BTN_MIDDLE,
1745 LIBINPUT_BUTTON_STATE_RELEASED);
1746 litest_button_click_debounced(device, li, button, false);
1747 litest_assert_button_event(li,
1748 button,
1749 LIBINPUT_BUTTON_STATE_RELEASED);
1750 litest_assert_empty_queue(li);
1751 }
1752 }
1753 END_TEST
1754
START_TEST(middlebutton_middleclick_during)1755 START_TEST(middlebutton_middleclick_during)
1756 {
1757 struct litest_device *device = litest_current_device();
1758 struct libinput *li = device->libinput;
1759 enum libinput_config_status status;
1760 unsigned int button;
1761
1762 disable_button_scrolling(device);
1763
1764 if (!libinput_device_pointer_has_button(device->libinput_device,
1765 BTN_MIDDLE))
1766 return;
1767
1768 status = libinput_device_config_middle_emulation_set_enabled(
1769 device->libinput_device,
1770 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1771 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1772 return;
1773
1774 litest_drain_events(li);
1775
1776 /* trigger emulation, then real middle */
1777 for (button = BTN_LEFT; button <= BTN_RIGHT; button++) {
1778 litest_button_click_debounced(device, li, BTN_LEFT, true);
1779 litest_button_click_debounced(device, li, BTN_RIGHT, true);
1780
1781 litest_assert_button_event(li,
1782 BTN_MIDDLE,
1783 LIBINPUT_BUTTON_STATE_PRESSED);
1784
1785 litest_button_click_debounced(device, li, BTN_MIDDLE, true);
1786 litest_assert_button_event(li,
1787 BTN_MIDDLE,
1788 LIBINPUT_BUTTON_STATE_RELEASED);
1789 litest_assert_button_event(li,
1790 BTN_MIDDLE,
1791 LIBINPUT_BUTTON_STATE_PRESSED);
1792
1793 litest_assert_empty_queue(li);
1794
1795 /* middle still down, release left/right */
1796 litest_button_click_debounced(device, li, button, false);
1797 litest_assert_empty_queue(li);
1798 litest_button_click_debounced(device, li, button, true);
1799 litest_assert_button_event(li,
1800 button,
1801 LIBINPUT_BUTTON_STATE_PRESSED);
1802 litest_assert_empty_queue(li);
1803
1804 /* release both */
1805 litest_button_click_debounced(device, li, BTN_LEFT, false);
1806 litest_button_click_debounced(device, li, BTN_RIGHT, false);
1807 litest_assert_button_event(li,
1808 button,
1809 LIBINPUT_BUTTON_STATE_RELEASED);
1810 litest_assert_empty_queue(li);
1811
1812 litest_button_click_debounced(device, li, BTN_MIDDLE, false);
1813 litest_assert_button_event(li,
1814 BTN_MIDDLE,
1815 LIBINPUT_BUTTON_STATE_RELEASED);
1816 litest_assert_empty_queue(li);
1817 }
1818 }
1819 END_TEST
1820
START_TEST(middlebutton_default_enabled)1821 START_TEST(middlebutton_default_enabled)
1822 {
1823 struct litest_device *dev = litest_current_device();
1824 struct libinput_device *device = dev->libinput_device;
1825 enum libinput_config_status status;
1826 int available;
1827 enum libinput_config_middle_emulation_state state;
1828
1829 if (!libinput_device_pointer_has_button(dev->libinput_device,
1830 BTN_MIDDLE))
1831 return;
1832
1833 available = libinput_device_config_middle_emulation_is_available(device);
1834 ck_assert(available);
1835
1836 state = libinput_device_config_middle_emulation_get_enabled(device);
1837 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1838
1839 state = libinput_device_config_middle_emulation_get_default_enabled(
1840 device);
1841 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1842
1843 status = libinput_device_config_middle_emulation_set_enabled(device,
1844 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1845 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1846
1847 status = libinput_device_config_middle_emulation_set_enabled(device,
1848 LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1849 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1850
1851 status = libinput_device_config_middle_emulation_set_enabled(device, 3);
1852 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1853 }
1854 END_TEST
1855
START_TEST(middlebutton_default_clickpad)1856 START_TEST(middlebutton_default_clickpad)
1857 {
1858 struct litest_device *dev = litest_current_device();
1859 struct libinput_device *device = dev->libinput_device;
1860 enum libinput_config_status status;
1861 enum libinput_config_middle_emulation_state state;
1862 int available;
1863
1864 available = libinput_device_config_middle_emulation_is_available(device);
1865 ck_assert(available);
1866
1867 state = libinput_device_config_middle_emulation_get_enabled(device);
1868 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1869 state = libinput_device_config_middle_emulation_get_default_enabled(
1870 device);
1871 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1872
1873 status = libinput_device_config_middle_emulation_set_enabled(device,
1874 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1875 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1876
1877 status = libinput_device_config_middle_emulation_set_enabled(device,
1878 LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1879 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1880
1881 status = libinput_device_config_middle_emulation_set_enabled(device, 3);
1882 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
1883 }
1884 END_TEST
1885
START_TEST(middlebutton_default_touchpad)1886 START_TEST(middlebutton_default_touchpad)
1887 {
1888 struct litest_device *dev = litest_current_device();
1889 struct libinput_device *device = dev->libinput_device;
1890 enum libinput_config_middle_emulation_state state;
1891 int available;
1892 const char *name = libinput_device_get_name(dev->libinput_device);
1893
1894 if (streq(name, "litest AlpsPS/2 ALPS GlidePoint") ||
1895 streq(name, "litest AlpsPS/2 ALPS DualPoint TouchPad"))
1896 return;
1897
1898 available = libinput_device_config_middle_emulation_is_available(device);
1899 ck_assert(!available);
1900
1901 if (libinput_device_pointer_has_button(device, BTN_MIDDLE))
1902 return;
1903
1904 state = libinput_device_config_middle_emulation_get_enabled(
1905 device);
1906 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1907 state = libinput_device_config_middle_emulation_get_default_enabled(
1908 device);
1909 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1910 }
1911 END_TEST
1912
START_TEST(middlebutton_default_alps)1913 START_TEST(middlebutton_default_alps)
1914 {
1915 struct litest_device *dev = litest_current_device();
1916 struct libinput_device *device = dev->libinput_device;
1917 enum libinput_config_middle_emulation_state state;
1918 int available;
1919
1920 available = libinput_device_config_middle_emulation_is_available(device);
1921 ck_assert(available);
1922
1923 state = libinput_device_config_middle_emulation_get_enabled(
1924 device);
1925 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1926 state = libinput_device_config_middle_emulation_get_default_enabled(
1927 device);
1928 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1929 }
1930 END_TEST
1931
START_TEST(middlebutton_default_disabled)1932 START_TEST(middlebutton_default_disabled)
1933 {
1934 struct litest_device *dev = litest_current_device();
1935 struct libinput_device *device = dev->libinput_device;
1936 enum libinput_config_middle_emulation_state state;
1937 enum libinput_config_status status;
1938 int available;
1939
1940 available = libinput_device_config_middle_emulation_is_available(device);
1941 ck_assert(!available);
1942 state = libinput_device_config_middle_emulation_get_enabled(device);
1943 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1944 state = libinput_device_config_middle_emulation_get_default_enabled(
1945 device);
1946 ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1947 status = libinput_device_config_middle_emulation_set_enabled(device,
1948 LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
1949 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
1950 status = libinput_device_config_middle_emulation_set_enabled(device,
1951 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1952 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
1953 }
1954 END_TEST
1955
START_TEST(middlebutton_button_scrolling)1956 START_TEST(middlebutton_button_scrolling)
1957 {
1958 struct litest_device *dev = litest_current_device();
1959 struct libinput_device *device = dev->libinput_device;
1960 struct libinput *li = dev->libinput;
1961 enum libinput_config_status status;
1962 struct libinput_event *ev;
1963 struct libinput_event_pointer *pev;
1964 int i;
1965
1966 status = libinput_device_config_middle_emulation_set_enabled(
1967 device,
1968 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
1969 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1970 return;
1971
1972 status = libinput_device_config_scroll_set_method(device,
1973 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
1974 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1975 return;
1976
1977 status = libinput_device_config_scroll_set_button(device, BTN_LEFT);
1978 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
1979 return;
1980
1981 litest_drain_events(li);
1982
1983 litest_event(dev, EV_KEY, BTN_LEFT, 1);
1984 litest_event(dev, EV_SYN, SYN_REPORT, 0);
1985 libinput_dispatch(li);
1986
1987 /* middle emulation discards */
1988 litest_assert_empty_queue(li);
1989
1990 litest_timeout_middlebutton();
1991 libinput_dispatch(li);
1992
1993 /* scroll discards */
1994 litest_assert_empty_queue(li);
1995 litest_timeout_buttonscroll();
1996 libinput_dispatch(li);
1997
1998 for (i = 0; i < 10; i++) {
1999 litest_event(dev, EV_REL, REL_Y, 1);
2000 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2001 libinput_dispatch(li);
2002 }
2003
2004 ev = libinput_get_event(li);
2005 do {
2006 pev = litest_is_axis_event(ev,
2007 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
2008 LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
2009 ck_assert_double_gt(libinput_event_pointer_get_axis_value(pev,
2010 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
2011 0.0);
2012 libinput_event_destroy(ev);
2013 ev = libinput_get_event(li);
2014 } while (ev);
2015
2016 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2017 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2018 libinput_dispatch(li);
2019
2020 ev = libinput_get_event(li);
2021 pev = litest_is_axis_event(ev,
2022 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
2023 LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
2024 ck_assert_double_eq(libinput_event_pointer_get_axis_value(pev,
2025 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
2026 0.0);
2027 libinput_event_destroy(ev);
2028
2029 /* no button release */
2030 litest_assert_empty_queue(li);
2031 }
2032 END_TEST
2033
START_TEST(middlebutton_button_scrolling_middle)2034 START_TEST(middlebutton_button_scrolling_middle)
2035 {
2036 struct litest_device *dev = litest_current_device();
2037 struct libinput_device *device = dev->libinput_device;
2038 struct libinput *li = dev->libinput;
2039 enum libinput_config_status status;
2040
2041 status = libinput_device_config_middle_emulation_set_enabled(
2042 device,
2043 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
2044 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
2045 return;
2046
2047 status = libinput_device_config_scroll_set_method(device,
2048 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
2049 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
2050 return;
2051
2052 status = libinput_device_config_scroll_set_button(device, BTN_LEFT);
2053 if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
2054 return;
2055
2056 litest_drain_events(li);
2057
2058 /* button scrolling should not stop middle emulation */
2059
2060 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2061 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2062 litest_event(dev, EV_KEY, BTN_RIGHT, 1);
2063 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2064 libinput_dispatch(li);
2065
2066 litest_assert_button_event(li,
2067 BTN_MIDDLE,
2068 LIBINPUT_BUTTON_STATE_PRESSED);
2069
2070 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2071 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2072 litest_event(dev, EV_KEY, BTN_RIGHT, 0);
2073 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2074 libinput_dispatch(li);
2075
2076 litest_assert_button_event(li,
2077 BTN_MIDDLE,
2078 LIBINPUT_BUTTON_STATE_RELEASED);
2079
2080 litest_assert_empty_queue(li);
2081 }
2082 END_TEST
2083
START_TEST(pointer_time_usec)2084 START_TEST(pointer_time_usec)
2085 {
2086 struct litest_device *dev = litest_current_device();
2087 struct libinput *li = dev->libinput;
2088 struct libinput_event_pointer *ptrev;
2089 struct libinput_event *event;
2090 uint64_t time_usec;
2091
2092 litest_drain_events(dev->libinput);
2093
2094 litest_event(dev, EV_REL, REL_X, 1);
2095 litest_event(dev, EV_REL, REL_Y, 1);
2096 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2097
2098 litest_wait_for_event(li);
2099
2100 event = libinput_get_event(li);
2101 ptrev = litest_is_motion_event(event);
2102
2103 time_usec = libinput_event_pointer_get_time_usec(ptrev);
2104 ck_assert_int_eq(libinput_event_pointer_get_time(ptrev),
2105 (uint32_t) (time_usec / 1000));
2106
2107 libinput_event_destroy(event);
2108 litest_drain_events(dev->libinput);
2109 }
2110 END_TEST
2111
START_TEST(debounce_bounce)2112 START_TEST(debounce_bounce)
2113 {
2114 struct litest_device *dev = litest_current_device();
2115 struct libinput *li = dev->libinput;
2116 unsigned int button = _i; /* ranged test */
2117
2118 if (!libinput_device_pointer_has_button(dev->libinput_device,
2119 button))
2120 return;
2121
2122 litest_disable_middleemu(dev);
2123 disable_button_scrolling(dev);
2124 litest_drain_events(li);
2125
2126 litest_event(dev, EV_KEY, button, 1);
2127 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2128 litest_event(dev, EV_KEY, button, 0);
2129 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2130 litest_event(dev, EV_KEY, button, 1);
2131 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2132 libinput_dispatch(li);
2133 litest_timeout_debounce();
2134 libinput_dispatch(li);
2135
2136 litest_assert_button_event(li,
2137 button,
2138 LIBINPUT_BUTTON_STATE_PRESSED);
2139 litest_assert_empty_queue(li);
2140
2141 litest_event(dev, EV_KEY, button, 0);
2142 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2143 litest_event(dev, EV_KEY, button, 1);
2144 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2145 litest_event(dev, EV_KEY, button, 0);
2146 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2147 libinput_dispatch(li);
2148 litest_timeout_debounce();
2149 libinput_dispatch(li);
2150
2151 litest_assert_button_event(li,
2152 button,
2153 LIBINPUT_BUTTON_STATE_RELEASED);
2154
2155 litest_assert_empty_queue(li);
2156 }
2157 END_TEST
2158
START_TEST(debounce_bounce_check_immediate)2159 START_TEST(debounce_bounce_check_immediate)
2160 {
2161 struct litest_device *dev = litest_current_device();
2162 struct libinput *li = dev->libinput;
2163
2164 litest_disable_middleemu(dev);
2165 disable_button_scrolling(dev);
2166 litest_drain_events(li);
2167
2168 /* Press must be sent without delay */
2169 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2170 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2171 litest_assert_button_event(li,
2172 BTN_LEFT,
2173 LIBINPUT_BUTTON_STATE_PRESSED);
2174 litest_timeout_debounce();
2175 litest_assert_empty_queue(li);
2176
2177 /* held down & past timeout, we expect releases to be immediate */
2178
2179 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2180 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2181 litest_assert_button_event(li,
2182 BTN_LEFT,
2183 LIBINPUT_BUTTON_STATE_RELEASED);
2184
2185 litest_timeout_debounce();
2186 litest_assert_empty_queue(li);
2187 }
2188 END_TEST
2189
2190 /* Triggers the event sequence that initializes the spurious
2191 * debouncing behavior */
2192 static inline void
debounce_trigger_spurious(struct litest_device * dev,struct libinput * li)2193 debounce_trigger_spurious(struct litest_device *dev, struct libinput *li)
2194 {
2195 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2196 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2197 libinput_dispatch(li);
2198 litest_timeout_debounce();
2199 libinput_dispatch(li);
2200
2201 litest_assert_button_event(li,
2202 BTN_LEFT,
2203 LIBINPUT_BUTTON_STATE_PRESSED);
2204
2205 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2206 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2207 libinput_dispatch(li);
2208 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2209 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2210 libinput_dispatch(li);
2211
2212 litest_timeout_debounce();
2213 libinput_dispatch(li);
2214
2215 litest_assert_button_event(li,
2216 BTN_LEFT,
2217 LIBINPUT_BUTTON_STATE_RELEASED);
2218 litest_assert_button_event(li,
2219 BTN_LEFT,
2220 LIBINPUT_BUTTON_STATE_PRESSED);
2221
2222 /* gets filtered now */
2223 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2224 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2225 libinput_dispatch(li);
2226 litest_timeout_debounce();
2227 libinput_dispatch(li);
2228 litest_assert_button_event(li,
2229 BTN_LEFT,
2230 LIBINPUT_BUTTON_STATE_RELEASED);
2231 litest_assert_empty_queue(li);
2232 }
2233
START_TEST(debounce_spurious)2234 START_TEST(debounce_spurious)
2235 {
2236 struct litest_device *dev = litest_current_device();
2237 struct libinput *li = dev->libinput;
2238 unsigned int button = _i; /* ranged test */
2239
2240 if (!libinput_device_pointer_has_button(dev->libinput_device,
2241 button))
2242 return;
2243
2244 litest_disable_middleemu(dev);
2245 disable_button_scrolling(dev);
2246 litest_drain_events(li);
2247
2248 debounce_trigger_spurious(dev, li);
2249
2250 for (int i = 0; i < 3; i++) {
2251 litest_event(dev, EV_KEY, button, 1);
2252 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2253 libinput_dispatch(li);
2254 litest_timeout_debounce();
2255 libinput_dispatch(li);
2256
2257 /* Not all devices can disable middle button emulation, time out on
2258 * middle button here to make sure the initial button press event
2259 * was flushed.
2260 */
2261 litest_timeout_middlebutton();
2262 libinput_dispatch(li);
2263
2264 litest_assert_button_event(li,
2265 button,
2266 LIBINPUT_BUTTON_STATE_PRESSED);
2267
2268 /* bouncy bouncy bouncy */
2269 litest_event(dev, EV_KEY, button, 0);
2270 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2271 litest_event(dev, EV_KEY, button, 1);
2272 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2273 litest_assert_empty_queue(li);
2274
2275 litest_event(dev, EV_KEY, button, 0);
2276 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2277 libinput_dispatch(li);
2278 litest_timeout_debounce();
2279 libinput_dispatch(li);
2280 litest_assert_button_event(li,
2281 button,
2282 LIBINPUT_BUTTON_STATE_RELEASED);
2283
2284 litest_assert_empty_queue(li);
2285 }
2286 }
2287 END_TEST
2288
START_TEST(debounce_spurious_multibounce)2289 START_TEST(debounce_spurious_multibounce)
2290 {
2291 struct litest_device *dev = litest_current_device();
2292 struct libinput *li = dev->libinput;
2293
2294 litest_disable_middleemu(dev);
2295 litest_drain_events(li);
2296
2297 debounce_trigger_spurious(dev, li);
2298 litest_drain_events(li);
2299
2300 /* Let's assume our button has ventricular fibrilation and sends a
2301 * lot of clicks. Debouncing is now enabled, ventricular
2302 * fibrillation should cause one button down for the first press and
2303 * one release for the last release.
2304 */
2305
2306 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2307 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2308 libinput_dispatch(li);
2309 litest_timeout_debounce();
2310
2311 /* Not all devices can disable middle button emulation, time out on
2312 * middle button here to make sure the initial button press event
2313 * was flushed.
2314 */
2315 libinput_dispatch(li);
2316 litest_timeout_middlebutton();
2317 libinput_dispatch(li);
2318 litest_assert_button_event(li,
2319 BTN_LEFT,
2320 LIBINPUT_BUTTON_STATE_PRESSED);
2321
2322 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2323 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2324 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2325 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2326 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2327 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2328 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2329 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2330 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2331 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2332 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2333 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2334 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2335 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2336
2337 litest_assert_empty_queue(li);
2338 litest_timeout_debounce();
2339
2340 litest_assert_button_event(li,
2341 BTN_LEFT,
2342 LIBINPUT_BUTTON_STATE_RELEASED);
2343
2344 litest_assert_empty_queue(li);
2345 }
2346 END_TEST
2347
START_TEST(debounce_spurious_dont_enable_on_otherbutton)2348 START_TEST(debounce_spurious_dont_enable_on_otherbutton)
2349 {
2350 struct litest_device *dev = litest_current_device();
2351 struct libinput_device *device = dev->libinput_device;
2352 struct libinput *li = dev->libinput;
2353
2354 if (!libinput_device_config_middle_emulation_is_available(device))
2355 return;
2356
2357 litest_disable_middleemu(dev);
2358 disable_button_scrolling(dev);
2359 litest_drain_events(li);
2360
2361 /* Don't trigger spurious debouncing on otherbutton events */
2362 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2363 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2364 libinput_dispatch(li);
2365 litest_timeout_debounce();
2366 libinput_dispatch(li);
2367
2368 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2369 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2370 litest_event(dev, EV_KEY, BTN_RIGHT, 1);
2371 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2372 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2373 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2374 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2375 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2376 litest_event(dev, EV_KEY, BTN_RIGHT, 0);
2377 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2378
2379 libinput_dispatch(li);
2380
2381 litest_assert_button_event(li,
2382 BTN_LEFT,
2383 LIBINPUT_BUTTON_STATE_PRESSED);
2384 litest_assert_button_event(li,
2385 BTN_LEFT,
2386 LIBINPUT_BUTTON_STATE_RELEASED);
2387
2388 litest_assert_button_event(li,
2389 BTN_RIGHT,
2390 LIBINPUT_BUTTON_STATE_PRESSED);
2391 litest_assert_button_event(li,
2392 BTN_LEFT,
2393 LIBINPUT_BUTTON_STATE_PRESSED);
2394 litest_assert_button_event(li,
2395 BTN_LEFT,
2396 LIBINPUT_BUTTON_STATE_RELEASED);
2397 litest_assert_button_event(li,
2398 BTN_RIGHT,
2399 LIBINPUT_BUTTON_STATE_RELEASED);
2400
2401 litest_assert_empty_queue(li);
2402
2403 /* Expect release to be immediate */
2404 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2405 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2406 libinput_dispatch(li);
2407 litest_timeout_debounce();
2408 libinput_dispatch(li);
2409
2410 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2411 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2412 libinput_dispatch(li);
2413 litest_assert_button_event(li,
2414 BTN_LEFT,
2415 LIBINPUT_BUTTON_STATE_PRESSED);
2416 litest_assert_button_event(li,
2417 BTN_LEFT,
2418 LIBINPUT_BUTTON_STATE_RELEASED);
2419 }
2420 END_TEST
2421
START_TEST(debounce_spurious_cancel_debounce_otherbutton)2422 START_TEST(debounce_spurious_cancel_debounce_otherbutton)
2423 {
2424 struct litest_device *dev = litest_current_device();
2425 struct libinput_device *device = dev->libinput_device;
2426 struct libinput *li = dev->libinput;
2427
2428 if (!libinput_device_config_middle_emulation_is_available(device))
2429 return;
2430
2431 litest_disable_middleemu(dev);
2432 disable_button_scrolling(dev);
2433 litest_drain_events(li);
2434
2435 debounce_trigger_spurious(dev, li);
2436
2437 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2438 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2439 libinput_dispatch(li);
2440 litest_timeout_debounce();
2441 libinput_dispatch(li);
2442
2443 /* spurious debouncing is on but the release should get flushed by
2444 * the other button */
2445 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2446 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2447 litest_event(dev, EV_KEY, BTN_RIGHT, 1);
2448 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2449 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2450 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2451 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2452 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2453 litest_event(dev, EV_KEY, BTN_RIGHT, 0);
2454 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2455
2456 libinput_dispatch(li);
2457
2458 litest_assert_button_event(li,
2459 BTN_LEFT,
2460 LIBINPUT_BUTTON_STATE_PRESSED);
2461 litest_assert_button_event(li,
2462 BTN_LEFT,
2463 LIBINPUT_BUTTON_STATE_RELEASED);
2464
2465 litest_assert_button_event(li,
2466 BTN_RIGHT,
2467 LIBINPUT_BUTTON_STATE_PRESSED);
2468 litest_assert_button_event(li,
2469 BTN_LEFT,
2470 LIBINPUT_BUTTON_STATE_PRESSED);
2471 litest_assert_button_event(li,
2472 BTN_LEFT,
2473 LIBINPUT_BUTTON_STATE_RELEASED);
2474 litest_assert_button_event(li,
2475 BTN_RIGHT,
2476 LIBINPUT_BUTTON_STATE_RELEASED);
2477
2478 litest_assert_empty_queue(li);
2479 }
2480 END_TEST
2481
START_TEST(debounce_spurious_switch_to_otherbutton)2482 START_TEST(debounce_spurious_switch_to_otherbutton)
2483 {
2484 struct litest_device *dev = litest_current_device();
2485 struct libinput_device *device = dev->libinput_device;
2486 struct libinput *li = dev->libinput;
2487
2488 if (!libinput_device_config_middle_emulation_is_available(device))
2489 return;
2490
2491 litest_drain_events(li);
2492 debounce_trigger_spurious(dev, li);
2493
2494 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2495 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2496 libinput_dispatch(li);
2497 litest_timeout_debounce();
2498 libinput_dispatch(li);
2499
2500 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2501 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2502 /* release is now held back,
2503 * other button should flush the release */
2504 litest_event(dev, EV_KEY, BTN_RIGHT, 1);
2505 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2506 litest_event(dev, EV_KEY, BTN_RIGHT, 0);
2507 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2508
2509 /* bouncing right button triggers debounce */
2510 litest_event(dev, EV_KEY, BTN_RIGHT, 1);
2511 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2512 litest_event(dev, EV_KEY, BTN_RIGHT, 0);
2513 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2514
2515 libinput_dispatch(li);
2516
2517 litest_assert_button_event(li,
2518 BTN_LEFT,
2519 LIBINPUT_BUTTON_STATE_PRESSED);
2520 litest_assert_button_event(li,
2521 BTN_LEFT,
2522 LIBINPUT_BUTTON_STATE_RELEASED);
2523
2524 litest_assert_button_event(li,
2525 BTN_RIGHT,
2526 LIBINPUT_BUTTON_STATE_PRESSED);
2527 litest_assert_button_event(li,
2528 BTN_RIGHT,
2529 LIBINPUT_BUTTON_STATE_RELEASED);
2530
2531 litest_assert_empty_queue(li);
2532 }
2533 END_TEST
2534
START_TEST(debounce_remove_device_button_up)2535 START_TEST(debounce_remove_device_button_up)
2536 {
2537 struct libinput *li;
2538 struct litest_device *dev;
2539
2540 li = litest_create_context();
2541
2542 dev = litest_add_device(li, LITEST_MOUSE);
2543 litest_drain_events(li);
2544
2545 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2546 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2547 litest_event(dev, EV_KEY, BTN_LEFT, 0);
2548 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2549 libinput_dispatch(li);
2550
2551 /* delete the device while the timer is still active */
2552 litest_delete_device(dev);
2553 libinput_dispatch(li);
2554
2555 litest_timeout_debounce();
2556 libinput_dispatch(li);
2557
2558 libinput_unref(li);
2559 }
2560 END_TEST
2561
START_TEST(debounce_remove_device_button_down)2562 START_TEST(debounce_remove_device_button_down)
2563 {
2564 struct libinput *li;
2565 struct litest_device *dev;
2566
2567 li = litest_create_context();
2568
2569 dev = litest_add_device(li, LITEST_MOUSE);
2570 litest_drain_events(li);
2571
2572 litest_event(dev, EV_KEY, BTN_LEFT, 1);
2573 litest_event(dev, EV_SYN, SYN_REPORT, 0);
2574 libinput_dispatch(li);
2575
2576 /* delete the device the timer is still active */
2577 litest_delete_device(dev);
2578 libinput_dispatch(li);
2579
2580 litest_timeout_debounce();
2581 libinput_dispatch(li);
2582
2583 libinput_unref(li);
2584 }
2585 END_TEST
2586
TEST_COLLECTION(pointer)2587 TEST_COLLECTION(pointer)
2588 {
2589 struct range axis_range = {ABS_X, ABS_Y + 1};
2590 struct range compass = {0, 7}; /* cardinal directions */
2591 struct range buttons = {BTN_LEFT, BTN_TASK + 1};
2592
2593 litest_add("pointer:motion", pointer_motion_relative, LITEST_RELATIVE, LITEST_POINTINGSTICK);
2594 litest_add_for_device("pointer:motion", pointer_motion_relative_zero, LITEST_MOUSE);
2595 litest_add_ranged("pointer:motion", pointer_motion_relative_min_decel, LITEST_RELATIVE, LITEST_POINTINGSTICK, &compass);
2596 litest_add("pointer:motion", pointer_motion_absolute, LITEST_ABSOLUTE, LITEST_ANY);
2597 litest_add("pointer:motion", pointer_motion_unaccel, LITEST_RELATIVE, LITEST_ANY);
2598 litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD);
2599 litest_add_no_device("pointer:button", pointer_button_auto_release);
2600 litest_add_no_device("pointer:button", pointer_seat_button_count);
2601 litest_add_for_device("pointer:button", pointer_button_has_no_button, LITEST_KEYBOARD);
2602 litest_add("pointer:button", pointer_recover_from_lost_button_count, LITEST_BUTTON, LITEST_CLICKPAD);
2603 litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET);
2604 litest_add("pointer:scroll", pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
2605 litest_add("pointer:scroll", pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE);
2606 litest_add("pointer:scroll", pointer_scroll_button_noscroll, LITEST_ANY, LITEST_RELATIVE|LITEST_BUTTON);
2607 litest_add("pointer:scroll", pointer_scroll_button_no_event_before_timeout, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
2608 litest_add("pointer:scroll", pointer_scroll_button_middle_emulation, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
2609 litest_add("pointer:scroll", pointer_scroll_nowheel_defaults, LITEST_RELATIVE|LITEST_BUTTON, LITEST_WHEEL);
2610 litest_add_for_device("pointer:scroll", pointer_scroll_defaults_logitech_marble , LITEST_LOGITECH_TRACKBALL);
2611 litest_add("pointer:scroll", pointer_scroll_natural_defaults, LITEST_WHEEL, LITEST_TABLET);
2612 litest_add("pointer:scroll", pointer_scroll_natural_defaults_noscroll, LITEST_ANY, LITEST_WHEEL);
2613 litest_add("pointer:scroll", pointer_scroll_natural_enable_config, LITEST_WHEEL, LITEST_TABLET);
2614 litest_add("pointer:scroll", pointer_scroll_natural_wheel, LITEST_WHEEL, LITEST_TABLET);
2615 litest_add("pointer:scroll", pointer_scroll_has_axis_invalid, LITEST_WHEEL, LITEST_TABLET);
2616
2617 litest_add("pointer:calibration", pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_ABSOLUTE|LITEST_PROTOCOL_A|LITEST_TABLET);
2618
2619 /* tests touchpads too */
2620 litest_add("pointer:left-handed", pointer_left_handed_defaults, LITEST_BUTTON, LITEST_ANY);
2621 litest_add("pointer:left-handed", pointer_left_handed, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
2622 litest_add("pointer:left-handed", pointer_left_handed_during_click, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
2623 litest_add("pointer:left-handed", pointer_left_handed_during_click_multiple_buttons, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
2624
2625 litest_add("pointer:accel", pointer_accel_defaults, LITEST_RELATIVE, LITEST_ANY);
2626 litest_add("pointer:accel", pointer_accel_invalid, LITEST_RELATIVE, LITEST_ANY);
2627 litest_add("pointer:accel", pointer_accel_defaults_absolute, LITEST_ABSOLUTE, LITEST_RELATIVE);
2628 litest_add("pointer:accel", pointer_accel_defaults_absolute_relative, LITEST_ABSOLUTE|LITEST_RELATIVE, LITEST_ANY);
2629 litest_add("pointer:accel", pointer_accel_direction_change, LITEST_RELATIVE, LITEST_POINTINGSTICK);
2630 litest_add("pointer:accel", pointer_accel_profile_defaults, LITEST_RELATIVE, LITEST_TOUCHPAD);
2631 litest_add("pointer:accel", pointer_accel_profile_defaults_noprofile, LITEST_TOUCHPAD, LITEST_ANY);
2632 litest_add("pointer:accel", pointer_accel_profile_invalid, LITEST_RELATIVE, LITEST_ANY);
2633 litest_add("pointer:accel", pointer_accel_profile_noaccel, LITEST_ANY, LITEST_TOUCHPAD|LITEST_RELATIVE|LITEST_TABLET);
2634 litest_add("pointer:accel", pointer_accel_profile_flat_motion_relative, LITEST_RELATIVE, LITEST_TOUCHPAD);
2635
2636 litest_add("pointer:middlebutton", middlebutton, LITEST_BUTTON, LITEST_CLICKPAD);
2637 litest_add("pointer:middlebutton", middlebutton_nostart_while_down, LITEST_BUTTON, LITEST_CLICKPAD);
2638 litest_add("pointer:middlebutton", middlebutton_timeout, LITEST_BUTTON, LITEST_CLICKPAD);
2639 litest_add("pointer:middlebutton", middlebutton_doubleclick, LITEST_BUTTON, LITEST_CLICKPAD);
2640 litest_add("pointer:middlebutton", middlebutton_middleclick, LITEST_BUTTON, LITEST_CLICKPAD);
2641 litest_add("pointer:middlebutton", middlebutton_middleclick_during, LITEST_BUTTON, LITEST_CLICKPAD);
2642 litest_add("pointer:middlebutton", middlebutton_default_enabled, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_POINTINGSTICK);
2643 litest_add("pointer:middlebutton", middlebutton_default_clickpad, LITEST_CLICKPAD, LITEST_ANY);
2644 litest_add("pointer:middlebutton", middlebutton_default_touchpad, LITEST_TOUCHPAD, LITEST_CLICKPAD);
2645 litest_add("pointer:middlebutton", middlebutton_default_disabled, LITEST_ANY, LITEST_BUTTON);
2646 litest_add_for_device("pointer:middlebutton", middlebutton_default_alps, LITEST_ALPS_SEMI_MT);
2647 litest_add("pointer:middlebutton", middlebutton_button_scrolling, LITEST_RELATIVE|LITEST_BUTTON, LITEST_CLICKPAD);
2648 litest_add("pointer:middlebutton", middlebutton_button_scrolling_middle, LITEST_RELATIVE|LITEST_BUTTON, LITEST_CLICKPAD);
2649
2650 litest_add_ranged("pointer:state", pointer_absolute_initial_state, LITEST_ABSOLUTE, LITEST_ANY, &axis_range);
2651
2652 litest_add("pointer:time", pointer_time_usec, LITEST_RELATIVE, LITEST_ANY);
2653
2654 litest_add_ranged("pointer:debounce", debounce_bounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, &buttons);
2655 litest_add("pointer:debounce", debounce_bounce_check_immediate, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
2656 litest_add_ranged("pointer:debounce", debounce_spurious, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, &buttons);
2657 litest_add("pointer:debounce", debounce_spurious_multibounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
2658 litest_add("pointer:debounce_otherbutton", debounce_spurious_dont_enable_on_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
2659 litest_add("pointer:debounce_otherbutton", debounce_spurious_cancel_debounce_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
2660 litest_add("pointer:debounce_otherbutton", debounce_spurious_switch_to_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
2661 litest_add_no_device("pointer:debounce", debounce_remove_device_button_down);
2662 litest_add_no_device("pointer:debounce", debounce_remove_device_button_up);
2663 }
2664