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