END_TEST START_TEST(log_priority) { struct libinput *li; li = libinput_path_create_context(&simple_interface, NULL); libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR); libinput_log_set_handler(li, simple_log_handler); log_handler_context = li; libinput_path_add_device(li, "/tmp"); ck_assert_int_eq(log_handler_called, 1); libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO); /* event0 is usually Lid Switch which prints an info that we don't handle it */ libinput_path_add_device(li, "/dev/input/event0"); ck_assert_int_gt(log_handler_called, 1); log_handler_called = 0; libinput_unref(li); log_handler_context = NULL; }
END_TEST START_TEST(path_create_destroy) { struct libinput *li; struct libinput_device *device; struct libevdev_uinput *uinput; int rc; void *userdata = &rc; uinput = litest_create_uinput_device("test device", NULL, EV_KEY, BTN_LEFT, EV_KEY, BTN_RIGHT, EV_REL, REL_X, EV_REL, REL_Y, -1); li = libinput_path_create_context(&simple_interface, userdata); ck_assert(li != NULL); ck_assert(libinput_get_user_data(li) == userdata); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput)); ck_assert(device != NULL); ck_assert_int_eq(open_func_count, 1); libevdev_uinput_destroy(uinput); libinput_unref(li); ck_assert_int_eq(close_func_count, 1); open_func_count = 0; close_func_count = 0; }
static struct libinput * open_device(const struct libinput_interface *interface, void *userdata, const char *path, int verbose) { struct libinput_device *device; struct libinput *li; li = libinput_path_create_context(interface, userdata); if (!li) { fprintf(stderr, "Failed to initialize context from %s\n", path); return NULL; } if (verbose) { libinput_log_set_handler(li, log_handler); libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); } device = libinput_path_add_device(li, path); if (!device) { fprintf(stderr, "Failed to initialized device %s\n", path); libinput_unref(li); li = NULL; } return li; }
END_TEST START_TEST(path_create_invalid) { struct libinput *li; struct libinput_device *device; const char *path = "/tmp"; open_func_count = 0; close_func_count = 0; li = libinput_path_create_context(&simple_interface, NULL); ck_assert(li != NULL); device = libinput_path_add_device(li, path); ck_assert(device == NULL); ck_assert_int_eq(open_func_count, 0); ck_assert_int_eq(close_func_count, 0); libinput_unref(li); ck_assert_int_eq(close_func_count, 0); open_func_count = 0; close_func_count = 0; }
END_TEST START_TEST(path_double_remove_device) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_device *device; int remove_event = 0; device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput)); ck_assert(device != NULL); litest_drain_events(li); libinput_path_remove_device(device); libinput_path_remove_device(device); libinput_dispatch(li); while ((event = libinput_get_event(li))) { enum libinput_event_type type; type = libinput_event_get_type(event); if (type == LIBINPUT_EVENT_DEVICE_REMOVED) remove_event++; libinput_event_destroy(event); } ck_assert_int_eq(remove_event, 1); }
END_TEST START_TEST(abs_mt_device_no_absx) { struct libevdev_uinput *uinput; struct libinput *li; struct libinput_device *device; uinput = litest_create_uinput_device("test device", NULL, EV_KEY, BTN_LEFT, EV_KEY, BTN_RIGHT, EV_ABS, ABS_X, EV_ABS, ABS_Y, EV_ABS, ABS_MT_SLOT, EV_ABS, ABS_MT_POSITION_Y, -1); li = litest_create_context(); litest_disable_log_handler(li); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput)); litest_restore_log_handler(li); ck_assert(device == NULL); libinput_unref(li); libevdev_uinput_destroy(uinput); }
END_TEST START_TEST(path_create_invalid_file) { struct libinput *li; struct libinput_device *device; char path[] = "/tmp/litest_path_XXXXXX"; int fd; umask(002); fd = mkstemp(path); ck_assert_int_ge(fd, 0); close(fd); open_func_count = 0; close_func_count = 0; li = libinput_path_create_context(&simple_interface, NULL); unlink(path); ck_assert(li != NULL); device = libinput_path_add_device(li, path); ck_assert(device == NULL); ck_assert_int_eq(open_func_count, 0); ck_assert_int_eq(close_func_count, 0); libinput_unref(li); ck_assert_int_eq(close_func_count, 0); open_func_count = 0; close_func_count = 0; }
END_TEST START_TEST(keyboard_ignore_no_pressed_release) { struct litest_device *dev; struct libinput *unused_libinput; struct libinput *libinput; struct libinput_event *event; struct libinput_event_keyboard *kevent; int events[] = { EV_KEY, KEY_A, -1, -1, }; enum libinput_key_state *state; enum libinput_key_state expected_states[] = { LIBINPUT_KEY_STATE_PRESSED, LIBINPUT_KEY_STATE_RELEASED, }; /* We can't send pressed -> released -> pressed events using uinput * as such non-symmetric events are dropped. Work-around this by first * adding the test device to the tested context after having sent an * initial pressed event. */ unused_libinput = litest_create_context(); dev = litest_add_device_with_overrides(unused_libinput, LITEST_KEYBOARD, "Generic keyboard", NULL, NULL, events); litest_keyboard_key(dev, KEY_A, true); litest_drain_events(unused_libinput); libinput = litest_create_context(); libinput_path_add_device(libinput, libevdev_uinput_get_devnode(dev->uinput)); litest_drain_events(libinput); litest_keyboard_key(dev, KEY_A, false); litest_keyboard_key(dev, KEY_A, true); litest_keyboard_key(dev, KEY_A, false); libinput_dispatch(libinput); ARRAY_FOR_EACH(expected_states, state) { event = libinput_get_event(libinput); ck_assert_notnull(event); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_KEYBOARD_KEY); kevent = libinput_event_get_keyboard_event(event); ck_assert_int_eq(libinput_event_keyboard_get_key(kevent), KEY_A); ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent), *state); libinput_event_destroy(event); libinput_dispatch(libinput); }
END_TEST START_TEST(path_add_device) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_device *device; const char *sysname1 = NULL, *sysname2 = NULL; libinput_dispatch(li); while ((event = libinput_get_event(li))) { enum libinput_event_type type; type = libinput_event_get_type(event); if (type == LIBINPUT_EVENT_DEVICE_ADDED) { ck_assert(sysname1 == NULL); device = libinput_event_get_device(event); ck_assert(device != NULL); sysname1 = libinput_device_get_sysname(device); } libinput_event_destroy(event); } device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput)); ck_assert(device != NULL); libinput_dispatch(li); while ((event = libinput_get_event(li))) { enum libinput_event_type type; type = libinput_event_get_type(event); if (type == LIBINPUT_EVENT_DEVICE_ADDED) { ck_assert(sysname2 == NULL); device = libinput_event_get_device(event); ck_assert(device != NULL); sysname2 = libinput_device_get_sysname(device); } libinput_event_destroy(event); } ck_assert_str_eq(sysname1, sysname2); libinput_event_destroy(event); }
END_TEST START_TEST(log_handler_NULL) { struct libinput *li; li = libinput_path_create_context(&simple_interface, NULL); libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); libinput_log_set_handler(li, NULL); libinput_path_add_device(li, "/tmp"); ck_assert_int_eq(log_handler_called, 0); log_handler_called = 0; libinput_unref(li); }
END_TEST static void assert_device_ignored(struct libinput *li, struct input_absinfo *absinfo) { struct libevdev_uinput *uinput; struct libinput_device *device; uinput = litest_create_uinput_abs_device("test device", NULL, absinfo, EV_KEY, BTN_LEFT, EV_KEY, BTN_RIGHT, -1); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput)); litest_assert_ptr_null(device); libevdev_uinput_destroy(uinput); }
END_TEST START_TEST(path_force_destroy) { struct litest_device *dev = litest_current_device(); struct libinput *li; struct libinput_device *device; li = libinput_path_create_context(&simple_interface, NULL); ck_assert_notnull(li); libinput_ref(li); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput)); ck_assert_notnull(device); while (libinput_unref(li) != NULL) ; }
END_TEST START_TEST(path_add_device) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_device *device; char *sysname1 = NULL, *sysname2 = NULL; enum libinput_event_type type; libinput_dispatch(li); event = libinput_get_event(li); ck_assert_notnull(event); type = libinput_event_get_type(event); ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); device = libinput_event_get_device(event); ck_assert_notnull(device); sysname1 = strdup(libinput_device_get_sysname(device)); libinput_event_destroy(event); litest_assert_empty_queue(li); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput)); ck_assert(device != NULL); libinput_dispatch(li); event = libinput_get_event(li); ck_assert_notnull(event); type = libinput_event_get_type(event); ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); device = libinput_event_get_device(event); ck_assert_notnull(device); sysname2 = strdup(libinput_device_get_sysname(device)); libinput_event_destroy(event); ck_assert_str_eq(sysname1, sysname2); free(sysname1); free(sysname2); }
END_TEST START_TEST(path_add_invalid_path) { struct libinput *li; struct libinput_event *event; struct libinput_device *device; li = litest_create_context(); device = libinput_path_add_device(li, "/tmp/"); ck_assert(device == NULL); libinput_dispatch(li); while ((event = libinput_get_event(li))) ck_abort(); libinput_unref(li); }
END_TEST START_TEST(path_seat_recycle) { struct libinput *li; struct libevdev_uinput *uinput; int rc; void *userdata = &rc; struct libinput_event *ev; struct libinput_device *device; struct libinput_seat *saved_seat = NULL; struct libinput_seat *seat; int data = 0; int found = 0; void *user_data; uinput = litest_create_uinput_device("test device", NULL, EV_KEY, BTN_LEFT, EV_KEY, BTN_RIGHT, EV_REL, REL_X, EV_REL, REL_Y, -1); li = libinput_path_create_context(&simple_interface, userdata); ck_assert(li != NULL); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput)); ck_assert(device != NULL); libinput_dispatch(li); while ((ev = libinput_get_event(li))) { switch (libinput_event_get_type(ev)) { case LIBINPUT_EVENT_DEVICE_ADDED: if (saved_seat) break; device = libinput_event_get_device(ev); ck_assert(device != NULL); saved_seat = libinput_device_get_seat(device); libinput_seat_set_user_data(saved_seat, &data); libinput_seat_ref(saved_seat); break; default: break; } libinput_event_destroy(ev); } ck_assert(saved_seat != NULL); libinput_suspend(li); litest_drain_events(li); libinput_resume(li); libinput_dispatch(li); while ((ev = libinput_get_event(li))) { switch (libinput_event_get_type(ev)) { case LIBINPUT_EVENT_DEVICE_ADDED: device = libinput_event_get_device(ev); ck_assert(device != NULL); seat = libinput_device_get_seat(device); user_data = libinput_seat_get_user_data(seat); if (user_data == &data) { found = 1; ck_assert(seat == saved_seat); } break; default: break; } libinput_event_destroy(ev); } ck_assert(found == 1); libinput_unref(li); libevdev_uinput_destroy(uinput); }
END_TEST START_TEST(path_add_device_suspend_resume_remove_device) { struct libinput *li; struct libinput_device *device; struct libinput_event *event; struct libevdev_uinput *uinput1, *uinput2; int rc; int nevents; void *userdata = &rc; uinput1 = litest_create_uinput_device("test device", NULL, EV_KEY, BTN_LEFT, EV_KEY, BTN_RIGHT, EV_REL, REL_X, EV_REL, REL_Y, -1); uinput2 = litest_create_uinput_device("test device 2", NULL, EV_KEY, BTN_LEFT, EV_KEY, BTN_RIGHT, EV_REL, REL_X, EV_REL, REL_Y, -1); li = libinput_path_create_context(&simple_interface, userdata); ck_assert(li != NULL); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput1)); ck_assert(device != NULL); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2)); libinput_device_ref(device); libinput_dispatch(li); nevents = 0; while ((event = libinput_get_event(li))) { enum libinput_event_type type; type = libinput_event_get_type(event); ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); libinput_event_destroy(event); nevents++; } ck_assert_int_eq(nevents, 2); libinput_suspend(li); libinput_dispatch(li); nevents = 0; while ((event = libinput_get_event(li))) { enum libinput_event_type type; type = libinput_event_get_type(event); ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED); libinput_event_destroy(event); nevents++; } ck_assert_int_eq(nevents, 2); /* now drop and remove one of the devices */ libevdev_uinput_destroy(uinput2); libinput_path_remove_device(device); libinput_device_unref(device); rc = libinput_resume(li); ck_assert_int_eq(rc, 0); libinput_dispatch(li); nevents = 0; while ((event = libinput_get_event(li))) { enum libinput_event_type type; type = libinput_event_get_type(event); ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); libinput_event_destroy(event); nevents++; } ck_assert_int_eq(nevents, 1); libevdev_uinput_destroy(uinput1); libinput_unref(li); open_func_count = 0; close_func_count = 0; }