END_TEST START_TEST(device_disable_release_buttons) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_device *device; struct libinput_event *event; struct libinput_event_pointer *ptrevent; enum libinput_config_status status; device = dev->libinput_device; litest_button_click(dev, BTN_LEFT, true); litest_drain_events(li); litest_assert_empty_queue(li); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_wait_for_event(li); event = libinput_get_event(li); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_BUTTON); ptrevent = libinput_event_get_pointer_event(event); ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent), BTN_LEFT); ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent), LIBINPUT_BUTTON_STATE_RELEASED); libinput_event_destroy(event); litest_assert_empty_queue(li); }
END_TEST START_TEST(device_disable_release_keys) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_device *device; struct libinput_event *event; struct libinput_event_keyboard *kbdevent; enum libinput_config_status status; device = dev->libinput_device; litest_button_click(dev, KEY_A, true); litest_drain_events(li); litest_assert_empty_queue(li); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); litest_wait_for_event(li); event = libinput_get_event(li); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_KEYBOARD_KEY); kbdevent = libinput_event_get_keyboard_event(event); ck_assert_int_eq(libinput_event_keyboard_get_key(kbdevent), KEY_A); ck_assert_int_eq(libinput_event_keyboard_get_key_state(kbdevent), LIBINPUT_KEY_STATE_RELEASED); libinput_event_destroy(event); litest_assert_empty_queue(li); }
END_TEST START_TEST(device_disable_touchpad) { 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); 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); litest_touch_down(dev, 0, 50, 50); litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10, 0); litest_touch_up(dev, 0); litest_assert_empty_queue(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); }
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_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(trackpoint_middlebutton_noscroll) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; struct libinput_event *event; /* Disable middle button scrolling */ libinput_device_config_scroll_set_method(dev->libinput_device, LIBINPUT_CONFIG_SCROLL_NO_SCROLL); litest_drain_events(li); /* A long middle button click + motion should get reported normally now */ litest_button_scroll(dev, BTN_MIDDLE, 0, 10); litest_assert_button_event(li, BTN_MIDDLE, 1); event = libinput_get_event(li); ck_assert(event != NULL); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_MOTION); libinput_event_destroy(event); litest_assert_button_event(li, BTN_MIDDLE, 0); litest_assert_empty_queue(li); /* Restore default scroll behavior */ libinput_device_config_scroll_set_method(dev->libinput_device, libinput_device_config_scroll_get_default_method( dev->libinput_device)); }
END_TEST START_TEST(trackpoint_scroll) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; litest_drain_events(li); litest_button_scroll(dev, BTN_MIDDLE, 1, 6); litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6); litest_button_scroll(dev, BTN_MIDDLE, 1, -7); litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -7); litest_button_scroll(dev, BTN_MIDDLE, 8, 1); litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 8); litest_button_scroll(dev, BTN_MIDDLE, -9, 1); litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9); /* scroll smaller than the threshold should not generate events */ litest_button_scroll(dev, BTN_MIDDLE, 1, 1); /* long middle press without movement should not generate events */ litest_button_scroll(dev, BTN_MIDDLE, 0, 0); litest_assert_empty_queue(li); }
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(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); }
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(device_disable_topsoftbutton) { struct litest_device *dev = litest_current_device(); struct litest_device *trackpoint; struct libinput *li = dev->libinput; struct libinput_device *device; enum libinput_config_status status; struct libinput_event *event; struct libinput_event_pointer *ptrevent; device = dev->libinput_device; trackpoint = litest_add_device(li, LITEST_TRACKPOINT); 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_touch_down(dev, 0, 90, 10); litest_button_click(dev, BTN_LEFT, true); litest_button_click(dev, BTN_LEFT, false); litest_touch_up(dev, 0); litest_wait_for_event(li); event = libinput_get_event(li); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_BUTTON); ck_assert_ptr_eq(libinput_event_get_device(event), trackpoint->libinput_device); ptrevent = libinput_event_get_pointer_event(event); ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent), BTN_RIGHT); ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent), LIBINPUT_BUTTON_STATE_PRESSED); libinput_event_destroy(event); event = libinput_get_event(li); ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_BUTTON); ck_assert_ptr_eq(libinput_event_get_device(event), trackpoint->libinput_device); ptrevent = libinput_event_get_pointer_event(event); ck_assert_int_eq(libinput_event_pointer_get_button(ptrevent), BTN_RIGHT); ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrevent), LIBINPUT_BUTTON_STATE_RELEASED); libinput_event_destroy(event); litest_assert_empty_queue(li); litest_delete_device(trackpoint); }
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_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 START_TEST(device_double_enable) { 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); status = libinput_device_config_send_events_set_mode(device, LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); 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); }
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; enum libinput_event_type type; 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); ev = libinput_get_event(li); 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(device != NULL); saved_seat = libinput_device_get_seat(device); libinput_seat_set_user_data(saved_seat, &data); libinput_seat_ref(saved_seat); libinput_event_destroy(ev); ck_assert(saved_seat != NULL); litest_assert_empty_queue(li); libinput_suspend(li); litest_drain_events(li); libinput_resume(li); libinput_dispatch(li); ev = libinput_get_event(li); 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(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); } libinput_event_destroy(ev); ck_assert(found == 1); libinput_unref(li); libevdev_uinput_destroy(uinput); }