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