END_TEST START_TEST(trackpoint_palmdetect_resume_touch) { struct litest_device *trackpoint = litest_current_device(); struct litest_device *touchpad; struct libinput *li = trackpoint->libinput; int i; touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C); litest_drain_events(li); for (i = 0; i < 10; i++) { litest_event(trackpoint, EV_REL, REL_X, 1); litest_event(trackpoint, EV_REL, REL_Y, 1); litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); } litest_drain_events(li); litest_touch_down(touchpad, 0, 30, 30); litest_touch_move_to(touchpad, 0, 30, 30, 80, 80, 10, 1); litest_assert_empty_queue(li); litest_timeout_trackpoint(); libinput_dispatch(li); /* touch started after last tp event, expect resume */ litest_touch_move_to(touchpad, 0, 80, 80, 30, 30, 10, 1); litest_touch_up(touchpad, 0); litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_delete_device(touchpad); }
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(path_device_sysname) { struct litest_device *dev = litest_current_device(); struct libinput_event *ev; struct libinput_device *device; const char *sysname; enum libinput_event_type type; libinput_dispatch(dev->libinput); ev = libinput_get_event(dev->libinput); ck_assert_notnull(ev); type = libinput_event_get_type(ev); ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); device = libinput_event_get_device(ev); ck_assert_notnull(device); 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); }
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(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(path_added_seat) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_device *device; struct libinput_seat *seat; const char *seat_name; enum libinput_event_type type; libinput_dispatch(li); event = libinput_get_event(li); ck_assert(event != NULL); type = libinput_event_get_type(event); ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED); device = libinput_event_get_device(event); seat = libinput_device_get_seat(device); ck_assert(seat != NULL); seat_name = libinput_seat_get_logical_name(seat); ck_assert_str_eq(seat_name, "default"); libinput_event_destroy(event); }
END_TEST START_TEST(path_added_device) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_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_ADDED) { break; } libinput_event_destroy(event); } ck_assert(event != NULL); device = libinput_event_get_device(event); ck_assert(device != NULL); libinput_event_destroy(event); }
END_TEST START_TEST(device_disable_events_pending) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_device *device; enum libinput_config_status status; struct libinput_event *event; int i; device = dev->libinput_device; litest_drain_events(li); /* put a couple of events in the queue, enough to feed the ptraccel trackers */ for (i = 0; i < 10; i++) { litest_event(dev, EV_REL, REL_X, 10); litest_event(dev, EV_SYN, SYN_REPORT, 0); } libinput_dispatch(li); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); /* expect above events */ litest_wait_for_event(li); while ((event = libinput_get_event(li)) != NULL) { ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_MOTION); libinput_event_destroy(event); } }
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_create_from_udev(&simple_interface, NULL, udev, "seatdoesntexist"); ck_assert(li != NULL); 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_destroy(li); udev_unref(udev); }
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_create_from_udev(&simple_interface, NULL, udev, "seat0"); ck_assert(li != NULL); 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_destroy(li); udev_unref(udev); }
END_TEST static void test_button_event(struct litest_device *dev, int button, int state) { struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_event_pointer *ptrev; litest_event(dev, EV_KEY, button, state); litest_event(dev, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); event = libinput_get_event(li); ck_assert(event != NULL); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_BUTTON); ptrev = libinput_event_get_pointer_event(event); ck_assert(ptrev != NULL); ck_assert_int_eq(libinput_event_pointer_get_button(ptrev), button); ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrev), state ? LIBINPUT_POINTER_BUTTON_STATE_PRESSED : LIBINPUT_POINTER_BUTTON_STATE_RELEASED); libinput_event_destroy(event); }
END_TEST START_TEST(udev_double_resume) { 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 */ ck_assert_int_ge(libinput_dispatch(li), 0); event = libinput_get_event(li); ck_assert(event != NULL); libinput_suspend(li); libinput_resume(li); libinput_resume(li); libinput_event_destroy(event); libinput_unref(li); udev_unref(udev); }
END_TEST START_TEST(trackpoint_palmdetect_require_min_events) { struct litest_device *trackpoint = litest_current_device(); struct litest_device *touchpad; struct libinput *li = trackpoint->libinput; touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C); litest_drain_events(li); /* A single event does not trigger palm detection */ litest_event(trackpoint, EV_REL, REL_X, 1); litest_event(trackpoint, EV_REL, REL_Y, 1); litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); litest_drain_events(li); litest_touch_down(touchpad, 0, 30, 30); litest_touch_move_to(touchpad, 0, 30, 30, 80, 80, 10, 1); litest_touch_up(touchpad, 0); litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_delete_device(touchpad); }
END_TEST START_TEST(trackpoint_topsoftbuttons_left_handed_both) { struct litest_device *touchpad = litest_current_device(); struct litest_device *trackpoint; struct libinput *li = touchpad->libinput; enum libinput_config_status status; struct libinput_event *event; struct libinput_device *device; trackpoint = litest_add_device(li, LITEST_TRACKPOINT); litest_drain_events(li); /* touchpad left-handed, trackpoint left-handed */ status = libinput_device_config_left_handed_set( touchpad->libinput_device, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); status = libinput_device_config_left_handed_set( trackpoint->libinput_device, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_touch_down(touchpad, 0, 5, 5); libinput_dispatch(li); litest_button_click(touchpad, BTN_LEFT, true); libinput_dispatch(li); event = libinput_get_event(li); litest_is_button_event(event, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED); device = libinput_event_get_device(event); ck_assert(device == trackpoint->libinput_device); libinput_event_destroy(event); litest_button_click(touchpad, BTN_LEFT, false); libinput_dispatch(li); event = libinput_get_event(li); litest_is_button_event(event, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED); device = libinput_event_get_device(event); ck_assert(device == trackpoint->libinput_device); libinput_event_destroy(event); litest_delete_device(trackpoint); }
END_TEST START_TEST(device_disable_release_tap) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_device *device; enum libinput_config_status status; device = dev->libinput_device; libinput_device_config_tap_set_enabled(device, LIBINPUT_CONFIG_TAP_ENABLED); litest_drain_events(li); litest_touch_down(dev, 0, 50, 50); litest_touch_up(dev, 0); libinput_dispatch(li); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); /* tap happened before suspending, so we still expect the event */ litest_timeout_tap(); litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED); litest_assert_empty_queue(li); /* resume, make sure we don't get anything */ status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); libinput_dispatch(li); litest_assert_empty_queue(li); }
inline void LibInputHandler::HandlePendingEvents() { libinput_dispatch(li); for (libinput_event *li_event = libinput_get_event(li); nullptr != li_event; li_event = libinput_get_event(li)) HandleEvent(li_event); }
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(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); }
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; }
END_TEST START_TEST(device_disable) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_device *device; enum libinput_config_status status; struct libinput_event *event; struct litest_device *tmp; device = dev->libinput_device; litest_drain_events(li); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); /* no event from disabling */ litest_assert_empty_queue(li); /* no event from disabled device */ litest_event(dev, EV_REL, REL_X, 10); litest_event(dev, EV_SYN, SYN_REPORT, 0); litest_assert_empty_queue(li); /* create a new device so the resumed fd isn't the same as the suspended one */ tmp = litest_add_device(li, LITEST_KEYBOARD); ck_assert_notnull(tmp); litest_drain_events(li); /* no event from resuming */ status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_assert_empty_queue(li); /* event from renabled device */ litest_event(dev, EV_REL, REL_X, 10); litest_event(dev, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); event = libinput_get_event(li); ck_assert_notnull(event); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_MOTION); libinput_event_destroy(event); litest_delete_device(tmp); }
END_TEST START_TEST(device_disable_release_tap_n_drag) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_device *device; enum libinput_config_status status; device = dev->libinput_device; libinput_device_config_tap_set_enabled(device, LIBINPUT_CONFIG_TAP_ENABLED); litest_drain_events(li); litest_touch_down(dev, 0, 50, 50); litest_touch_up(dev, 0); litest_touch_down(dev, 0, 50, 50); libinput_dispatch(li); litest_timeout_tap(); libinput_dispatch(li); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); libinput_dispatch(li); litest_touch_up(dev, 0); litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED); litest_assert_empty_queue(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(device_disable_release_softbutton) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_device *device; enum libinput_config_status status; device = dev->libinput_device; litest_drain_events(li); litest_touch_down(dev, 0, 90, 90); litest_button_click(dev, BTN_LEFT, true); /* make sure softbutton works */ litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED); /* disable */ status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED); litest_assert_empty_queue(li); litest_button_click(dev, BTN_LEFT, false); litest_touch_up(dev, 0); litest_assert_empty_queue(li); /* resume, make sure we don't get anything */ status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); libinput_dispatch(li); litest_assert_empty_queue(li); }
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_added_device) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_device *device; 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); libinput_event_destroy(event); }
END_TEST static void test_wheel_event(struct litest_device *dev, int which, int amount) { struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_event_pointer *ptrev; /* the current evdev implementation scales the scroll wheel events up by a factor 10 */ const int scroll_step = 10; int expected = amount * scroll_step; /* mouse scroll wheels are 'upside down' */ if (which == REL_WHEEL) amount *= -1; litest_event(dev, EV_REL, which, amount); litest_event(dev, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); event = libinput_get_event(li); ck_assert(event != NULL); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_AXIS); ptrev = libinput_event_get_pointer_event(event); ck_assert(ptrev != NULL); ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), which == REL_WHEEL ? LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL : LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL); ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), li_fixed_from_int(expected)); libinput_event_destroy(event); }
static void test_relative_event(struct litest_device *dev, int dx, int dy) { struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_event_pointer *ptrev; litest_event(dev, EV_REL, REL_X, dx); litest_event(dev, EV_REL, REL_Y, dy); litest_event(dev, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); event = libinput_get_event(li); ck_assert(event != NULL); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_MOTION); ptrev = libinput_event_get_pointer_event(event); ck_assert(ptrev != NULL); ck_assert_int_eq(libinput_event_pointer_get_dx(ptrev), li_fixed_from_int(dx)); ck_assert_int_eq(libinput_event_pointer_get_dy(ptrev), li_fixed_from_int(dy)); libinput_event_destroy(event); }
static int input_event(int fd, uint32_t mask, void *data) { (void)fd, (void)mask; struct input *input = data; if (libinput_dispatch(input->handle) != 0) wlc_log(WLC_LOG_WARN, "Failed to dispatch libinput"); struct libinput_event *event; while ((event = libinput_get_event(input->handle))) { struct libinput *handle = libinput_event_get_context(event); struct libinput_device *device = libinput_event_get_device(event); (void)handle; switch (libinput_event_get_type(event)) { case LIBINPUT_EVENT_DEVICE_ADDED: WLC_INTERFACE_EMIT(input.created, device); break; case LIBINPUT_EVENT_DEVICE_REMOVED: WLC_INTERFACE_EMIT(input.destroyed, device); break; case LIBINPUT_EVENT_POINTER_MOTION: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_MOTION; ev.time = libinput_event_pointer_get_time(pev); ev.motion.dx = libinput_event_pointer_get_dx(pev); ev.motion.dy = libinput_event_pointer_get_dy(pev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_MOTION_ABSOLUTE; ev.time = libinput_event_pointer_get_time(pev); ev.motion_abs.x = pointer_abs_x; ev.motion_abs.y = pointer_abs_y; ev.motion_abs.internal = pev; wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_POINTER_BUTTON: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_BUTTON; ev.time = libinput_event_pointer_get_time(pev); ev.button.code = libinput_event_pointer_get_button(pev); ev.button.state = (enum wl_pointer_button_state)libinput_event_pointer_get_button_state(pev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_POINTER_AXIS: { struct libinput_event_pointer *pev = libinput_event_get_pointer_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_SCROLL; ev.time = libinput_event_pointer_get_time(pev); #if LIBINPUT_VERSION_MAJOR == 0 && LIBINPUT_VERSION_MINOR < 8 /* < libinput 0.8.x (at least to 0.6.x) */ const enum wl_pointer_axis axis = libinput_event_pointer_get_axis(pev); ev.scroll.amount[(axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)] = libinput_event_pointer_get_axis_value(pev); ev.scroll.axis_bits |= (axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL ? WLC_SCROLL_AXIS_HORIZONTAL : WLC_SCROLL_AXIS_VERTICAL); #else /* > libinput 0.8.0 */ if (libinput_event_pointer_has_axis(pev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { ev.scroll.amount[0] = libinput_event_pointer_get_axis_value(pev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); ev.scroll.axis_bits |= WLC_SCROLL_AXIS_VERTICAL; } if (libinput_event_pointer_has_axis(pev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { ev.scroll.amount[1] = libinput_event_pointer_get_axis_value(pev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); ev.scroll.axis_bits |= WLC_SCROLL_AXIS_HORIZONTAL; } #endif // We should get other axis information from libinput as well, like source (finger, wheel) (v0.8) wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_KEYBOARD_KEY: { struct libinput_event_keyboard *kev = libinput_event_get_keyboard_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_KEY; ev.time = libinput_event_keyboard_get_time(kev); ev.key.code = libinput_event_keyboard_get_key(kev); ev.key.state = (enum wl_keyboard_key_state)libinput_event_keyboard_get_key_state(kev); ev.device = device; wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_TOUCH_UP: { struct libinput_event_touch *tev = libinput_event_get_touch_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_TOUCH; ev.time = libinput_event_touch_get_time(tev); ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event)); ev.touch.slot = libinput_event_touch_get_seat_slot(tev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_TOUCH_DOWN: case LIBINPUT_EVENT_TOUCH_MOTION: { struct libinput_event_touch *tev = libinput_event_get_touch_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_TOUCH; ev.time = libinput_event_touch_get_time(tev); ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event)); ev.touch.x = touch_abs_x; ev.touch.y = touch_abs_y; ev.touch.internal = tev; ev.touch.slot = libinput_event_touch_get_seat_slot(tev); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; case LIBINPUT_EVENT_TOUCH_FRAME: case LIBINPUT_EVENT_TOUCH_CANCEL: { struct libinput_event_touch *tev = libinput_event_get_touch_event(event); struct wlc_input_event ev = {0}; ev.type = WLC_INPUT_EVENT_TOUCH; ev.time = libinput_event_touch_get_time(tev); ev.touch.type = wlc_touch_type_for_libinput_type(libinput_event_get_type(event)); wl_signal_emit(&wlc_system_signals()->input, &ev); } break; default: break; } libinput_event_destroy(event); } return 0; }
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); }