END_TEST START_TEST(udev_device_sysname) { struct libinput *li; struct libinput_event *ev; struct libinput_device *device; const char *sysname; struct udev *udev; udev = udev_new(); ck_assert(udev != NULL); li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); while ((ev = libinput_get_event(li))) { if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED) continue; device = libinput_event_get_device(ev); sysname = libinput_device_get_sysname(device); ck_assert(sysname != NULL && strlen(sysname) > 1); ck_assert(strchr(sysname, '/') == NULL); ck_assert_int_eq(strncmp(sysname, "event", 5), 0); libinput_event_destroy(ev); } libinput_unref(li); udev_unref(udev); }
END_TEST START_TEST(abs_mt_device_no_range) { struct libinput *li; int code = _i; /* looped test */ /* set x/y so libinput doesn't just reject for missing axes */ struct input_absinfo absinfo[] = { { ABS_X, 0, 10, 0, 0, 0 }, { ABS_Y, 0, 10, 0, 0, 0 }, { ABS_MT_SLOT, 0, 10, 0, 0, 0 }, { ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 }, { ABS_MT_POSITION_X, 0, 10, 0, 0, 0 }, { ABS_MT_POSITION_Y, 0, 10, 0, 0, 0 }, { code, 0, 0, 0, 0, 0 }, { -1, -1, -1, -1, -1, -1 } }; li = litest_create_context(); litest_disable_log_handler(li); if (code != ABS_MT_TOOL_TYPE && code != ABS_MT_TRACKING_ID) /* kernel overrides it */ assert_device_ignored(li, absinfo); litest_restore_log_handler(li); libinput_unref(li); }
END_TEST START_TEST(udev_create_empty_seat) { struct libinput *li; struct libinput_event *event; struct udev *udev; int fd; udev = udev_new(); ck_assert(udev != NULL); /* expect a libinput reference, but no events */ li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); ck_assert_int_eq(libinput_udev_assign_seat(li, "seatdoesntexist"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); libinput_dispatch(li); event = libinput_get_event(li); ck_assert(event == NULL); libinput_event_destroy(event); libinput_unref(li); udev_unref(udev); }
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_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; }
END_TEST START_TEST(udev_create_seat0) { struct libinput *li; struct libinput_event *event; struct udev *udev; int fd; udev = udev_new(); ck_assert(udev != NULL); li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); /* expect at least one event */ libinput_dispatch(li); event = libinput_get_event(li); ck_assert(event != NULL); libinput_event_destroy(event); libinput_unref(li); udev_unref(udev); }
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(device_reenable_device_removed) { struct libinput *li; struct litest_device *litest_device; struct libinput_device *device; enum libinput_config_status status; li = litest_create_context(); litest_device = litest_add_device(li, LITEST_MOUSE); device = litest_device->libinput_device; libinput_device_ref(device); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); litest_delete_device(litest_device); litest_drain_events(li); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); /* can't really check for much here, this really just exercises the code path. */ litest_assert_empty_queue(li); libinput_device_unref(device); libinput_unref(li); }
END_TEST START_TEST(device_group_ref) { struct libinput *li = litest_create_context(); struct litest_device *dev = litest_add_device(li, LITEST_MOUSE); struct libinput_device *device = dev->libinput_device; struct libinput_device_group *group; group = libinput_device_get_device_group(device); ck_assert_notnull(group); libinput_device_group_ref(group); libinput_device_ref(device); litest_drain_events(li); litest_delete_device(dev); litest_drain_events(li); /* make sure the device is dead but the group is still around */ ck_assert(libinput_device_unref(device) == NULL); libinput_device_group_ref(group); ck_assert_notnull(libinput_device_group_unref(group)); ck_assert(libinput_device_group_unref(group) == NULL); libinput_unref(li); }
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(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_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(abs_mt_device_missing_res) { struct libinput *li; struct input_absinfo absinfo[] = { { ABS_X, 0, 10, 0, 0, 10 }, { ABS_Y, 0, 10, 0, 0, 10 }, { ABS_MT_SLOT, 0, 2, 0, 0, 0 }, { ABS_MT_TRACKING_ID, 0, 255, 0, 0, 0 }, { ABS_MT_POSITION_X, 0, 10, 0, 0, 10 }, { ABS_MT_POSITION_Y, 0, 10, 0, 0, 0 }, { -1, -1, -1, -1, -1, -1 } }; li = litest_create_context(); litest_disable_log_handler(li); assert_device_ignored(li, absinfo); absinfo[4].resolution = 0; absinfo[5].resolution = 20; assert_device_ignored(li, absinfo); litest_restore_log_handler(li); libinput_unref(li); }
LibinputServer::~LibinputServer() { #ifdef KEY_INPUT_HANDLING_VIRTUAL if (m_virtualkeyboard != nullptr) { Destruct(m_virtualkeyboard); } #endif libinput_unref(m_libinput); udev_unref(m_udev); }
END_TEST START_TEST(device_reenable_syspath_changed) { struct libinput *li; struct litest_device *litest_device; struct libinput_device *device1, *device2; enum libinput_config_status status; struct libinput_event *event; li = litest_create_context(); litest_device = litest_add_device(li, LITEST_MOUSE); device1 = litest_device->libinput_device; libinput_device_ref(device1); status = libinput_device_config_send_events_set_mode(device1, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_drain_events(li); litest_delete_device(litest_device); litest_drain_events(li); litest_device = litest_add_device(li, LITEST_MOUSE); device2 = litest_device->libinput_device; /* Note: if the sysname isn't the same, some other device got added * or removed while this test was running. This is unlikely and * would result in a false positive, so let's fail the test here */ ck_assert_str_eq(libinput_device_get_sysname(device1), libinput_device_get_sysname(device2)); status = libinput_device_config_send_events_set_mode(device1, LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); /* can't really check for much here, other than that if we pump events through libinput, none of them should be from the first device */ litest_event(litest_device, EV_REL, REL_X, 1); litest_event(litest_device, EV_REL, REL_Y, 1); litest_event(litest_device, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); while ((event = libinput_get_event(li))) { ck_assert(libinput_event_get_device(event) != device1); libinput_event_destroy(event); } litest_delete_device(litest_device); libinput_device_unref(device1); libinput_unref(li); }
END_TEST START_TEST(path_set_user_data) { struct libinput *li; int data1, data2; li = libinput_path_create_context(&simple_interface, &data1); ck_assert(li != NULL); ck_assert(libinput_get_user_data(li) == &data1); libinput_set_user_data(li, &data2); ck_assert(libinput_get_user_data(li) == &data2); libinput_unref(li); }
END_TEST /** * This test only works if there's at least one device in the system that is * assigned the default seat. Should cover the 99% case. */ START_TEST(udev_added_seat_default) { struct libinput *li; struct libinput_event *event; struct udev *udev; struct libinput_device *device; struct libinput_seat *seat; const char *seat_name; enum libinput_event_type type; int default_seat_found = 0; udev = udev_new(); ck_assert(udev != NULL); li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); while (!default_seat_found && (event = libinput_get_event(li))) { type = libinput_event_get_type(event); if (type != LIBINPUT_EVENT_DEVICE_ADDED) { libinput_event_destroy(event); continue; } device = libinput_event_get_device(event); seat = libinput_device_get_seat(device); ck_assert(seat != NULL); seat_name = libinput_seat_get_logical_name(seat); default_seat_found = !strcmp(seat_name, "default"); libinput_event_destroy(event); } ck_assert(default_seat_found); libinput_unref(li); udev_unref(udev); }
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 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) ; }
void LibInputHandler::Close() { if (fd.IsDefined()) { io_loop.Remove(fd); fd.SetUndefined(); } if (nullptr != li) libinput_unref(li); li = nullptr; if (nullptr != li_if) delete li_if; li_if = nullptr; delete udev_context; udev_context = nullptr; }
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); }
int main(int argc, char **argv) { struct libinput *li; struct tools_options options; struct libinput_event *ev; if (argc > 1) { printf("Usage: %s [--help]\n" "\n" "This tool creates a libinput context on the default seat \"seat0\"\n" "and lists all devices recognized by libinput and the configuration options.\n" "Where multiple options are possible, the default is prefixed with \"*\".\n" "\n" "This tool requires access to the /dev/input/eventX nodes.\n", program_invocation_short_name); return 1; } tools_init_options(&options); li = tools_open_backend(&options, NULL, &interface); if (!li) return 1; libinput_dispatch(li); while ((ev = libinput_get_event(li))) { if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_ADDED) print_device_notify(ev); libinput_event_destroy(ev); libinput_dispatch(li); } libinput_unref(li); return 0; }
static struct libinput * open_udev(const struct libinput_interface *interface, void *userdata, const char *seat, int verbose) { struct libinput *li; struct udev *udev = udev_new(); if (!udev) { fprintf(stderr, "Failed to initialize udev\n"); return NULL; } li = libinput_udev_create_context(interface, userdata, udev); if (!li) { fprintf(stderr, "Failed to initialize context from udev\n"); goto out; } if (verbose) { libinput_log_set_handler(li, log_handler); libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); } if (libinput_udev_assign_seat(li, seat)) { fprintf(stderr, "Failed to set seat\n"); libinput_unref(li); li = NULL; goto out; } out: udev_unref(udev); return li; }
END_TEST START_TEST(abs_device_missing_res) { struct libinput *li; struct input_absinfo absinfo[] = { { ABS_X, 0, 10, 0, 0, 10 }, { ABS_Y, 0, 10, 0, 0, 0 }, { -1, -1, -1, -1, -1, -1 } }; li = litest_create_context(); litest_disable_log_handler(li); assert_device_ignored(li, absinfo); absinfo[0].resolution = 0; absinfo[1].resolution = 20; assert_device_ignored(li, absinfo); litest_restore_log_handler(li); libinput_unref(li); }
END_TEST START_TEST(udev_seat_recycle) { struct udev *udev; struct libinput *li; 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; udev = udev_new(); ck_assert(udev != NULL); li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); 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); udev_unref(udev); }
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; }