1/* 2 * Copyright © 2017 James Ye <jye836@gmail.com> 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 <fcntl.h> 28#include <libinput.h> 29 30#include "libinput-util.h" 31#include "litest.h" 32 33static inline bool 34switch_has_lid(struct litest_device *dev) 35{ 36 return libinput_device_switch_has_switch(dev->libinput_device, 37 LIBINPUT_SWITCH_LID) > 0; 38} 39 40static inline bool 41switch_has_tablet_mode(struct litest_device *dev) 42{ 43 return libinput_device_switch_has_switch(dev->libinput_device, 44 LIBINPUT_SWITCH_TABLET_MODE) > 0; 45} 46 47START_TEST(switch_has_cap) 48{ 49 struct litest_device *dev = litest_current_device(); 50 51 /* Need to check for this specific device here because the 52 * unreliable tablet mode switch removes the capability too */ 53 if (dev->which == LITEST_TABLET_MODE_UNRELIABLE) { 54 ck_assert(!libinput_device_has_capability(dev->libinput_device, 55 LIBINPUT_DEVICE_CAP_SWITCH)); 56 return; 57 } 58 59 ck_assert(libinput_device_has_capability(dev->libinput_device, 60 LIBINPUT_DEVICE_CAP_SWITCH)); 61 62} 63END_TEST 64 65START_TEST(switch_has_lid_switch) 66{ 67 struct litest_device *dev = litest_current_device(); 68 69 if (!libevdev_has_event_code(dev->evdev, EV_SW, SW_LID)) 70 return; 71 72 ck_assert_int_eq(libinput_device_switch_has_switch(dev->libinput_device, 73 LIBINPUT_SWITCH_LID), 74 1); 75} 76END_TEST 77 78static bool 79tablet_mode_switch_is_reliable(struct litest_device *dev) 80{ 81 bool is_unreliable = false; 82 83 quirks_get_bool(dev->quirks, 84 QUIRK_MODEL_TABLET_MODE_SWITCH_UNRELIABLE, 85 &is_unreliable); 86 87 return !is_unreliable; 88} 89 90START_TEST(switch_has_tablet_mode_switch) 91{ 92 struct litest_device *dev = litest_current_device(); 93 int has_switch; 94 95 if (!libevdev_has_event_code(dev->evdev, EV_SW, SW_TABLET_MODE)) 96 return; 97 98 has_switch = libinput_device_switch_has_switch(dev->libinput_device, 99 LIBINPUT_SWITCH_TABLET_MODE); 100 101 if (!tablet_mode_switch_is_reliable(dev)) 102 ck_assert_int_ne(has_switch, 1); 103 else 104 ck_assert_int_eq(has_switch, 1); 105} 106END_TEST 107 108START_TEST(switch_toggle) 109{ 110 struct litest_device *dev = litest_current_device(); 111 struct libinput *li = dev->libinput; 112 struct libinput_event *event; 113 enum libinput_switch sw = _i; /* ranged test */ 114 115 litest_drain_events(li); 116 117 litest_grab_device(dev); 118 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON); 119 libinput_dispatch(li); 120 121 if (libinput_device_switch_has_switch(dev->libinput_device, sw) > 0) { 122 event = libinput_get_event(li); 123 litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON); 124 libinput_event_destroy(event); 125 } else { 126 litest_assert_empty_queue(li); 127 } 128 129 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF); 130 libinput_dispatch(li); 131 132 if (libinput_device_switch_has_switch(dev->libinput_device, sw) > 0) { 133 event = libinput_get_event(li); 134 litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_OFF); 135 libinput_event_destroy(event); 136 } 137 138 litest_assert_empty_queue(li); 139 litest_ungrab_device(dev); 140} 141END_TEST 142 143START_TEST(switch_toggle_double) 144{ 145 struct litest_device *dev = litest_current_device(); 146 struct libinput *li = dev->libinput; 147 struct libinput_event *event; 148 enum libinput_switch sw = _i; /* ranged test */ 149 150 if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0) 151 return; 152 153 litest_drain_events(li); 154 155 litest_grab_device(dev); 156 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON); 157 libinput_dispatch(li); 158 159 event = libinput_get_event(li); 160 litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON); 161 libinput_event_destroy(event); 162 163 /* This will be filtered by the kernel, so this test is a bit 164 * useless */ 165 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON); 166 libinput_dispatch(li); 167 168 litest_assert_empty_queue(li); 169 litest_ungrab_device(dev); 170} 171END_TEST 172 173static bool 174lid_switch_is_reliable(struct litest_device *dev) 175{ 176 char *prop; 177 bool is_reliable = false; 178 179 if (quirks_get_string(dev->quirks, 180 QUIRK_ATTR_LID_SWITCH_RELIABILITY, 181 &prop)) { 182 is_reliable = streq(prop, "reliable"); 183 } 184 185 186 return is_reliable; 187} 188 189START_TEST(switch_down_on_init) 190{ 191 struct litest_device *dev = litest_current_device(); 192 struct libinput *li; 193 struct libinput_event *event; 194 enum libinput_switch sw = _i; /* ranged test */ 195 196 if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0) 197 return; 198 199 if (sw == LIBINPUT_SWITCH_LID && !lid_switch_is_reliable(dev)) 200 return; 201 202 litest_grab_device(dev); 203 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON); 204 litest_ungrab_device(dev); 205 206 /* need separate context to test */ 207 li = litest_create_context(); 208 libinput_path_add_device(li, 209 libevdev_uinput_get_devnode(dev->uinput)); 210 libinput_dispatch(li); 211 212 litest_wait_for_event_of_type(li, LIBINPUT_EVENT_SWITCH_TOGGLE, -1); 213 event = libinput_get_event(li); 214 litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON); 215 libinput_event_destroy(event); 216 217 while ((event = libinput_get_event(li))) { 218 ck_assert_int_ne(libinput_event_get_type(event), 219 LIBINPUT_EVENT_SWITCH_TOGGLE); 220 libinput_event_destroy(event); 221 } 222 223 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF); 224 libinput_dispatch(li); 225 event = libinput_get_event(li); 226 litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_OFF); 227 libinput_event_destroy(event); 228 litest_assert_empty_queue(li); 229 230 litest_destroy_context(li); 231} 232END_TEST 233 234START_TEST(switch_not_down_on_init) 235{ 236 struct litest_device *dev = litest_current_device(); 237 struct libinput *li; 238 struct libinput_event *event; 239 enum libinput_switch sw = LIBINPUT_SWITCH_LID; 240 241 if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0) 242 return; 243 244 if (sw == LIBINPUT_SWITCH_LID && lid_switch_is_reliable(dev)) 245 return; 246 247 litest_grab_device(dev); 248 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON); 249 litest_ungrab_device(dev); 250 251 /* need separate context to test */ 252 li = litest_create_context(); 253 libinput_path_add_device(li, 254 libevdev_uinput_get_devnode(dev->uinput)); 255 libinput_dispatch(li); 256 257 while ((event = libinput_get_event(li)) != NULL) { 258 ck_assert_int_ne(libinput_event_get_type(event), 259 LIBINPUT_EVENT_SWITCH_TOGGLE); 260 libinput_event_destroy(event); 261 } 262 263 litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF); 264 litest_assert_empty_queue(li); 265 litest_destroy_context(li); 266} 267END_TEST 268 269static inline struct litest_device * 270switch_init_paired_touchpad(struct libinput *li) 271{ 272 enum litest_device_type which = LITEST_SYNAPTICS_I2C; 273 274 return litest_add_device(li, which); 275} 276 277START_TEST(switch_disable_touchpad) 278{ 279 struct litest_device *sw = litest_current_device(); 280 struct litest_device *touchpad; 281 struct libinput *li = sw->libinput; 282 enum libinput_switch which = _i; /* ranged test */ 283 284 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0) 285 return; 286 287 touchpad = switch_init_paired_touchpad(li); 288 litest_disable_tap(touchpad->libinput_device); 289 litest_disable_hold_gestures(touchpad->libinput_device); 290 litest_drain_events(li); 291 292 litest_grab_device(sw); 293 294 /* switch is on - no events */ 295 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 296 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 297 298 litest_touch_down(touchpad, 0, 50, 50); 299 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 300 litest_touch_up(touchpad, 0); 301 litest_assert_empty_queue(li); 302 303 /* switch is off - motion events */ 304 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF); 305 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 306 307 litest_touch_down(touchpad, 0, 50, 50); 308 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 309 litest_touch_up(touchpad, 0); 310 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 311 312 litest_delete_device(touchpad); 313 litest_ungrab_device(sw); 314} 315END_TEST 316 317START_TEST(switch_disable_touchpad_during_touch) 318{ 319 struct litest_device *sw = litest_current_device(); 320 struct litest_device *touchpad; 321 struct libinput *li = sw->libinput; 322 enum libinput_switch which = _i; /* ranged test */ 323 324 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0) 325 return; 326 327 touchpad = switch_init_paired_touchpad(li); 328 litest_disable_tap(touchpad->libinput_device); 329 litest_disable_hold_gestures(touchpad->libinput_device); 330 litest_drain_events(li); 331 332 litest_touch_down(touchpad, 0, 50, 50); 333 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5); 334 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 335 336 litest_grab_device(sw); 337 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 338 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 339 litest_ungrab_device(sw); 340 341 litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 5); 342 litest_touch_up(touchpad, 0); 343 litest_assert_empty_queue(li); 344 345 litest_delete_device(touchpad); 346} 347END_TEST 348 349START_TEST(switch_disable_touchpad_edge_scroll) 350{ 351 struct litest_device *sw = litest_current_device(); 352 struct litest_device *touchpad; 353 struct libinput *li = sw->libinput; 354 enum libinput_switch which = _i; /* ranged test */ 355 356 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0) 357 return; 358 359 touchpad = switch_init_paired_touchpad(li); 360 litest_enable_edge_scroll(touchpad); 361 362 litest_drain_events(li); 363 364 litest_grab_device(sw); 365 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 366 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 367 litest_ungrab_device(sw); 368 369 litest_touch_down(touchpad, 0, 99, 20); 370 libinput_dispatch(li); 371 litest_timeout_edgescroll(); 372 libinput_dispatch(li); 373 litest_assert_empty_queue(li); 374 375 litest_touch_move_to(touchpad, 0, 99, 20, 99, 80, 60); 376 libinput_dispatch(li); 377 litest_assert_empty_queue(li); 378 379 litest_touch_move_to(touchpad, 0, 99, 80, 99, 20, 60); 380 litest_touch_up(touchpad, 0); 381 libinput_dispatch(li); 382 litest_assert_empty_queue(li); 383 384 litest_delete_device(touchpad); 385} 386END_TEST 387 388START_TEST(switch_disable_touchpad_edge_scroll_interrupt) 389{ 390 struct litest_device *sw = litest_current_device(); 391 struct litest_device *touchpad; 392 struct libinput *li = sw->libinput; 393 struct libinput_event *event; 394 enum libinput_switch which = _i; /* ranged test */ 395 396 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0) 397 return; 398 399 touchpad = switch_init_paired_touchpad(li); 400 litest_enable_edge_scroll(touchpad); 401 402 litest_drain_events(li); 403 404 litest_touch_down(touchpad, 0, 99, 20); 405 libinput_dispatch(li); 406 litest_timeout_edgescroll(); 407 litest_touch_move_to(touchpad, 0, 99, 20, 99, 30, 10); 408 libinput_dispatch(li); 409 litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER); 410 411 litest_grab_device(sw); 412 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 413 litest_ungrab_device(sw); 414 libinput_dispatch(li); 415 416 litest_assert_axis_end_sequence(li, 417 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 418 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 419 LIBINPUT_POINTER_AXIS_SOURCE_FINGER); 420 421 event = libinput_get_event(li); 422 litest_is_switch_event(event, which, LIBINPUT_SWITCH_STATE_ON); 423 libinput_event_destroy(event); 424 425 litest_delete_device(touchpad); 426} 427END_TEST 428 429START_TEST(switch_disable_touchpad_already_open) 430{ 431 struct litest_device *sw = litest_current_device(); 432 struct litest_device *touchpad; 433 struct libinput *li = sw->libinput; 434 enum libinput_switch which = _i; /* ranged test */ 435 436 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0) 437 return; 438 439 touchpad = switch_init_paired_touchpad(li); 440 441 litest_disable_tap(touchpad->libinput_device); 442 litest_disable_hold_gestures(touchpad->libinput_device); 443 litest_drain_events(li); 444 445 /* default: switch is off - motion events */ 446 litest_touch_down(touchpad, 0, 50, 50); 447 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 448 litest_touch_up(touchpad, 0); 449 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 450 451 /* disable switch - motion events */ 452 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF); 453 litest_assert_empty_queue(li); 454 455 litest_touch_down(touchpad, 0, 50, 50); 456 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 457 litest_touch_up(touchpad, 0); 458 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 459 460 litest_delete_device(touchpad); 461} 462END_TEST 463 464START_TEST(switch_dont_resume_disabled_touchpad) 465{ 466 struct litest_device *sw = litest_current_device(); 467 struct litest_device *touchpad; 468 struct libinput *li = sw->libinput; 469 enum libinput_switch which = _i; /* ranged test */ 470 471 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0) 472 return; 473 474 touchpad = switch_init_paired_touchpad(li); 475 litest_disable_tap(touchpad->libinput_device); 476 litest_disable_hold_gestures(touchpad->libinput_device); 477 libinput_device_config_send_events_set_mode(touchpad->libinput_device, 478 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); 479 litest_drain_events(li); 480 481 /* switch is on - no events */ 482 litest_grab_device(sw); 483 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 484 litest_ungrab_device(sw); 485 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 486 487 litest_touch_down(touchpad, 0, 50, 50); 488 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 489 litest_touch_up(touchpad, 0); 490 litest_assert_empty_queue(li); 491 492 /* switch is off but but tp is still disabled */ 493 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF); 494 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 495 496 litest_touch_down(touchpad, 0, 50, 50); 497 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 498 litest_touch_up(touchpad, 0); 499 litest_assert_empty_queue(li); 500 501 litest_delete_device(touchpad); 502} 503END_TEST 504 505START_TEST(switch_dont_resume_disabled_touchpad_external_mouse) 506{ 507 struct litest_device *sw = litest_current_device(); 508 struct litest_device *touchpad, *mouse; 509 struct libinput *li = sw->libinput; 510 enum libinput_switch which = _i; /* ranged test */ 511 512 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0) 513 return; 514 515 touchpad = switch_init_paired_touchpad(li); 516 mouse = litest_add_device(li, LITEST_MOUSE); 517 litest_disable_tap(touchpad->libinput_device); 518 litest_disable_hold_gestures(touchpad->libinput_device); 519 libinput_device_config_send_events_set_mode(touchpad->libinput_device, 520 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE); 521 litest_drain_events(li); 522 523 litest_touch_down(touchpad, 0, 50, 50); 524 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 525 litest_touch_up(touchpad, 0); 526 litest_assert_empty_queue(li); 527 528 /* switch is on - no events */ 529 litest_grab_device(sw); 530 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 531 litest_ungrab_device(sw); 532 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 533 534 litest_touch_down(touchpad, 0, 50, 50); 535 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 536 litest_touch_up(touchpad, 0); 537 litest_assert_empty_queue(li); 538 539 /* switch is off but but tp is still disabled */ 540 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF); 541 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 542 543 litest_touch_down(touchpad, 0, 50, 50); 544 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 545 litest_touch_up(touchpad, 0); 546 litest_assert_empty_queue(li); 547 548 litest_delete_device(touchpad); 549 litest_delete_device(mouse); 550} 551END_TEST 552 553START_TEST(lid_open_on_key) 554{ 555 struct litest_device *sw = litest_current_device(); 556 struct litest_device *keyboard; 557 struct libinput *li = sw->libinput; 558 struct libinput_event *event; 559 560 if (!switch_has_lid(sw)) 561 return; 562 563 keyboard = litest_add_device(li, LITEST_KEYBOARD); 564 565 litest_grab_device(sw); 566 for (int i = 0; i < 3; i++) { 567 litest_switch_action(sw, 568 LIBINPUT_SWITCH_LID, 569 LIBINPUT_SWITCH_STATE_ON); 570 litest_drain_events(li); 571 572 litest_event(keyboard, EV_KEY, KEY_A, 1); 573 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 574 litest_event(keyboard, EV_KEY, KEY_A, 0); 575 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 576 libinput_dispatch(li); 577 578 event = libinput_get_event(li); 579 litest_is_switch_event(event, 580 LIBINPUT_SWITCH_LID, 581 LIBINPUT_SWITCH_STATE_OFF); 582 libinput_event_destroy(event); 583 584 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY); 585 586 litest_switch_action(sw, 587 LIBINPUT_SWITCH_LID, 588 LIBINPUT_SWITCH_STATE_OFF); 589 litest_assert_empty_queue(li); 590 } 591 litest_ungrab_device(sw); 592 593 litest_delete_device(keyboard); 594} 595END_TEST 596 597START_TEST(lid_open_on_key_touchpad_enabled) 598{ 599 struct litest_device *sw = litest_current_device(); 600 struct litest_device *keyboard, *touchpad; 601 struct libinput *li = sw->libinput; 602 603 if (!switch_has_lid(sw)) 604 return; 605 606 keyboard = litest_add_device(li, LITEST_KEYBOARD); 607 touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C); 608 609 litest_disable_hold_gestures(touchpad->libinput_device); 610 611 litest_grab_device(sw); 612 litest_switch_action(sw, 613 LIBINPUT_SWITCH_LID, 614 LIBINPUT_SWITCH_STATE_ON); 615 litest_ungrab_device(sw); 616 litest_drain_events(li); 617 618 litest_event(keyboard, EV_KEY, KEY_A, 1); 619 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 620 litest_event(keyboard, EV_KEY, KEY_A, 0); 621 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 622 litest_drain_events(li); 623 litest_timeout_dwt_long(); 624 625 litest_touch_down(touchpad, 0, 50, 50); 626 litest_touch_move_to(touchpad, 0, 50, 50, 70, 70, 10); 627 litest_touch_up(touchpad, 0); 628 libinput_dispatch(li); 629 630 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 631 632 litest_delete_device(keyboard); 633 litest_delete_device(touchpad); 634} 635END_TEST 636 637START_TEST(switch_suspend_with_keyboard) 638{ 639 struct libinput *li; 640 struct litest_device *keyboard; 641 struct litest_device *sw; 642 enum libinput_switch which = _i; /* ranged test */ 643 644 li = litest_create_context(); 645 646 switch(which) { 647 case LIBINPUT_SWITCH_LID: 648 sw = litest_add_device(li, LITEST_LID_SWITCH); 649 break; 650 case LIBINPUT_SWITCH_TABLET_MODE: 651 sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS); 652 break; 653 default: 654 abort(); 655 } 656 657 libinput_dispatch(li); 658 659 keyboard = litest_add_device(li, LITEST_KEYBOARD); 660 libinput_dispatch(li); 661 662 litest_grab_device(sw); 663 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 664 litest_drain_events(li); 665 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF); 666 litest_drain_events(li); 667 litest_ungrab_device(sw); 668 669 litest_delete_device(keyboard); 670 litest_drain_events(li); 671 672 litest_delete_device(sw); 673 libinput_dispatch(li); 674 675 litest_destroy_context(li); 676} 677END_TEST 678 679START_TEST(switch_suspend_with_touchpad) 680{ 681 struct libinput *li; 682 struct litest_device *touchpad, *sw; 683 enum libinput_switch which = _i; /* ranged test */ 684 685 li = litest_create_context(); 686 687 switch(which) { 688 case LIBINPUT_SWITCH_LID: 689 sw = litest_add_device(li, LITEST_LID_SWITCH); 690 break; 691 case LIBINPUT_SWITCH_TABLET_MODE: 692 sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS); 693 break; 694 default: 695 abort(); 696 } 697 698 litest_drain_events(li); 699 700 touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C); 701 litest_drain_events(li); 702 703 litest_grab_device(sw); 704 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON); 705 litest_drain_events(li); 706 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF); 707 litest_drain_events(li); 708 litest_ungrab_device(sw); 709 710 litest_delete_device(sw); 711 litest_drain_events(li); 712 litest_delete_device(touchpad); 713 litest_drain_events(li); 714 715 litest_destroy_context(li); 716} 717END_TEST 718 719START_TEST(lid_update_hw_on_key) 720{ 721 struct litest_device *sw = litest_current_device(); 722 struct libinput *li = sw->libinput; 723 struct litest_device *keyboard; 724 struct libevdev *evdev; 725 struct input_event event; 726 int fd; 727 int rc; 728 729 if (!switch_has_lid(sw)) 730 return; 731 732 keyboard = litest_add_device(li, LITEST_KEYBOARD); 733 734 litest_grab_device(sw); 735 litest_switch_action(sw, 736 LIBINPUT_SWITCH_LID, 737 LIBINPUT_SWITCH_STATE_ON); 738 litest_drain_events(li); 739 litest_ungrab_device(sw); 740 741 /* Separate direct libevdev context to check if the HW event goes 742 * through */ 743 fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK); 744 ck_assert_int_ge(fd, 0); 745 ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0); 746 ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1); 747 748 /* Typing on the keyboard should trigger a lid open event */ 749 litest_event(keyboard, EV_KEY, KEY_A, 1); 750 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 751 litest_event(keyboard, EV_KEY, KEY_A, 0); 752 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 753 litest_drain_events(li); 754 755 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 756 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); 757 ck_assert_int_eq(event.type, EV_SW); 758 ck_assert_int_eq(event.code, SW_LID); 759 ck_assert_int_eq(event.value, 0); 760 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 761 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); 762 ck_assert_int_eq(event.type, EV_SYN); 763 ck_assert_int_eq(event.code, SYN_REPORT); 764 ck_assert_int_eq(event.value, 0); 765 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 766 ck_assert_int_eq(rc, -EAGAIN); 767 768 litest_delete_device(keyboard); 769 close(fd); 770 libevdev_free(evdev); 771} 772END_TEST 773 774START_TEST(lid_update_hw_on_key_closed_on_init) 775{ 776 struct litest_device *sw = litest_current_device(); 777 struct libinput *li; 778 struct litest_device *keyboard; 779 struct libevdev *evdev = sw->evdev; 780 struct input_event event; 781 int fd; 782 int rc; 783 784 litest_grab_device(sw); 785 litest_switch_action(sw, 786 LIBINPUT_SWITCH_LID, 787 LIBINPUT_SWITCH_STATE_ON); 788 litest_ungrab_device(sw); 789 790 /* Separate direct libevdev context to check if the HW event goes 791 * through */ 792 fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK); 793 ck_assert_int_ge(fd, 0); 794 ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0); 795 ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1); 796 797 keyboard = litest_add_device(sw->libinput, LITEST_KEYBOARD); 798 799 /* separate context for the right state on init */ 800 li = litest_create_context(); 801 libinput_path_add_device(li, 802 libevdev_uinput_get_devnode(sw->uinput)); 803 libinput_path_add_device(li, 804 libevdev_uinput_get_devnode(keyboard->uinput)); 805 806 /* don't expect a switch waiting for us, this is run for an 807 * unreliable device */ 808 while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) { 809 ck_assert_int_ne(libinput_next_event_type(li), 810 LIBINPUT_EVENT_SWITCH_TOGGLE); 811 libinput_event_destroy(libinput_get_event(li)); 812 } 813 814 litest_event(keyboard, EV_KEY, KEY_A, 1); 815 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 816 litest_event(keyboard, EV_KEY, KEY_A, 0); 817 litest_event(keyboard, EV_SYN, SYN_REPORT, 0); 818 /* No switch event, we're still in vanilla (open) state */ 819 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY); 820 821 /* Make sure kernel state has updated */ 822 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 823 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); 824 ck_assert_int_eq(event.type, EV_SW); 825 ck_assert_int_eq(event.code, SW_LID); 826 ck_assert_int_eq(event.value, 0); 827 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 828 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); 829 ck_assert_int_eq(event.type, EV_SYN); 830 ck_assert_int_eq(event.code, SYN_REPORT); 831 ck_assert_int_eq(event.value, 0); 832 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 833 ck_assert_int_eq(rc, -EAGAIN); 834 835 litest_destroy_context(li); 836 litest_delete_device(keyboard); 837 close(fd); 838 libevdev_free(evdev); 839} 840END_TEST 841 842START_TEST(lid_update_hw_on_key_multiple_keyboards) 843{ 844 struct litest_device *sw = litest_current_device(); 845 struct libinput *li = sw->libinput; 846 struct litest_device *keyboard1, *keyboard2; 847 struct libevdev *evdev = sw->evdev; 848 struct input_event event; 849 int fd; 850 int rc; 851 852 if (!switch_has_lid(sw)) 853 return; 854 855 keyboard1 = litest_add_device(li, 856 LITEST_KEYBOARD_BLADE_STEALTH_VIDEOSWITCH); 857 libinput_dispatch(li); 858 859 keyboard2 = litest_add_device(li, LITEST_KEYBOARD_BLADE_STEALTH); 860 libinput_dispatch(li); 861 862 litest_grab_device(sw); 863 litest_switch_action(sw, 864 LIBINPUT_SWITCH_LID, 865 LIBINPUT_SWITCH_STATE_ON); 866 litest_drain_events(li); 867 litest_ungrab_device(sw); 868 869 /* Separate direct libevdev context to check if the HW event goes 870 * through */ 871 fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK); 872 ck_assert_int_ge(fd, 0); 873 ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0); 874 ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1); 875 876 /* Typing on the second keyboard should trigger a lid open event */ 877 litest_event(keyboard2, EV_KEY, KEY_A, 1); 878 litest_event(keyboard2, EV_SYN, SYN_REPORT, 0); 879 litest_event(keyboard2, EV_KEY, KEY_A, 0); 880 litest_event(keyboard2, EV_SYN, SYN_REPORT, 0); 881 litest_drain_events(li); 882 883 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 884 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); 885 ck_assert_int_eq(event.type, EV_SW); 886 ck_assert_int_eq(event.code, SW_LID); 887 ck_assert_int_eq(event.value, 0); 888 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 889 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS); 890 ck_assert_int_eq(event.type, EV_SYN); 891 ck_assert_int_eq(event.code, SYN_REPORT); 892 ck_assert_int_eq(event.value, 0); 893 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event); 894 ck_assert_int_eq(rc, -EAGAIN); 895 896 litest_delete_device(keyboard1); 897 litest_delete_device(keyboard2); 898 close(fd); 899 libevdev_free(evdev); 900} 901END_TEST 902 903START_TEST(lid_key_press) 904{ 905 struct litest_device *sw = litest_current_device(); 906 struct libinput *li = sw->libinput; 907 908 litest_drain_events(li); 909 910 litest_keyboard_key(sw, KEY_VOLUMEUP, true); 911 litest_keyboard_key(sw, KEY_VOLUMEUP, false); 912 libinput_dispatch(li); 913 914 /* Check that we're routing key events from a lid device too */ 915 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY); 916} 917END_TEST 918 919START_TEST(tablet_mode_disable_touchpad_on_init) 920{ 921 struct litest_device *sw = litest_current_device(); 922 struct litest_device *touchpad; 923 struct libinput *li = sw->libinput; 924 925 if (!switch_has_tablet_mode(sw)) 926 return; 927 928 litest_grab_device(sw); 929 litest_switch_action(sw, 930 LIBINPUT_SWITCH_TABLET_MODE, 931 LIBINPUT_SWITCH_STATE_ON); 932 litest_drain_events(li); 933 934 /* touchpad comes with switch already on - no events */ 935 touchpad = switch_init_paired_touchpad(li); 936 litest_disable_tap(touchpad->libinput_device); 937 litest_disable_hold_gestures(touchpad->libinput_device); 938 litest_drain_events(li); 939 940 litest_touch_down(touchpad, 0, 50, 50); 941 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 942 litest_touch_up(touchpad, 0); 943 litest_assert_empty_queue(li); 944 945 litest_switch_action(sw, 946 LIBINPUT_SWITCH_TABLET_MODE, 947 LIBINPUT_SWITCH_STATE_OFF); 948 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 949 950 litest_touch_down(touchpad, 0, 50, 50); 951 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 952 litest_touch_up(touchpad, 0); 953 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 954 litest_ungrab_device(sw); 955 956 litest_delete_device(touchpad); 957} 958END_TEST 959 960START_TEST(tablet_mode_disable_touchpad_on_resume) 961{ 962 struct litest_device *sw = litest_current_device(); 963 struct litest_device *touchpad; 964 struct libinput *li = sw->libinput; 965 struct libinput_event *event; 966 bool have_switch_toggle = false; 967 968 if (!switch_has_tablet_mode(sw)) 969 return; 970 971 touchpad = switch_init_paired_touchpad(li); 972 litest_disable_tap(touchpad->libinput_device); 973 litest_disable_hold_gestures(touchpad->libinput_device); 974 litest_drain_events(li); 975 976 libinput_suspend(li); 977 litest_switch_action(sw, 978 LIBINPUT_SWITCH_TABLET_MODE, 979 LIBINPUT_SWITCH_STATE_ON); 980 litest_drain_events(li); 981 libinput_resume(li); 982 libinput_dispatch(li); 983 984 while ((event = libinput_get_event(li))) { 985 enum libinput_event_type type; 986 987 type = libinput_event_get_type(event); 988 switch (type) { 989 case LIBINPUT_EVENT_DEVICE_ADDED: 990 break; 991 case LIBINPUT_EVENT_SWITCH_TOGGLE: 992 litest_is_switch_event(event, 993 LIBINPUT_SWITCH_TABLET_MODE, 994 LIBINPUT_SWITCH_STATE_ON); 995 have_switch_toggle = true; 996 break; 997 default: 998 ck_abort(); 999 } 1000 libinput_event_destroy(event); 1001 } 1002 1003 ck_assert(have_switch_toggle); 1004 1005 litest_touch_down(touchpad, 0, 50, 50); 1006 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 1007 litest_touch_up(touchpad, 0); 1008 litest_assert_empty_queue(li); 1009 1010 litest_switch_action(sw, 1011 LIBINPUT_SWITCH_TABLET_MODE, 1012 LIBINPUT_SWITCH_STATE_OFF); 1013 libinput_dispatch(li); 1014 event = libinput_get_event(li); 1015 litest_is_switch_event(event, 1016 LIBINPUT_SWITCH_TABLET_MODE, 1017 LIBINPUT_SWITCH_STATE_OFF); 1018 libinput_event_destroy(event); 1019 1020 litest_touch_down(touchpad, 0, 50, 50); 1021 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 1022 litest_touch_up(touchpad, 0); 1023 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 1024 1025 litest_delete_device(touchpad); 1026} 1027END_TEST 1028 1029START_TEST(tablet_mode_enable_touchpad_on_resume) 1030{ 1031 struct litest_device *sw = litest_current_device(); 1032 struct litest_device *touchpad; 1033 struct libinput *li = sw->libinput; 1034 struct libinput_event *event; 1035 1036 if (!switch_has_tablet_mode(sw)) 1037 return; 1038 1039 touchpad = switch_init_paired_touchpad(li); 1040 litest_disable_tap(touchpad->libinput_device); 1041 litest_drain_events(li); 1042 1043 litest_switch_action(sw, 1044 LIBINPUT_SWITCH_TABLET_MODE, 1045 LIBINPUT_SWITCH_STATE_ON); 1046 libinput_suspend(li); 1047 litest_drain_events(li); 1048 1049 litest_switch_action(sw, 1050 LIBINPUT_SWITCH_TABLET_MODE, 1051 LIBINPUT_SWITCH_STATE_OFF); 1052 1053 libinput_resume(li); 1054 libinput_dispatch(li); 1055 1056 litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED); 1057 1058 litest_touch_down(touchpad, 0, 50, 50); 1059 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 1060 litest_touch_up(touchpad, 0); 1061 litest_drain_events_of_type(li, 1062 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, 1063 LIBINPUT_EVENT_GESTURE_HOLD_END, 1064 -1); 1065 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 1066 1067 litest_switch_action(sw, 1068 LIBINPUT_SWITCH_TABLET_MODE, 1069 LIBINPUT_SWITCH_STATE_ON); 1070 libinput_dispatch(li); 1071 event = libinput_get_event(li); 1072 litest_is_switch_event(event, 1073 LIBINPUT_SWITCH_TABLET_MODE, 1074 LIBINPUT_SWITCH_STATE_ON); 1075 libinput_event_destroy(event); 1076 1077 litest_touch_down(touchpad, 0, 50, 50); 1078 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10); 1079 litest_touch_up(touchpad, 0); 1080 litest_assert_empty_queue(li); 1081 1082 litest_delete_device(touchpad); 1083} 1084END_TEST 1085 1086START_TEST(tablet_mode_disable_keyboard) 1087{ 1088 struct litest_device *sw = litest_current_device(); 1089 struct litest_device *keyboard; 1090 struct libinput *li = sw->libinput; 1091 1092 if (!switch_has_tablet_mode(sw)) 1093 return; 1094 1095 keyboard = litest_add_device(li, LITEST_KEYBOARD); 1096 litest_drain_events(li); 1097 1098 litest_keyboard_key(keyboard, KEY_A, true); 1099 litest_keyboard_key(keyboard, KEY_A, false); 1100 litest_keyboard_key(keyboard, KEY_B, true); /* KEY_B down but not up */ 1101 libinput_dispatch(li); 1102 1103 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED); 1104 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED); 1105 litest_assert_key_event(li, KEY_B, LIBINPUT_KEY_STATE_PRESSED); /* KEY_B down but not up */ 1106 1107 litest_switch_action(sw, 1108 LIBINPUT_SWITCH_TABLET_MODE, 1109 LIBINPUT_SWITCH_STATE_ON); 1110 1111 /* The key currently down must be released */ 1112 litest_assert_key_event(li, KEY_B, LIBINPUT_KEY_STATE_RELEASED); 1113 litest_assert_switch_event(li, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_ON); 1114 litest_assert_empty_queue(li); 1115 1116 litest_keyboard_key(keyboard, KEY_B, false); /* release the kernel device */ 1117 litest_keyboard_key(keyboard, KEY_A, true); 1118 litest_keyboard_key(keyboard, KEY_A, false); 1119 litest_assert_empty_queue(li); 1120 1121 litest_switch_action(sw, 1122 LIBINPUT_SWITCH_TABLET_MODE, 1123 LIBINPUT_SWITCH_STATE_OFF); 1124 litest_assert_switch_event(li, LIBINPUT_SWITCH_TABLET_MODE, LIBINPUT_SWITCH_STATE_OFF); 1125 1126 litest_keyboard_key(keyboard, KEY_A, true); 1127 litest_keyboard_key(keyboard, KEY_A, false); 1128 litest_keyboard_key(keyboard, KEY_B, true); 1129 litest_keyboard_key(keyboard, KEY_B, false); 1130 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED); 1131 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED); 1132 litest_assert_key_event(li, KEY_B, LIBINPUT_KEY_STATE_PRESSED); 1133 litest_assert_key_event(li, KEY_B, LIBINPUT_KEY_STATE_RELEASED); 1134 1135 litest_delete_device(keyboard); 1136} 1137END_TEST 1138 1139START_TEST(tablet_mode_disable_keyboard_on_init) 1140{ 1141 struct litest_device *sw = litest_current_device(); 1142 struct litest_device *keyboard; 1143 struct libinput *li = sw->libinput; 1144 1145 if (!switch_has_tablet_mode(sw)) 1146 return; 1147 1148 litest_switch_action(sw, 1149 LIBINPUT_SWITCH_TABLET_MODE, 1150 LIBINPUT_SWITCH_STATE_ON); 1151 litest_drain_events(li); 1152 1153 /* keyboard comes with switch already on - no events */ 1154 keyboard = litest_add_device(li, LITEST_KEYBOARD); 1155 litest_drain_events(li); 1156 1157 litest_keyboard_key(keyboard, KEY_A, true); 1158 litest_keyboard_key(keyboard, KEY_A, false); 1159 litest_assert_empty_queue(li); 1160 1161 litest_switch_action(sw, 1162 LIBINPUT_SWITCH_TABLET_MODE, 1163 LIBINPUT_SWITCH_STATE_OFF); 1164 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 1165 1166 litest_keyboard_key(keyboard, KEY_A, true); 1167 litest_keyboard_key(keyboard, KEY_A, false); 1168 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY); 1169 1170 litest_delete_device(keyboard); 1171} 1172END_TEST 1173 1174START_TEST(tablet_mode_disable_keyboard_on_resume) 1175{ 1176 struct litest_device *sw = litest_current_device(); 1177 struct litest_device *keyboard; 1178 struct libinput *li = sw->libinput; 1179 struct libinput_event *event; 1180 bool have_switch_toggle = false; 1181 1182 if (!switch_has_tablet_mode(sw)) 1183 return; 1184 1185 keyboard = litest_add_device(li, LITEST_KEYBOARD); 1186 litest_drain_events(li); 1187 libinput_suspend(li); 1188 1189 /* We cannot grab this device because libinput doesn't have an open 1190 * fd to this device, we need an independent grab. 1191 */ 1192 libevdev_grab(sw->evdev, LIBEVDEV_GRAB); 1193 litest_switch_action(sw, 1194 LIBINPUT_SWITCH_TABLET_MODE, 1195 LIBINPUT_SWITCH_STATE_ON); 1196 libevdev_grab(sw->evdev, LIBEVDEV_UNGRAB); 1197 litest_drain_events(li); 1198 1199 libinput_resume(li); 1200 libinput_dispatch(li); 1201 1202 while ((event = libinput_get_event(li))) { 1203 enum libinput_event_type type; 1204 1205 type = libinput_event_get_type(event); 1206 switch (type) { 1207 case LIBINPUT_EVENT_DEVICE_ADDED: 1208 break; 1209 case LIBINPUT_EVENT_SWITCH_TOGGLE: 1210 litest_is_switch_event(event, 1211 LIBINPUT_SWITCH_TABLET_MODE, 1212 LIBINPUT_SWITCH_STATE_ON); 1213 have_switch_toggle = true; 1214 break; 1215 default: 1216 ck_abort(); 1217 } 1218 libinput_event_destroy(event); 1219 } 1220 1221 ck_assert(have_switch_toggle); 1222 1223 litest_keyboard_key(keyboard, KEY_A, true); 1224 litest_keyboard_key(keyboard, KEY_A, false); 1225 litest_assert_empty_queue(li); 1226 1227 litest_grab_device(sw); 1228 litest_switch_action(sw, 1229 LIBINPUT_SWITCH_TABLET_MODE, 1230 LIBINPUT_SWITCH_STATE_OFF); 1231 litest_ungrab_device(sw); 1232 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 1233 1234 litest_keyboard_key(keyboard, KEY_A, true); 1235 litest_keyboard_key(keyboard, KEY_A, false); 1236 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY); 1237 1238 litest_delete_device(keyboard); 1239} 1240END_TEST 1241 1242START_TEST(tablet_mode_enable_keyboard_on_resume) 1243{ 1244 struct litest_device *sw = litest_current_device(); 1245 struct litest_device *keyboard; 1246 struct libinput *li = sw->libinput; 1247 1248 if (!switch_has_tablet_mode(sw)) 1249 return; 1250 1251 keyboard = litest_add_device(li, LITEST_KEYBOARD); 1252 litest_grab_device(sw); 1253 litest_switch_action(sw, 1254 LIBINPUT_SWITCH_TABLET_MODE, 1255 LIBINPUT_SWITCH_STATE_ON); 1256 litest_drain_events(li); 1257 litest_ungrab_device(sw); 1258 libinput_suspend(li); 1259 litest_drain_events(li); 1260 1261 litest_switch_action(sw, 1262 LIBINPUT_SWITCH_TABLET_MODE, 1263 LIBINPUT_SWITCH_STATE_OFF); 1264 1265 libinput_resume(li); 1266 libinput_dispatch(li); 1267 litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED); 1268 1269 litest_keyboard_key(keyboard, KEY_A, true); 1270 litest_keyboard_key(keyboard, KEY_A, false); 1271 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY); 1272 1273 litest_switch_action(sw, 1274 LIBINPUT_SWITCH_TABLET_MODE, 1275 LIBINPUT_SWITCH_STATE_ON); 1276 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 1277 1278 litest_keyboard_key(keyboard, KEY_A, true); 1279 litest_keyboard_key(keyboard, KEY_A, false); 1280 litest_assert_empty_queue(li); 1281 1282 litest_delete_device(keyboard); 1283} 1284END_TEST 1285 1286START_TEST(tablet_mode_disable_trackpoint) 1287{ 1288 struct litest_device *sw = litest_current_device(); 1289 struct litest_device *trackpoint; 1290 struct libinput *li = sw->libinput; 1291 1292 if (!switch_has_tablet_mode(sw)) 1293 return; 1294 1295 trackpoint = litest_add_device(li, LITEST_TRACKPOINT); 1296 litest_drain_events(li); 1297 1298 litest_event(trackpoint, EV_REL, REL_Y, -1); 1299 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1300 litest_event(trackpoint, EV_REL, REL_Y, -1); 1301 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1302 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 1303 1304 litest_grab_device(sw); 1305 litest_switch_action(sw, 1306 LIBINPUT_SWITCH_TABLET_MODE, 1307 LIBINPUT_SWITCH_STATE_ON); 1308 litest_drain_events(li); 1309 1310 litest_event(trackpoint, EV_REL, REL_Y, -1); 1311 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1312 litest_event(trackpoint, EV_REL, REL_Y, -1); 1313 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1314 litest_assert_empty_queue(li); 1315 1316 litest_switch_action(sw, 1317 LIBINPUT_SWITCH_TABLET_MODE, 1318 LIBINPUT_SWITCH_STATE_OFF); 1319 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 1320 1321 litest_event(trackpoint, EV_REL, REL_Y, -1); 1322 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1323 litest_event(trackpoint, EV_REL, REL_Y, -1); 1324 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1325 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 1326 litest_ungrab_device(sw); 1327 1328 litest_delete_device(trackpoint); 1329} 1330END_TEST 1331 1332START_TEST(tablet_mode_disable_trackpoint_on_init) 1333{ 1334 struct litest_device *sw = litest_current_device(); 1335 struct litest_device *trackpoint; 1336 struct libinput *li = sw->libinput; 1337 1338 if (!switch_has_tablet_mode(sw)) 1339 return; 1340 1341 litest_grab_device(sw); 1342 litest_switch_action(sw, 1343 LIBINPUT_SWITCH_TABLET_MODE, 1344 LIBINPUT_SWITCH_STATE_ON); 1345 litest_drain_events(li); 1346 1347 /* trackpoint comes with switch already on - no events */ 1348 trackpoint = litest_add_device(li, LITEST_TRACKPOINT); 1349 litest_drain_events(li); 1350 1351 litest_event(trackpoint, EV_REL, REL_Y, -1); 1352 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1353 litest_event(trackpoint, EV_REL, REL_Y, -1); 1354 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1355 litest_assert_empty_queue(li); 1356 1357 litest_switch_action(sw, 1358 LIBINPUT_SWITCH_TABLET_MODE, 1359 LIBINPUT_SWITCH_STATE_OFF); 1360 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE); 1361 1362 litest_event(trackpoint, EV_REL, REL_Y, -1); 1363 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1364 litest_event(trackpoint, EV_REL, REL_Y, -1); 1365 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); 1366 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); 1367 litest_ungrab_device(sw); 1368 1369 litest_delete_device(trackpoint); 1370} 1371END_TEST 1372 1373START_TEST(dock_toggle) 1374{ 1375 struct litest_device *sw = litest_current_device(); 1376 struct libinput *li = sw->libinput; 1377 1378 if (!libevdev_has_event_code(sw->evdev, EV_SW, SW_DOCK)) 1379 return; 1380 1381 litest_drain_events(li); 1382 1383 litest_grab_device(sw); 1384 litest_event(sw, EV_SW, SW_DOCK, 1); 1385 libinput_dispatch(li); 1386 1387 litest_event(sw, EV_SW, SW_DOCK, 0); 1388 libinput_dispatch(li); 1389 litest_ungrab_device(sw); 1390 1391 litest_assert_empty_queue(li); 1392} 1393END_TEST 1394 1395TEST_COLLECTION(switch) 1396{ 1397 struct range switches = { LIBINPUT_SWITCH_LID, 1398 LIBINPUT_SWITCH_TABLET_MODE + 1}; 1399 1400 litest_add(switch_has_cap, LITEST_SWITCH, LITEST_ANY); 1401 litest_add(switch_has_lid_switch, LITEST_SWITCH, LITEST_ANY); 1402 litest_add(switch_has_tablet_mode_switch, LITEST_SWITCH, LITEST_ANY); 1403 litest_add_ranged(switch_toggle, LITEST_SWITCH, LITEST_ANY, &switches); 1404 litest_add_ranged(switch_toggle_double, LITEST_SWITCH, LITEST_ANY, &switches); 1405 litest_add_ranged(switch_down_on_init, LITEST_SWITCH, LITEST_ANY, &switches); 1406 litest_add(switch_not_down_on_init, LITEST_SWITCH, LITEST_ANY); 1407 litest_add_ranged(switch_disable_touchpad, LITEST_SWITCH, LITEST_ANY, &switches); 1408 litest_add_ranged(switch_disable_touchpad_during_touch, LITEST_SWITCH, LITEST_ANY, &switches); 1409 litest_add_ranged(switch_disable_touchpad_edge_scroll, LITEST_SWITCH, LITEST_ANY, &switches); 1410 litest_add_ranged(switch_disable_touchpad_edge_scroll_interrupt, LITEST_SWITCH, LITEST_ANY, &switches); 1411 litest_add_ranged(switch_disable_touchpad_already_open, LITEST_SWITCH, LITEST_ANY, &switches); 1412 litest_add_ranged(switch_dont_resume_disabled_touchpad, LITEST_SWITCH, LITEST_ANY, &switches); 1413 litest_add_ranged(switch_dont_resume_disabled_touchpad_external_mouse, LITEST_SWITCH, LITEST_ANY, &switches); 1414 1415 litest_add_ranged_no_device(switch_suspend_with_keyboard, &switches); 1416 litest_add_ranged_no_device(switch_suspend_with_touchpad, &switches); 1417 1418 litest_add(lid_open_on_key, LITEST_SWITCH, LITEST_ANY); 1419 litest_add(lid_open_on_key_touchpad_enabled, LITEST_SWITCH, LITEST_ANY); 1420 litest_add_for_device(lid_update_hw_on_key, LITEST_LID_SWITCH_SURFACE3); 1421 litest_add_for_device(lid_update_hw_on_key_closed_on_init, LITEST_LID_SWITCH_SURFACE3); 1422 litest_add_for_device(lid_update_hw_on_key_multiple_keyboards, LITEST_LID_SWITCH_SURFACE3); 1423 litest_add_for_device(lid_key_press, LITEST_GPIO_KEYS); 1424 1425 litest_add(tablet_mode_disable_touchpad_on_init, LITEST_SWITCH, LITEST_ANY); 1426 litest_add(tablet_mode_disable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY); 1427 litest_add(tablet_mode_enable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY); 1428 litest_add(tablet_mode_disable_keyboard, LITEST_SWITCH, LITEST_ANY); 1429 litest_add(tablet_mode_disable_keyboard_on_init, LITEST_SWITCH, LITEST_ANY); 1430 litest_add(tablet_mode_disable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY); 1431 litest_add(tablet_mode_enable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY); 1432 litest_add(tablet_mode_disable_trackpoint, LITEST_SWITCH, LITEST_ANY); 1433 litest_add(tablet_mode_disable_trackpoint_on_init, LITEST_SWITCH, LITEST_ANY); 1434 1435 litest_add(dock_toggle, LITEST_SWITCH, LITEST_ANY); 1436} 1437