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