1/* 2 * Copyright © 2013 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include <config.h> 25 26#include <check.h> 27#include <errno.h> 28#include <fcntl.h> 29#include <libinput.h> 30#include <stdio.h> 31#include <sys/stat.h> 32#include <unistd.h> 33 34#include "litest.h" 35#include "libinput-util.h" 36 37struct counter { 38 int open_func_count; 39 int close_func_count; 40}; 41 42static int 43open_restricted_count(const char *path, int flags, void *data) 44{ 45 struct counter *c = data; 46 int fd; 47 48 c->open_func_count++; 49 50 fd = open(path, flags); 51 return fd < 0 ? -errno : fd; 52} 53 54static void 55close_restricted_count(int fd, void *data) 56{ 57 struct counter *c = data; 58 59 c->close_func_count++; 60 close(fd); 61} 62 63static const struct libinput_interface counting_interface = { 64 .open_restricted = open_restricted_count, 65 .close_restricted = close_restricted_count, 66}; 67 68static int 69open_restricted(const char *path, int flags, void *data) 70{ 71 int fd = open(path, flags); 72 return fd < 0 ? -errno : fd; 73} 74 75static void 76close_restricted(int fd, void *data) 77{ 78 close(fd); 79} 80 81static const struct libinput_interface simple_interface = { 82 .open_restricted = open_restricted, 83 .close_restricted = close_restricted, 84}; 85 86START_TEST(path_create_NULL) 87{ 88 struct libinput *li; 89 struct counter counter; 90 91 counter.open_func_count = 0; 92 counter.close_func_count = 0; 93 94 li = libinput_path_create_context(NULL, NULL); 95 ck_assert(li == NULL); 96 li = libinput_path_create_context(&counting_interface, &counter); 97 ck_assert_notnull(li); 98 libinput_unref(li); 99 100 ck_assert_int_eq(counter.open_func_count, 0); 101 ck_assert_int_eq(counter.close_func_count, 0); 102} 103END_TEST 104 105START_TEST(path_create_invalid) 106{ 107 struct libinput *li; 108 struct libinput_device *device; 109 const char *path = "/tmp"; 110 struct counter counter; 111 112 counter.open_func_count = 0; 113 counter.close_func_count = 0; 114 115 li = libinput_path_create_context(&counting_interface, &counter); 116 ck_assert_notnull(li); 117 118 litest_disable_log_handler(li); 119 120 device = libinput_path_add_device(li, path); 121 ck_assert(device == NULL); 122 123 ck_assert_int_eq(counter.open_func_count, 0); 124 ck_assert_int_eq(counter.close_func_count, 0); 125 126 litest_restore_log_handler(li); 127 libinput_unref(li); 128 ck_assert_int_eq(counter.close_func_count, 0); 129} 130END_TEST 131 132START_TEST(path_create_invalid_kerneldev) 133{ 134 struct libinput *li; 135 struct libinput_device *device; 136 const char *path = "/dev/uinput"; 137 struct counter counter; 138 139 counter.open_func_count = 0; 140 counter.close_func_count = 0; 141 142 li = libinput_path_create_context(&counting_interface, &counter); 143 ck_assert_notnull(li); 144 145 litest_disable_log_handler(li); 146 147 device = libinput_path_add_device(li, path); 148 ck_assert(device == NULL); 149 150 ck_assert_int_eq(counter.open_func_count, 1); 151 ck_assert_int_eq(counter.close_func_count, 1); 152 153 litest_restore_log_handler(li); 154 libinput_unref(li); 155 ck_assert_int_eq(counter.close_func_count, 1); 156} 157END_TEST 158 159START_TEST(path_create_invalid_file) 160{ 161 struct libinput *li; 162 struct libinput_device *device; 163 char path[] = "/tmp/litest_path_XXXXXX"; 164 int fd; 165 struct counter counter; 166 167 umask(002); 168 fd = mkstemp(path); 169 ck_assert_int_ge(fd, 0); 170 close(fd); 171 172 counter.open_func_count = 0; 173 counter.close_func_count = 0; 174 175 li = libinput_path_create_context(&counting_interface, &counter); 176 unlink(path); 177 178 litest_disable_log_handler(li); 179 180 ck_assert_notnull(li); 181 device = libinput_path_add_device(li, path); 182 ck_assert(device == NULL); 183 184 ck_assert_int_eq(counter.open_func_count, 0); 185 ck_assert_int_eq(counter.close_func_count, 0); 186 187 litest_restore_log_handler(li); 188 libinput_unref(li); 189 ck_assert_int_eq(counter.close_func_count, 0); 190} 191END_TEST 192 193START_TEST(path_create_pathmax_file) 194{ 195 struct libinput *li; 196 struct libinput_device *device; 197 char *path; 198 struct counter counter; 199 200 path = zalloc(PATH_MAX * 2); 201 memset(path, 'a', PATH_MAX * 2 - 1); 202 203 counter.open_func_count = 0; 204 counter.close_func_count = 0; 205 206 li = libinput_path_create_context(&counting_interface, &counter); 207 208 litest_set_log_handler_bug(li); 209 ck_assert_notnull(li); 210 device = libinput_path_add_device(li, path); 211 ck_assert(device == NULL); 212 213 ck_assert_int_eq(counter.open_func_count, 0); 214 ck_assert_int_eq(counter.close_func_count, 0); 215 216 litest_restore_log_handler(li); 217 libinput_unref(li); 218 ck_assert_int_eq(counter.close_func_count, 0); 219 220 free(path); 221} 222END_TEST 223 224 225START_TEST(path_create_destroy) 226{ 227 struct libinput *li; 228 struct libinput_device *device; 229 struct libevdev_uinput *uinput; 230 struct counter counter; 231 232 counter.open_func_count = 0; 233 counter.close_func_count = 0; 234 235 uinput = litest_create_uinput_device("test device", NULL, 236 EV_KEY, BTN_LEFT, 237 EV_KEY, BTN_RIGHT, 238 EV_REL, REL_X, 239 EV_REL, REL_Y, 240 -1); 241 242 li = libinput_path_create_context(&counting_interface, &counter); 243 ck_assert_notnull(li); 244 245 litest_disable_log_handler(li); 246 247 ck_assert(libinput_get_user_data(li) == &counter); 248 249 device = libinput_path_add_device(li, 250 libevdev_uinput_get_devnode(uinput)); 251 ck_assert_notnull(device); 252 253 ck_assert_int_eq(counter.open_func_count, 1); 254 255 libevdev_uinput_destroy(uinput); 256 libinput_unref(li); 257 ck_assert_int_eq(counter.close_func_count, 1); 258} 259END_TEST 260 261START_TEST(path_force_destroy) 262{ 263 struct litest_device *dev = litest_current_device(); 264 struct libinput *li; 265 struct libinput_device *device; 266 267 li = libinput_path_create_context(&simple_interface, NULL); 268 ck_assert_notnull(li); 269 libinput_ref(li); 270 device = libinput_path_add_device(li, 271 libevdev_uinput_get_devnode(dev->uinput)); 272 ck_assert_notnull(device); 273 274 while (libinput_unref(li) != NULL) 275 ; 276} 277END_TEST 278 279START_TEST(path_set_user_data) 280{ 281 struct libinput *li; 282 int data1, data2; 283 284 li = libinput_path_create_context(&simple_interface, &data1); 285 ck_assert_notnull(li); 286 ck_assert(libinput_get_user_data(li) == &data1); 287 libinput_set_user_data(li, &data2); 288 ck_assert(libinput_get_user_data(li) == &data2); 289 290 libinput_unref(li); 291} 292END_TEST 293 294START_TEST(path_added_seat) 295{ 296 struct litest_device *dev = litest_current_device(); 297 struct libinput *li = dev->libinput; 298 struct libinput_event *event; 299 struct libinput_device *device; 300 struct libinput_seat *seat; 301 const char *seat_name; 302 enum libinput_event_type type; 303 304 libinput_dispatch(li); 305 306 event = libinput_get_event(li); 307 ck_assert_notnull(event); 308 309 type = libinput_event_get_type(event); 310 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 311 312 device = libinput_event_get_device(event); 313 seat = libinput_device_get_seat(device); 314 ck_assert_notnull(seat); 315 316 seat_name = libinput_seat_get_logical_name(seat); 317 ck_assert_str_eq(seat_name, "default"); 318 319 libinput_event_destroy(event); 320} 321END_TEST 322 323START_TEST(path_seat_change) 324{ 325 struct litest_device *dev = litest_current_device(); 326 struct libinput *li = dev->libinput; 327 struct libinput_event *event; 328 struct libinput_device *device; 329 struct libinput_seat *seat1, *seat2; 330 const char *seat1_name; 331 const char *seat2_name = "new seat"; 332 int rc; 333 334 libinput_dispatch(li); 335 336 event = libinput_get_event(li); 337 ck_assert_int_eq(libinput_event_get_type(event), 338 LIBINPUT_EVENT_DEVICE_ADDED); 339 340 device = libinput_event_get_device(event); 341 libinput_device_ref(device); 342 343 seat1 = libinput_device_get_seat(device); 344 libinput_seat_ref(seat1); 345 346 seat1_name = libinput_seat_get_logical_name(seat1); 347 libinput_event_destroy(event); 348 349 litest_drain_events(li); 350 351 rc = libinput_device_set_seat_logical_name(device, 352 seat2_name); 353 ck_assert_int_eq(rc, 0); 354 355 libinput_dispatch(li); 356 357 event = libinput_get_event(li); 358 ck_assert_notnull(event); 359 360 ck_assert_int_eq(libinput_event_get_type(event), 361 LIBINPUT_EVENT_DEVICE_REMOVED); 362 363 ck_assert(libinput_event_get_device(event) == device); 364 libinput_event_destroy(event); 365 366 event = libinput_get_event(li); 367 ck_assert_notnull(event); 368 ck_assert_int_eq(libinput_event_get_type(event), 369 LIBINPUT_EVENT_DEVICE_ADDED); 370 ck_assert(libinput_event_get_device(event) != device); 371 libinput_device_unref(device); 372 373 device = libinput_event_get_device(event); 374 seat2 = libinput_device_get_seat(device); 375 376 ck_assert_str_ne(libinput_seat_get_logical_name(seat2), 377 seat1_name); 378 ck_assert_str_eq(libinput_seat_get_logical_name(seat2), 379 seat2_name); 380 libinput_event_destroy(event); 381 382 libinput_seat_unref(seat1); 383 384 /* litest: swap the new device in, so cleanup works */ 385 libinput_device_unref(dev->libinput_device); 386 libinput_device_ref(device); 387 dev->libinput_device = device; 388} 389END_TEST 390 391START_TEST(path_added_device) 392{ 393 struct litest_device *dev = litest_current_device(); 394 struct libinput *li = dev->libinput; 395 struct libinput_event *event; 396 struct libinput_device *device; 397 enum libinput_event_type type; 398 399 libinput_dispatch(li); 400 401 event = libinput_get_event(li); 402 ck_assert_notnull(event); 403 type = libinput_event_get_type(event); 404 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 405 device = libinput_event_get_device(event); 406 ck_assert_notnull(device); 407 408 libinput_event_destroy(event); 409} 410END_TEST 411 412START_TEST(path_add_device) 413{ 414 struct litest_device *dev = litest_current_device(); 415 struct libinput *li = dev->libinput; 416 struct libinput_event *event; 417 struct libinput_device *device; 418 char *sysname1 = NULL, *sysname2 = NULL; 419 enum libinput_event_type type; 420 421 libinput_dispatch(li); 422 423 event = libinput_get_event(li); 424 ck_assert_notnull(event); 425 type = libinput_event_get_type(event); 426 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 427 device = libinput_event_get_device(event); 428 ck_assert_notnull(device); 429 sysname1 = safe_strdup(libinput_device_get_sysname(device)); 430 libinput_event_destroy(event); 431 432 litest_assert_empty_queue(li); 433 434 device = libinput_path_add_device(li, 435 libevdev_uinput_get_devnode(dev->uinput)); 436 ck_assert_notnull(device); 437 438 libinput_dispatch(li); 439 440 event = libinput_get_event(li); 441 ck_assert_notnull(event); 442 type = libinput_event_get_type(event); 443 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 444 device = libinput_event_get_device(event); 445 ck_assert_notnull(device); 446 sysname2 = safe_strdup(libinput_device_get_sysname(device)); 447 libinput_event_destroy(event); 448 449 ck_assert_str_eq(sysname1, sysname2); 450 451 free(sysname1); 452 free(sysname2); 453} 454END_TEST 455 456START_TEST(path_add_invalid_path) 457{ 458 struct libinput *li; 459 struct libinput_device *device; 460 461 li = litest_create_context(); 462 463 litest_disable_log_handler(li); 464 device = libinput_path_add_device(li, "/tmp/"); 465 litest_restore_log_handler(li); 466 ck_assert(device == NULL); 467 468 libinput_dispatch(li); 469 470 litest_assert_empty_queue(li); 471 472 litest_destroy_context(li); 473} 474END_TEST 475 476START_TEST(path_device_sysname) 477{ 478 struct litest_device *dev = litest_current_device(); 479 struct libinput_event *ev; 480 struct libinput_device *device; 481 const char *sysname; 482 enum libinput_event_type type; 483 484 libinput_dispatch(dev->libinput); 485 486 ev = libinput_get_event(dev->libinput); 487 ck_assert_notnull(ev); 488 type = libinput_event_get_type(ev); 489 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 490 device = libinput_event_get_device(ev); 491 ck_assert_notnull(device); 492 sysname = libinput_device_get_sysname(device); 493 494 ck_assert_notnull(sysname); 495 ck_assert_int_gt(strlen(sysname), 1); 496 ck_assert(strchr(sysname, '/') == NULL); 497 ck_assert(strneq(sysname, "event", 5)); 498 499 libinput_event_destroy(ev); 500} 501END_TEST 502 503START_TEST(path_remove_device) 504{ 505 struct litest_device *dev = litest_current_device(); 506 struct libinput *li = dev->libinput; 507 struct libinput_event *event; 508 struct libinput_device *device; 509 int remove_event = 0; 510 511 device = libinput_path_add_device(li, 512 libevdev_uinput_get_devnode(dev->uinput)); 513 ck_assert_notnull(device); 514 litest_drain_events(li); 515 516 libinput_path_remove_device(device); 517 libinput_dispatch(li); 518 519 while ((event = libinput_get_event(li))) { 520 enum libinput_event_type type; 521 type = libinput_event_get_type(event); 522 523 if (type == LIBINPUT_EVENT_DEVICE_REMOVED) 524 remove_event++; 525 526 libinput_event_destroy(event); 527 } 528 529 ck_assert_int_eq(remove_event, 1); 530} 531END_TEST 532 533START_TEST(path_double_remove_device) 534{ 535 struct litest_device *dev = litest_current_device(); 536 struct libinput *li = dev->libinput; 537 struct libinput_event *event; 538 struct libinput_device *device; 539 int remove_event = 0; 540 541 device = libinput_path_add_device(li, 542 libevdev_uinput_get_devnode(dev->uinput)); 543 ck_assert_notnull(device); 544 litest_drain_events(li); 545 546 libinput_path_remove_device(device); 547 libinput_path_remove_device(device); 548 libinput_dispatch(li); 549 550 while ((event = libinput_get_event(li))) { 551 enum libinput_event_type type; 552 type = libinput_event_get_type(event); 553 554 if (type == LIBINPUT_EVENT_DEVICE_REMOVED) 555 remove_event++; 556 557 libinput_event_destroy(event); 558 } 559 560 ck_assert_int_eq(remove_event, 1); 561} 562END_TEST 563 564START_TEST(path_suspend) 565{ 566 struct libinput *li; 567 struct libinput_device *device; 568 struct libevdev_uinput *uinput; 569 int rc; 570 void *userdata = &rc; 571 572 uinput = litest_create_uinput_device("test device", NULL, 573 EV_KEY, BTN_LEFT, 574 EV_KEY, BTN_RIGHT, 575 EV_REL, REL_X, 576 EV_REL, REL_Y, 577 -1); 578 579 li = libinput_path_create_context(&simple_interface, userdata); 580 ck_assert_notnull(li); 581 582 device = libinput_path_add_device(li, 583 libevdev_uinput_get_devnode(uinput)); 584 ck_assert_notnull(device); 585 586 libinput_suspend(li); 587 libinput_resume(li); 588 589 libevdev_uinput_destroy(uinput); 590 libinput_unref(li); 591} 592END_TEST 593 594START_TEST(path_double_suspend) 595{ 596 struct libinput *li; 597 struct libinput_device *device; 598 struct libevdev_uinput *uinput; 599 int rc; 600 void *userdata = &rc; 601 602 uinput = litest_create_uinput_device("test device", NULL, 603 EV_KEY, BTN_LEFT, 604 EV_KEY, BTN_RIGHT, 605 EV_REL, REL_X, 606 EV_REL, REL_Y, 607 -1); 608 609 li = libinput_path_create_context(&simple_interface, userdata); 610 ck_assert_notnull(li); 611 612 device = libinput_path_add_device(li, 613 libevdev_uinput_get_devnode(uinput)); 614 ck_assert_notnull(device); 615 616 libinput_suspend(li); 617 libinput_suspend(li); 618 libinput_resume(li); 619 620 libevdev_uinput_destroy(uinput); 621 libinput_unref(li); 622} 623END_TEST 624 625START_TEST(path_double_resume) 626{ 627 struct libinput *li; 628 struct libinput_device *device; 629 struct libevdev_uinput *uinput; 630 int rc; 631 void *userdata = &rc; 632 633 uinput = litest_create_uinput_device("test device", NULL, 634 EV_KEY, BTN_LEFT, 635 EV_KEY, BTN_RIGHT, 636 EV_REL, REL_X, 637 EV_REL, REL_Y, 638 -1); 639 640 li = libinput_path_create_context(&simple_interface, userdata); 641 ck_assert_notnull(li); 642 643 device = libinput_path_add_device(li, 644 libevdev_uinput_get_devnode(uinput)); 645 ck_assert_notnull(device); 646 647 libinput_suspend(li); 648 libinput_resume(li); 649 libinput_resume(li); 650 651 libevdev_uinput_destroy(uinput); 652 libinput_unref(li); 653} 654END_TEST 655 656START_TEST(path_add_device_suspend_resume) 657{ 658 struct libinput *li; 659 struct libinput_device *device; 660 struct libinput_event *event; 661 struct libevdev_uinput *uinput1, *uinput2; 662 int rc; 663 int nevents; 664 void *userdata = &rc; 665 666 uinput1 = litest_create_uinput_device("test device", NULL, 667 EV_KEY, BTN_LEFT, 668 EV_KEY, BTN_RIGHT, 669 EV_REL, REL_X, 670 EV_REL, REL_Y, 671 -1); 672 uinput2 = litest_create_uinput_device("test device 2", NULL, 673 EV_KEY, BTN_LEFT, 674 EV_KEY, BTN_RIGHT, 675 EV_REL, REL_X, 676 EV_REL, REL_Y, 677 -1); 678 679 li = libinput_path_create_context(&simple_interface, userdata); 680 ck_assert_notnull(li); 681 682 device = libinput_path_add_device(li, 683 libevdev_uinput_get_devnode(uinput1)); 684 ck_assert_notnull(device); 685 libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2)); 686 687 libinput_dispatch(li); 688 689 nevents = 0; 690 while ((event = libinput_get_event(li))) { 691 enum libinput_event_type type; 692 type = libinput_event_get_type(event); 693 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 694 libinput_event_destroy(event); 695 nevents++; 696 } 697 698 ck_assert_int_eq(nevents, 2); 699 700 libinput_suspend(li); 701 libinput_dispatch(li); 702 703 nevents = 0; 704 while ((event = libinput_get_event(li))) { 705 enum libinput_event_type type; 706 type = libinput_event_get_type(event); 707 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED); 708 libinput_event_destroy(event); 709 nevents++; 710 } 711 712 ck_assert_int_eq(nevents, 2); 713 714 libinput_resume(li); 715 libinput_dispatch(li); 716 717 nevents = 0; 718 while ((event = libinput_get_event(li))) { 719 enum libinput_event_type type; 720 type = libinput_event_get_type(event); 721 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 722 libinput_event_destroy(event); 723 nevents++; 724 } 725 726 ck_assert_int_eq(nevents, 2); 727 728 libevdev_uinput_destroy(uinput1); 729 libevdev_uinput_destroy(uinput2); 730 libinput_unref(li); 731} 732END_TEST 733 734START_TEST(path_add_device_suspend_resume_fail) 735{ 736 struct libinput *li; 737 struct libinput_device *device; 738 struct libinput_event *event; 739 struct libevdev_uinput *uinput1, *uinput2; 740 int rc; 741 int nevents; 742 void *userdata = &rc; 743 744 uinput1 = litest_create_uinput_device("test device", NULL, 745 EV_KEY, BTN_LEFT, 746 EV_KEY, BTN_RIGHT, 747 EV_REL, REL_X, 748 EV_REL, REL_Y, 749 -1); 750 uinput2 = litest_create_uinput_device("test device 2", NULL, 751 EV_KEY, BTN_LEFT, 752 EV_KEY, BTN_RIGHT, 753 EV_REL, REL_X, 754 EV_REL, REL_Y, 755 -1); 756 757 li = libinput_path_create_context(&simple_interface, userdata); 758 ck_assert_notnull(li); 759 760 device = libinput_path_add_device(li, 761 libevdev_uinput_get_devnode(uinput1)); 762 ck_assert_notnull(device); 763 device = libinput_path_add_device(li, 764 libevdev_uinput_get_devnode(uinput2)); 765 ck_assert_notnull(device); 766 767 libinput_dispatch(li); 768 769 nevents = 0; 770 while ((event = libinput_get_event(li))) { 771 enum libinput_event_type type; 772 type = libinput_event_get_type(event); 773 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 774 libinput_event_destroy(event); 775 nevents++; 776 } 777 778 ck_assert_int_eq(nevents, 2); 779 780 libinput_suspend(li); 781 libinput_dispatch(li); 782 783 nevents = 0; 784 while ((event = libinput_get_event(li))) { 785 enum libinput_event_type type; 786 type = libinput_event_get_type(event); 787 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED); 788 libinput_event_destroy(event); 789 nevents++; 790 } 791 792 ck_assert_int_eq(nevents, 2); 793 794 /* now drop one of the devices */ 795 libevdev_uinput_destroy(uinput1); 796 rc = libinput_resume(li); 797 ck_assert_int_eq(rc, -1); 798 799 libinput_dispatch(li); 800 801 nevents = 0; 802 while ((event = libinput_get_event(li))) { 803 enum libinput_event_type type; 804 type = libinput_event_get_type(event); 805 /* We expect one device being added, second one fails, 806 * causing a removed event for the first one */ 807 if (type != LIBINPUT_EVENT_DEVICE_ADDED && 808 type != LIBINPUT_EVENT_DEVICE_REMOVED) 809 ck_abort(); 810 libinput_event_destroy(event); 811 nevents++; 812 } 813 814 ck_assert_int_eq(nevents, 2); 815 816 libevdev_uinput_destroy(uinput2); 817 libinput_unref(li); 818} 819END_TEST 820 821START_TEST(path_add_device_suspend_resume_remove_device) 822{ 823 struct libinput *li; 824 struct libinput_device *device; 825 struct libinput_event *event; 826 struct libevdev_uinput *uinput1, *uinput2; 827 int rc; 828 int nevents; 829 void *userdata = &rc; 830 831 uinput1 = litest_create_uinput_device("test device", NULL, 832 EV_KEY, BTN_LEFT, 833 EV_KEY, BTN_RIGHT, 834 EV_REL, REL_X, 835 EV_REL, REL_Y, 836 -1); 837 uinput2 = litest_create_uinput_device("test device 2", NULL, 838 EV_KEY, BTN_LEFT, 839 EV_KEY, BTN_RIGHT, 840 EV_REL, REL_X, 841 EV_REL, REL_Y, 842 -1); 843 844 li = libinput_path_create_context(&simple_interface, userdata); 845 ck_assert_notnull(li); 846 847 device = libinput_path_add_device(li, 848 libevdev_uinput_get_devnode(uinput1)); 849 ck_assert_notnull(device); 850 device = libinput_path_add_device(li, 851 libevdev_uinput_get_devnode(uinput2)); 852 853 libinput_device_ref(device); 854 libinput_dispatch(li); 855 856 nevents = 0; 857 while ((event = libinput_get_event(li))) { 858 enum libinput_event_type type; 859 type = libinput_event_get_type(event); 860 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 861 libinput_event_destroy(event); 862 nevents++; 863 } 864 865 ck_assert_int_eq(nevents, 2); 866 867 libinput_suspend(li); 868 libinput_dispatch(li); 869 870 nevents = 0; 871 while ((event = libinput_get_event(li))) { 872 enum libinput_event_type type; 873 type = libinput_event_get_type(event); 874 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED); 875 libinput_event_destroy(event); 876 nevents++; 877 } 878 879 ck_assert_int_eq(nevents, 2); 880 881 /* now drop and remove one of the devices */ 882 libevdev_uinput_destroy(uinput2); 883 libinput_path_remove_device(device); 884 libinput_device_unref(device); 885 886 rc = libinput_resume(li); 887 ck_assert_int_eq(rc, 0); 888 889 libinput_dispatch(li); 890 891 nevents = 0; 892 while ((event = libinput_get_event(li))) { 893 enum libinput_event_type type; 894 type = libinput_event_get_type(event); 895 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 896 libinput_event_destroy(event); 897 nevents++; 898 } 899 900 ck_assert_int_eq(nevents, 1); 901 902 libevdev_uinput_destroy(uinput1); 903 libinput_unref(li); 904} 905END_TEST 906 907START_TEST(path_device_gone) 908{ 909 struct libinput *li; 910 struct libinput_device *device; 911 struct libevdev_uinput *uinput; 912 struct libinput_event *event; 913 914 uinput = litest_create_uinput_device("test device", NULL, 915 EV_KEY, BTN_LEFT, 916 EV_KEY, BTN_RIGHT, 917 EV_REL, REL_X, 918 EV_REL, REL_Y, 919 -1); 920 921 li = libinput_path_create_context(&simple_interface, NULL); 922 ck_assert_notnull(li); 923 924 device = libinput_path_add_device(li, 925 libevdev_uinput_get_devnode(uinput)); 926 ck_assert_notnull(device); 927 928 litest_drain_events(li); 929 930 libevdev_uinput_destroy(uinput); 931 932 libinput_dispatch(li); 933 934 event = libinput_get_event(li); 935 ck_assert_notnull(event); 936 litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED); 937 libinput_event_destroy(event); 938 939 libinput_unref(li); 940} 941END_TEST 942 943START_TEST(path_seat_recycle) 944{ 945 struct libinput *li; 946 struct libevdev_uinput *uinput; 947 int rc; 948 void *userdata = &rc; 949 struct libinput_event *ev; 950 struct libinput_device *device; 951 struct libinput_seat *saved_seat = NULL; 952 struct libinput_seat *seat; 953 int data = 0; 954 int found = 0; 955 void *user_data; 956 enum libinput_event_type type; 957 958 uinput = litest_create_uinput_device("test device", NULL, 959 EV_KEY, BTN_LEFT, 960 EV_KEY, BTN_RIGHT, 961 EV_REL, REL_X, 962 EV_REL, REL_Y, 963 -1); 964 965 li = libinput_path_create_context(&simple_interface, userdata); 966 ck_assert_notnull(li); 967 968 device = libinput_path_add_device(li, 969 libevdev_uinput_get_devnode(uinput)); 970 ck_assert_notnull(device); 971 972 libinput_dispatch(li); 973 974 ev = libinput_get_event(li); 975 ck_assert_notnull(ev); 976 type = libinput_event_get_type(ev); 977 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 978 device = libinput_event_get_device(ev); 979 ck_assert_notnull(device); 980 saved_seat = libinput_device_get_seat(device); 981 libinput_seat_set_user_data(saved_seat, &data); 982 libinput_seat_ref(saved_seat); 983 libinput_event_destroy(ev); 984 ck_assert_notnull(saved_seat); 985 986 litest_assert_empty_queue(li); 987 988 libinput_suspend(li); 989 990 litest_drain_events(li); 991 992 libinput_resume(li); 993 994 libinput_dispatch(li); 995 ev = libinput_get_event(li); 996 ck_assert_notnull(ev); 997 type = libinput_event_get_type(ev); 998 ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); 999 device = libinput_event_get_device(ev); 1000 ck_assert_notnull(device); 1001 1002 seat = libinput_device_get_seat(device); 1003 user_data = libinput_seat_get_user_data(seat); 1004 if (user_data == &data) { 1005 found = 1; 1006 ck_assert(seat == saved_seat); 1007 } 1008 1009 libinput_event_destroy(ev); 1010 ck_assert(found == 1); 1011 1012 libinput_unref(li); 1013 1014 libevdev_uinput_destroy(uinput); 1015} 1016END_TEST 1017 1018START_TEST(path_udev_assign_seat) 1019{ 1020 struct litest_device *dev = litest_current_device(); 1021 struct libinput *li = dev->libinput; 1022 int rc; 1023 1024 litest_set_log_handler_bug(li); 1025 rc = libinput_udev_assign_seat(li, "foo"); 1026 ck_assert_int_eq(rc, -1); 1027 litest_restore_log_handler(li); 1028} 1029END_TEST 1030 1031START_TEST(path_ignore_device) 1032{ 1033 struct litest_device *dev; 1034 struct libinput *li; 1035 struct libinput_device *device; 1036 const char *path; 1037 1038 dev = litest_create(LITEST_IGNORED_MOUSE, NULL, NULL, NULL, NULL); 1039 path = libevdev_uinput_get_devnode(dev->uinput); 1040 ck_assert_notnull(path); 1041 1042 li = litest_create_context(); 1043 device = libinput_path_add_device(li, path); 1044 ck_assert(device == NULL); 1045 1046 litest_destroy_context(li); 1047 litest_delete_device(dev); 1048} 1049END_TEST 1050 1051TEST_COLLECTION(path) 1052{ 1053 litest_add_no_device(path_create_NULL); 1054 litest_add_no_device(path_create_invalid); 1055 litest_add_no_device(path_create_invalid_file); 1056 litest_add_no_device(path_create_invalid_kerneldev); 1057 litest_add_no_device(path_create_pathmax_file); 1058 litest_add_no_device(path_create_destroy); 1059 litest_add(path_force_destroy, LITEST_ANY, LITEST_ANY); 1060 litest_add_no_device(path_set_user_data); 1061 litest_add_no_device(path_suspend); 1062 litest_add_no_device(path_double_suspend); 1063 litest_add_no_device(path_double_resume); 1064 litest_add_no_device(path_add_device_suspend_resume); 1065 litest_add_no_device(path_add_device_suspend_resume_fail); 1066 litest_add_no_device(path_add_device_suspend_resume_remove_device); 1067 litest_add_for_device(path_added_seat, LITEST_SYNAPTICS_CLICKPAD_X220); 1068 litest_add_for_device(path_seat_change, LITEST_SYNAPTICS_CLICKPAD_X220); 1069 litest_add(path_added_device, LITEST_ANY, LITEST_ANY); 1070 litest_add(path_device_sysname, LITEST_ANY, LITEST_ANY); 1071 litest_add_for_device(path_add_device, LITEST_SYNAPTICS_CLICKPAD_X220); 1072 litest_add_no_device(path_add_invalid_path); 1073 litest_add_for_device(path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220); 1074 litest_add_for_device(path_double_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220); 1075 litest_add_no_device(path_device_gone); 1076 litest_add_no_device(path_seat_recycle); 1077 litest_add_for_device(path_udev_assign_seat, LITEST_SYNAPTICS_CLICKPAD_X220); 1078 1079 litest_add_no_device(path_ignore_device); 1080} 1081