diff --git a/Makefile.am b/Makefile.am index c2001b3c..dd98722e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,3 +6,6 @@ valgrind: (cd test; $(MAKE) valgrind) AM_DISTCHECK_CONFIGURE_FLAGS = --disable-test-run + +gcov: + (cd test; $(MAKE) gcov) diff --git a/configure.ac b/configure.ac index e611d772..25e6562a 100644 --- a/configure.ac +++ b/configure.ac @@ -262,6 +262,26 @@ AM_CONDITIONAL(BUILD_DOCS, [test "x$build_documentation" = "xyes"]) AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes]) AM_CONDITIONAL(BUILD_EVENTGUI, [test "x$build_eventgui" = "xyes"]) +####################### +# enable/disable gcov # +####################### + +AC_ARG_ENABLE([gcov], + [AS_HELP_STRING([--enable-gcov], + [Enable to enable coverage testing (default:disabled)])], + [enable_gcov="$enableval"], + [enable_gcov=no]) +if test "x$enable_gcov" != "xno"; then + GCOV_CFLAGS="-fprofile-arcs -ftest-coverage" + GCOV_LDFLAGS="-fprofile-arcs -ftest-coverage" + enable_gcov=yes +fi + +AM_CONDITIONAL([GCOV_ENABLED], [test "x$enable_gcov" != "xno"]) +AC_SUBST([GCOV_CFLAGS]) +AC_SUBST([GCOV_LDFLAGS]) + + AC_CONFIG_FILES([Makefile doc/Makefile doc/libinput.doxygen @@ -288,4 +308,5 @@ AC_MSG_RESULT([ Tests use valgrind ${VALGRIND} Tests use libunwind ${HAVE_LIBUNWIND} Build GUI event tool ${build_eventgui} + Enable gcov profiling ${enable_gcov} ]) diff --git a/src/Makefile.am b/src/Makefile.am index a2bc94c3..a7ce4720 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,13 +39,17 @@ libinput_la_LIBADD = $(MTDEV_LIBS) \ $(LIBEVDEV_LIBS) \ $(LIBWACOM_LIBS) \ libinput-util.la +libinput_la_LDFLAGS = $(GCOV_LDFLAGS) \ + -version-info $(LIBINPUT_LT_VERSION) -shared \ + -Wl,--version-script=$(srcdir)/libinput.sym libinput_la_CFLAGS = -I$(top_srcdir)/include \ $(MTDEV_CFLAGS) \ $(LIBUDEV_CFLAGS) \ $(LIBEVDEV_CFLAGS) \ $(LIBWACOM_CFLAGS) \ - $(GCC_CFLAGS) + $(GCC_CFLAGS) \ + $(GCOV_CFLAGS) EXTRA_libinput_la_DEPENDENCIES = $(srcdir)/libinput.sym libinput_util_la_SOURCES = \ @@ -53,9 +57,11 @@ libinput_util_la_SOURCES = \ libinput-util.h libinput_util_la_LIBADD = +libinput_util_la_LDFLAGS = $(GCOV_LDFLAGS) libinput_util_la_CFLAGS = -I$(top_srcdir)/include \ $(LIBUDEV_CFLAGS) \ - $(GCC_CFLAGS) + $(GCC_CFLAGS) \ + $(GCOV_CFLAGS) libfilter_la_SOURCES = \ filter.c \ @@ -64,9 +70,6 @@ libfilter_la_SOURCES = \ libfilter_la_LIBADD = libfilter_la_CFLAGS = -libinput_la_LDFLAGS = -version-info $(LIBINPUT_LT_VERSION) -shared \ - -Wl,--version-script=$(srcdir)/libinput.sym - pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libinput.pc diff --git a/src/libinput-util.c b/src/libinput-util.c index 7f0701e5..40e1e6e5 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -144,6 +144,9 @@ parse_mouse_dpi_property(const char *prop) bool is_default = false; int nread, dpi = 0, rate; + if (!prop) + return 0; + while (*prop != 0) { if (*prop == ' ') { prop++; @@ -190,6 +193,9 @@ parse_mouse_wheel_click_count_property(const char *prop) { int count = 0; + if (!prop) + return 0; + if (!safe_atoi(prop, &count) || abs(count) > 360) return 0; @@ -211,6 +217,9 @@ parse_mouse_wheel_click_angle_property(const char *prop) { int angle = 0; + if (!prop) + return 0; + if (!safe_atoi(prop, &angle) || abs(angle) > 360) return 0; @@ -230,6 +239,9 @@ parse_trackpoint_accel_property(const char *prop) { double accel; + if (!prop) + return 0.0; + if (!safe_atod(prop, &accel)) accel = 0.0; diff --git a/test/Makefile.am b/test/Makefile.am index ba05729e..5980dba0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \ $(LIBUDEV_CFLAGS) \ -I$(top_builddir)/src # for libinput-version.h -AM_CFLAGS = $(GCC_CFLAGS) +AM_CFLAGS = $(GCC_CFLAGS) $(GCOV_CFLAGS) AM_CXXFLAGS = $(GCC_CXXFLAGS) TEST_LIBS = liblitest.la $(CHECK_LIBS) $(LIBUDEV_LIBS) $(LIBEVDEV_LIBS) $(top_builddir)/src/libinput.la @@ -163,3 +163,14 @@ DISTCLEANFILES=test-suite-valgrind.log endif endif EXTRA_DIST=valgrind.suppressions + +if GCOV_ENABLED + +CLEANFILES = gcov-reports/*.gcov gcov-reports/summary.txt *.gcno *.gcda + +gcov: generate-gcov-report.sh check-TESTS + $(AM_V_GEN)$(srcdir)/generate-gcov-report.sh gcov-reports $(top_builddir)/src $(builddir) +else +gcov: + @echo "Run ./configure --enable-gcov to produce gcov reports" && false +endif diff --git a/test/generate-gcov-report.sh b/test/generate-gcov-report.sh new file mode 100755 index 00000000..2d913710 --- /dev/null +++ b/test/generate-gcov-report.sh @@ -0,0 +1,42 @@ +#!/bin/bash -e + +if [[ $# -lt 2 ]]; then + echo "Usage: ./generate-gcov-report.sh [ ... ]" + exit 1 +fi + +target_dir=$1 +shift +source_dirs=$* + +if [[ "${target_dir:0:1}" != '/' ]]; then + target_dir="$PWD/$target_dir" +fi +summary_file="$target_dir/summary.txt" + +mkdir -p "$target_dir" +rm -f "$target_dir"/*.gcov + +for dir in $source_dirs; do + pushd "$dir" > /dev/null + for file in *.c; do + find ./ -name "*${file/\.c/.gcda}" \ + \! -path "*selftest*" \ + -exec gcov {} \; > /dev/null + done + find ./ -name "*.gcov" \ + \! -path "*/`basename "$target_dir"`/*" \ + -exec mv {} "$target_dir" \; + popd > /dev/null +done + +echo "========== coverage report ========" > "$summary_file" +for file in "$target_dir"/*.gcov; do + total=`grep -v " -:" "$file" | wc -l` + missing=`grep "#####" "$file" | wc -l` + hit=$((total - missing)); + percent=$((($hit * 100)/$total)) + fname=`basename "$file"` + printf "%-50s total lines: %4s not tested: %4s (%3s%%)\n" "$fname" "$total" "$missing" "$percent">> "$summary_file" +done +echo "========== =============== ========" >> "$summary_file" diff --git a/test/litest-device-keyboard.c b/test/litest-device-keyboard.c index 07819f73..10d8f3ff 100644 --- a/test/litest-device-keyboard.c +++ b/test/litest-device-keyboard.c @@ -191,6 +191,9 @@ static int events[] = { EV_KEY, KEY_SEARCH, EV_KEY, KEY_MEDIA, EV_KEY, KEY_FN, + EV_LED, LED_NUML, + EV_LED, LED_CAPSL, + EV_LED, LED_SCROLLL, -1, -1, }; diff --git a/test/litest.c b/test/litest.c index 24baf816..10993d9f 100644 --- a/test/litest.c +++ b/test/litest.c @@ -1265,6 +1265,26 @@ litest_restore_log_handler(struct libinput *libinput) libinput_log_set_handler(libinput, litest_log_handler); } +LIBINPUT_ATTRIBUTE_PRINTF(3, 0) +static void +litest_bug_log_handler(struct libinput *libinput, + enum libinput_log_priority pri, + const char *format, + va_list args) +{ + if (strstr(format, "client bug: ") || + strstr(format, "libinput bug: ")) + return; + + litest_abort_msg("Expected bug statement in log msg, aborting.\n"); +} + +void +litest_set_log_handler_bug(struct libinput *libinput) +{ + libinput_log_set_handler(libinput, litest_bug_log_handler); +} + struct litest_device * litest_add_device_with_overrides(struct libinput *libinput, enum litest_device_type which, @@ -2748,6 +2768,8 @@ litest_is_pad_button_event(struct libinput_event *event, litest_assert_int_eq(libinput_event_tablet_pad_get_button_number(p), button); + litest_assert_int_eq(libinput_event_tablet_pad_get_button_state(p), + state); return p; } diff --git a/test/litest.h b/test/litest.h index 43103650..ccda9a42 100644 --- a/test/litest.h +++ b/test/litest.h @@ -257,6 +257,7 @@ enum litest_device_feature { LITEST_RING = 1 << 22, LITEST_STRIP = 1 << 23, LITEST_TRACKBALL = 1 << 24, + LITEST_LEDS = 1 << 25, }; struct litest_device { @@ -306,6 +307,7 @@ struct range { struct libinput *litest_create_context(void); void litest_disable_log_handler(struct libinput *libinput); void litest_restore_log_handler(struct libinput *libinput); +void litest_set_log_handler_bug(struct libinput *libinput); #define litest_add(name_, func_, ...) \ _litest_add(name_, #func_, func_, __VA_ARGS__) diff --git a/test/test-device.c b/test/test-device.c index af39508a..3fa35d8b 100644 --- a/test/test-device.c +++ b/test/test-device.c @@ -763,6 +763,20 @@ START_TEST(device_context) } END_TEST +START_TEST(device_user_data) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + void *userdata = &dev; /* not referenced */ + + ck_assert(libinput_device_get_user_data(device) == NULL); + libinput_device_set_user_data(device, userdata); + ck_assert_ptr_eq(libinput_device_get_user_data(device), userdata); + libinput_device_set_user_data(device, NULL); + ck_assert(libinput_device_get_user_data(device) == NULL); +} +END_TEST + static int open_restricted(const char *path, int flags, void *data) { int fd; @@ -1468,6 +1482,72 @@ START_TEST(device_quirks_apple_magicmouse) } END_TEST +START_TEST(device_capability_at_least_one) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + enum libinput_device_capability caps[] = { + LIBINPUT_DEVICE_CAP_KEYBOARD, + LIBINPUT_DEVICE_CAP_POINTER, + LIBINPUT_DEVICE_CAP_TOUCH, + LIBINPUT_DEVICE_CAP_TABLET_TOOL, + LIBINPUT_DEVICE_CAP_TABLET_PAD, + LIBINPUT_DEVICE_CAP_GESTURE, + }; + enum libinput_device_capability *cap; + int ncaps = 0; + + ARRAY_FOR_EACH(caps, cap) { + if (libinput_device_has_capability(device, *cap)) + ncaps++; + } + ck_assert_int_gt(ncaps, 0); + +} +END_TEST + +START_TEST(device_capability_check_invalid) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + + ck_assert(!libinput_device_has_capability(device, -1)); + ck_assert(!libinput_device_has_capability(device, 6)); + ck_assert(!libinput_device_has_capability(device, 0xffff)); + +} +END_TEST + +START_TEST(device_has_size) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + double w, h; + int rc; + + rc = libinput_device_get_size(device, &w, &h); + ck_assert_int_eq(rc, 0); + /* This matches the current set of test devices but may fail if + * newer ones are added */ + ck_assert_double_gt(w, 40); + ck_assert_double_gt(h, 20); +} +END_TEST + +START_TEST(device_has_no_size) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + double w = 45, h = 67; + int rc; + + rc = libinput_device_get_size(device, &w, &h); + ck_assert_int_eq(rc, -1); + ck_assert_double_eq(w, 45); + ck_assert_double_eq(h, 67); +} +END_TEST + void litest_setup_tests_device(void) { @@ -1498,6 +1578,7 @@ litest_setup_tests_device(void) litest_add("device:sendevents", device_disable_topsoftbutton, LITEST_TOPBUTTONPAD, LITEST_ANY); litest_add("device:id", device_ids, LITEST_ANY, LITEST_ANY); litest_add_for_device("device:context", device_context, LITEST_SYNAPTICS_CLICKPAD_X220); + litest_add_for_device("device:context", device_user_data, LITEST_SYNAPTICS_CLICKPAD_X220); litest_add("device:udev", device_get_udev_handle, LITEST_ANY, LITEST_ANY); @@ -1532,4 +1613,12 @@ litest_setup_tests_device(void) litest_add_for_device("device:quirks", device_quirks_no_abs_mt_y, LITEST_ANKER_MOUSE_KBD); litest_add_for_device("device:quirks", device_quirks_cyborg_rat_mode_button, LITEST_CYBORG_RAT); litest_add_for_device("device:quirks", device_quirks_apple_magicmouse, LITEST_MAGICMOUSE); + + litest_add("device:capability", device_capability_at_least_one, LITEST_ANY, LITEST_ANY); + litest_add("device:capability", device_capability_check_invalid, LITEST_ANY, LITEST_ANY); + + litest_add("device:size", device_has_size, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("device:size", device_has_size, LITEST_TABLET, LITEST_ANY); + litest_add("device:size", device_has_no_size, LITEST_ANY, + LITEST_TOUCHPAD|LITEST_TABLET|LITEST_TOUCH|LITEST_ABSOLUTE|LITEST_SINGLE_TOUCH); } diff --git a/test/test-keyboard.c b/test/test-keyboard.c index 780506aa..14af378d 100644 --- a/test/test-keyboard.c +++ b/test/test-keyboard.c @@ -50,18 +50,13 @@ START_TEST(keyboard_seat_key_count) NULL, NULL, NULL); } + litest_drain_events(libinput); + for (i = 0; i < num_devices; ++i) litest_keyboard_key(devices[i], KEY_A, true); libinput_dispatch(libinput); while ((ev = libinput_get_event(libinput))) { - if (libinput_event_get_type(ev) != - LIBINPUT_EVENT_KEYBOARD_KEY) { - libinput_event_destroy(ev); - libinput_dispatch(libinput); - continue; - } - kev = litest_is_keyboard_event(ev, KEY_A, LIBINPUT_KEY_STATE_PRESSED); @@ -82,13 +77,6 @@ START_TEST(keyboard_seat_key_count) libinput_dispatch(libinput); while ((ev = libinput_get_event(libinput))) { - if (libinput_event_get_type(ev) != - LIBINPUT_EVENT_KEYBOARD_KEY) { - libinput_event_destroy(ev); - libinput_dispatch(libinput); - continue; - } - kev = libinput_event_get_keyboard_event(ev); ck_assert_notnull(kev); ck_assert_int_eq(libinput_event_keyboard_get_key(kev), KEY_A); @@ -378,6 +366,62 @@ START_TEST(keyboard_no_buttons) } END_TEST +START_TEST(keyboard_leds) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + + /* we can't actually test the results here without physically + * looking at the LEDs. So all we do is trigger the code for devices + * with and without LEDs and check that it doesn't go boom + */ + + libinput_device_led_update(device, + LIBINPUT_LED_NUM_LOCK); + libinput_device_led_update(device, + LIBINPUT_LED_CAPS_LOCK); + libinput_device_led_update(device, + LIBINPUT_LED_SCROLL_LOCK); + + libinput_device_led_update(device, + LIBINPUT_LED_NUM_LOCK| + LIBINPUT_LED_CAPS_LOCK); + libinput_device_led_update(device, + LIBINPUT_LED_NUM_LOCK| + LIBINPUT_LED_CAPS_LOCK | + LIBINPUT_LED_SCROLL_LOCK); + libinput_device_led_update(device, 0); + libinput_device_led_update(device, -1); +} +END_TEST + +START_TEST(keyboard_no_scroll) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + enum libinput_config_scroll_method method; + enum libinput_config_status status; + + method = libinput_device_config_scroll_get_method(device); + ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL); + method = libinput_device_config_scroll_get_default_method(device); + ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL); + + status = libinput_device_config_scroll_set_method(device, + LIBINPUT_CONFIG_SCROLL_2FG); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + status = libinput_device_config_scroll_set_method(device, + LIBINPUT_CONFIG_SCROLL_EDGE); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + status = libinput_device_config_scroll_set_method(device, + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + status = libinput_device_config_scroll_set_method(device, + LIBINPUT_CONFIG_SCROLL_NO_SCROLL); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); +} +END_TEST + void litest_setup_tests_keyboard(void) { @@ -389,4 +433,8 @@ litest_setup_tests_keyboard(void) litest_add("keyboard:time", keyboard_time_usec, LITEST_KEYS, LITEST_ANY); litest_add("keyboard:events", keyboard_no_buttons, LITEST_KEYS, LITEST_ANY); + + litest_add("keyboard:leds", keyboard_leds, LITEST_ANY, LITEST_ANY); + + litest_add("keyboard:scroll", keyboard_no_scroll, LITEST_KEYS, LITEST_WHEEL); } diff --git a/test/test-misc.c b/test/test-misc.c index 00399d4d..ed5471db 100644 --- a/test/test-misc.c +++ b/test/test-misc.c @@ -718,6 +718,9 @@ START_TEST(dpi_parser) dpi = parse_mouse_dpi_property(tests[i].tag); ck_assert_int_eq(dpi, tests[i].expected_value); } + + dpi = parse_mouse_dpi_property(NULL); + ck_assert_int_eq(dpi, 0); } END_TEST @@ -772,6 +775,9 @@ START_TEST(wheel_click_count_parser) angle = parse_mouse_wheel_click_count_property(tests[i].tag); ck_assert_int_eq(angle, tests[i].expected_value); } + + angle = parse_mouse_wheel_click_count_property(NULL); + ck_assert_int_eq(angle, 0); } END_TEST @@ -798,6 +804,9 @@ START_TEST(trackpoint_accel_parser) accel = parse_trackpoint_accel_property(tests[i].tag); ck_assert(accel == tests[i].expected_value); } + + accel = parse_trackpoint_accel_property(NULL); + ck_assert_double_eq(accel, 0.0); } END_TEST @@ -844,6 +853,9 @@ START_TEST(dimension_prop_parser) ck_assert_int_eq(y, 0xad); } } + + success = parse_dimension_property(NULL, &x, &y); + ck_assert(success == false); } END_TEST diff --git a/test/test-pad.c b/test/test-pad.c index e2651e68..7048570e 100644 --- a/test/test-pad.c +++ b/test/test-pad.c @@ -53,6 +53,72 @@ START_TEST(pad_no_cap) } END_TEST +START_TEST(pad_time) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *ev; + struct libinput_event_tablet_pad *pev; + unsigned int code; + uint64_t time, time_usec, oldtime; + + litest_drain_events(li); + + for (code = BTN_0; code < KEY_MAX; code++) { + if (!libevdev_has_event_code(dev->evdev, EV_KEY, code)) + continue; + + litest_button_click(dev, code, 1); + litest_button_click(dev, code, 0); + libinput_dispatch(li); + + switch (code) { + case BTN_STYLUS: + litest_assert_empty_queue(li); + continue; + default: + break; + } + + break; + } + + ev = libinput_get_event(li); + pev = litest_is_pad_button_event(ev, + 0, + LIBINPUT_BUTTON_STATE_PRESSED); + time = libinput_event_tablet_pad_get_time(pev); + time_usec = libinput_event_tablet_pad_get_time_usec(pev); + + ck_assert(time != 0); + ck_assert(time == time_usec/1000); + + libinput_event_destroy(ev); + + litest_drain_events(li); + msleep(10); + + litest_button_click(dev, code, 1); + litest_button_click(dev, code, 0); + libinput_dispatch(li); + + ev = libinput_get_event(li); + pev = litest_is_pad_button_event(ev, + 0, + LIBINPUT_BUTTON_STATE_PRESSED); + + oldtime = time; + time = libinput_event_tablet_pad_get_time(pev); + time_usec = libinput_event_tablet_pad_get_time_usec(pev); + + ck_assert(time > oldtime); + ck_assert(time != 0); + ck_assert(time == time_usec/1000); + + libinput_event_destroy(ev); +} +END_TEST + START_TEST(pad_num_buttons) { struct litest_device *dev = litest_current_device(); @@ -637,6 +703,8 @@ litest_setup_tests_pad(void) litest_add("pad:cap", pad_cap, LITEST_TABLET_PAD, LITEST_ANY); litest_add("pad:cap", pad_no_cap, LITEST_ANY, LITEST_TABLET_PAD); + litest_add("pad:time", pad_time, LITEST_TABLET_PAD, LITEST_ANY); + litest_add("pad:button", pad_num_buttons, LITEST_TABLET_PAD, LITEST_ANY); litest_add("pad:button", pad_button, LITEST_TABLET_PAD, LITEST_ANY); diff --git a/test/test-path.c b/test/test-path.c index 0890d3e0..4f49d2b0 100644 --- a/test/test-path.c +++ b/test/test-path.c @@ -192,6 +192,24 @@ START_TEST(path_create_destroy) } 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_set_user_data) { struct libinput *li; @@ -310,24 +328,16 @@ START_TEST(path_added_device) struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_device *device; + enum libinput_event_type type; 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); - + 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(device != NULL); + ck_assert_notnull(device); libinput_event_destroy(event); } @@ -339,23 +349,21 @@ START_TEST(path_add_device) struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_device *device; - const char *sysname1 = NULL, *sysname2 = NULL; + char *sysname1 = NULL, *sysname2 = NULL; + enum libinput_event_type type; libinput_dispatch(li); - while ((event = libinput_get_event(li))) { - enum libinput_event_type type; - type = libinput_event_get_type(event); + 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); - 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); - } + litest_assert_empty_queue(li); device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput)); @@ -363,23 +371,19 @@ START_TEST(path_add_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) { - ck_assert(sysname2 == NULL); - device = libinput_event_get_device(event); - ck_assert(device != NULL); - sysname2 = libinput_device_get_sysname(device); - } - - libinput_event_destroy(event); - } + 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); - libinput_event_destroy(event); + free(sysname1); + free(sysname2); } END_TEST @@ -411,21 +415,23 @@ START_TEST(path_device_sysname) struct libinput_event *ev; struct libinput_device *device; const char *sysname; + enum libinput_event_type type; libinput_dispatch(dev->libinput); - while ((ev = libinput_get_event(dev->libinput))) { - if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED) - continue; + 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); - 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); + 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_event_destroy(ev); } END_TEST @@ -865,6 +871,7 @@ START_TEST(path_seat_recycle) 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, @@ -881,27 +888,21 @@ START_TEST(path_seat_recycle) 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); - } + 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); @@ -909,26 +910,21 @@ START_TEST(path_seat_recycle) 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); + 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); - } - break; - default: - break; - } - - libinput_event_destroy(ev); + 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); @@ -937,6 +933,19 @@ START_TEST(path_seat_recycle) } END_TEST +START_TEST(path_udev_assign_seat) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + int rc; + + litest_set_log_handler_bug(li); + rc = libinput_udev_assign_seat(li, "foo"); + ck_assert_int_eq(rc, -1); + litest_restore_log_handler(li); +} +END_TEST + void litest_setup_tests_path(void) { @@ -945,6 +954,7 @@ litest_setup_tests_path(void) litest_add_no_device("path:create", path_create_invalid_file); litest_add_no_device("path:create", path_create_invalid_kerneldev); litest_add_no_device("path:create", path_create_destroy); + litest_add("path:create", path_force_destroy, LITEST_ANY, LITEST_ANY); litest_add_no_device("path:create", path_set_user_data); litest_add_no_device("path:suspend", path_suspend); litest_add_no_device("path:suspend", path_double_suspend); @@ -961,4 +971,5 @@ litest_setup_tests_path(void) litest_add_for_device("path:device events", path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220); litest_add_for_device("path:device events", path_double_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220); litest_add_no_device("path:seat", path_seat_recycle); + litest_add_for_device("path:udev", path_udev_assign_seat, LITEST_SYNAPTICS_CLICKPAD_X220); } diff --git a/test/test-pointer.c b/test/test-pointer.c index e0cd0646..a706c001 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -473,6 +473,21 @@ START_TEST(pointer_button_auto_release) } END_TEST +START_TEST(pointer_button_has_no_button) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + unsigned int code; + + ck_assert(!libinput_device_has_capability(device, + LIBINPUT_DEVICE_CAP_POINTER)); + + for (code = BTN_LEFT; code < KEY_OK; code++) + ck_assert_int_eq(-1, + libinput_device_pointer_has_button(device, code)); +} +END_TEST + static inline double wheel_click_count(struct litest_device *dev, int which) { @@ -659,6 +674,35 @@ START_TEST(pointer_scroll_natural_wheel) } END_TEST +START_TEST(pointer_scroll_has_axis_invalid) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *pev; + + litest_drain_events(dev->libinput); + + if (!libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL)) + return; + + litest_event(dev, EV_REL, REL_WHEEL, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + + libinput_dispatch(li); + event = libinput_get_event(li); + pev = litest_is_axis_event(event, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + LIBINPUT_POINTER_AXIS_SOURCE_WHEEL); + + ck_assert_int_eq(libinput_event_pointer_has_axis(pev, -1), 0); + ck_assert_int_eq(libinput_event_pointer_has_axis(pev, 2), 0); + ck_assert_int_eq(libinput_event_pointer_has_axis(pev, 3), 0); + ck_assert_int_eq(libinput_event_pointer_has_axis(pev, 0xffff), 0); + libinput_event_destroy(event); +} +END_TEST + START_TEST(pointer_seat_button_count) { const int num_devices = 4; @@ -1062,7 +1106,7 @@ START_TEST(pointer_accel_defaults) speed); } - for (speed = 1.2; speed <= -2.0; speed += 0.2) { + for (speed = 1.2; speed <= 2.0; speed += 0.2) { status = libinput_device_config_accel_set_speed(device, speed); ck_assert_int_eq(status, @@ -1772,6 +1816,7 @@ litest_setup_tests_pointer(void) litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD); litest_add_no_device("pointer:button", pointer_button_auto_release); litest_add_no_device("pointer:button", pointer_seat_button_count); + litest_add_for_device("pointer:button", pointer_button_has_no_button, LITEST_KEYBOARD); litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:scroll", pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add("pointer:scroll", pointer_scroll_button_no_event_before_timeout, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); @@ -1780,6 +1825,7 @@ litest_setup_tests_pointer(void) litest_add("pointer:scroll", pointer_scroll_natural_defaults, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:scroll", pointer_scroll_natural_enable_config, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:scroll", pointer_scroll_natural_wheel, LITEST_WHEEL, LITEST_TABLET); + litest_add("pointer:scroll", pointer_scroll_has_axis_invalid, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:calibration", pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_ABSOLUTE|LITEST_PROTOCOL_A|LITEST_TABLET); diff --git a/test/test-tablet.c b/test/test-tablet.c index 60af14be..7fc4c587 100644 --- a/test/test-tablet.c +++ b/test/test-tablet.c @@ -34,6 +34,129 @@ #include "evdev-tablet.h" #include "litest.h" +START_TEST(button_down_up) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_tablet_tool *tev; + struct axis_replacement axes[] = { + { ABS_DISTANCE, 10 }, + { ABS_PRESSURE, 0 }, + { -1, -1 } + }; + + if (!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_STYLUS)) + return; + + litest_tablet_proximity_in(dev, 10, 10, axes); + litest_drain_events(li); + + litest_event(dev, EV_KEY, BTN_STYLUS, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), + BTN_STYLUS); + ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev), + LIBINPUT_BUTTON_STATE_PRESSED); + libinput_event_destroy(event); + litest_assert_empty_queue(li); + + litest_event(dev, EV_KEY, BTN_STYLUS, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), + BTN_STYLUS); + ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev), + LIBINPUT_BUTTON_STATE_RELEASED); + libinput_event_destroy(event); + litest_assert_empty_queue(li); + +} +END_TEST + +START_TEST(button_seat_count) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_tablet_tool *tev; + struct litest_device *dev2; + struct axis_replacement axes[] = { + { ABS_DISTANCE, 10 }, + { ABS_PRESSURE, 0 }, + { -1, -1 } + }; + + if (!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_STYLUS)) + return; + + dev2 = litest_add_device(li, LITEST_WACOM_CINTIQ_13HDT_PEN); + litest_tablet_proximity_in(dev, 10, 10, axes); + litest_tablet_proximity_in(dev2, 10, 10, axes); + litest_drain_events(li); + + litest_event(dev, EV_KEY, BTN_STYLUS, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev2, EV_KEY, BTN_STYLUS, 1); + litest_event(dev2, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), + BTN_STYLUS); + ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev), + LIBINPUT_BUTTON_STATE_PRESSED); + ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 1); + libinput_event_destroy(event); + + event = libinput_get_event(li); + tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), + BTN_STYLUS); + ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev), + LIBINPUT_BUTTON_STATE_PRESSED); + ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 2); + libinput_event_destroy(event); + + litest_assert_empty_queue(li); + + litest_event(dev2, EV_KEY, BTN_STYLUS, 0); + litest_event(dev2, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_STYLUS, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev), + LIBINPUT_BUTTON_STATE_RELEASED); + ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), + BTN_STYLUS); + ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 1); + libinput_event_destroy(event); + + event = libinput_get_event(li); + tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + ck_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev), + LIBINPUT_BUTTON_STATE_RELEASED); + ck_assert_int_eq(libinput_event_tablet_tool_get_button(tev), + BTN_STYLUS); + ck_assert_int_eq(libinput_event_tablet_tool_get_seat_button_count(tev), 0); + libinput_event_destroy(event); + litest_assert_empty_queue(li); + + litest_delete_device(dev2); +} +END_TEST + START_TEST(tip_down_up) { struct litest_device *dev = litest_current_device(); @@ -700,16 +823,7 @@ START_TEST(proximity_in_out) ck_assert(have_proximity_out); /* Proximity out must not emit axis events */ - litest_tablet_proximity_out(dev); - libinput_dispatch(li); - - while ((event = libinput_get_event(li))) { - enum libinput_event_type type = libinput_event_get_type(event); - - ck_assert(type != LIBINPUT_EVENT_TABLET_TOOL_AXIS); - - libinput_event_destroy(event); - } + litest_assert_empty_queue(li); } END_TEST @@ -1601,16 +1715,8 @@ START_TEST(motion_event_state) libinput_dispatch(li); - while ((event = libinput_get_event(li))) { - if (libinput_event_get_type(event) == LIBINPUT_EVENT_TABLET_TOOL_AXIS) - break; - libinput_event_destroy(event); - } - - /* pop the first event off */ - ck_assert_notnull(event); - tablet_event = libinput_event_get_tablet_tool_event(event); - ck_assert_notnull(tablet_event); + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS); last_x = libinput_event_tablet_tool_get_x(tablet_event); last_y = libinput_event_tablet_tool_get_y(tablet_event); @@ -1785,6 +1891,44 @@ START_TEST(tool_serial) } END_TEST +START_TEST(tool_id) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event_tablet_tool *tablet_event; + struct libinput_event *event; + struct libinput_tablet_tool *tool; + uint64_t tool_id; + + litest_drain_events(li); + + litest_tablet_proximity_in(dev, 10, 10, NULL); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + tool = libinput_event_tablet_tool_get_tool(tablet_event); + + ck_assert_int_eq(libinput_device_get_id_vendor(dev->libinput_device), + VENDOR_ID_WACOM); + + switch (libinput_device_get_id_product(dev->libinput_device)) { + case 0x27: /* Intuos 5 */ + tool_id = 1050626; + break; + case 0xc6: /* Cintiq 12WX */ + case 0xf4: /* Cintiq 24HD */ + case 0x333: /* Cintiq 13HD */ + tool_id = 2083; + break; + } + + ck_assert(tool_id == libinput_tablet_tool_get_tool_id(tool)); + libinput_event_destroy(event); +} +END_TEST + START_TEST(serial_changes_tool) { struct litest_device *dev = litest_current_device(); @@ -1882,11 +2026,42 @@ START_TEST(tool_ref) } END_TEST +START_TEST(tool_user_data) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event_tablet_tool *tablet_event; + struct libinput_event *event; + struct libinput_tablet_tool *tool; + void *userdata = &dev; /* not dereferenced */ + + litest_drain_events(li); + + litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1); + litest_event(dev, EV_MSC, MSC_SERIAL, 1000); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + tool = libinput_event_tablet_tool_get_tool(tablet_event); + ck_assert_notnull(tool); + + ck_assert(libinput_tablet_tool_get_user_data(tool) == NULL); + libinput_tablet_tool_set_user_data(tool, userdata); + ck_assert(libinput_tablet_tool_get_user_data(tool) == userdata); + libinput_tablet_tool_set_user_data(tool, NULL); + ck_assert(libinput_tablet_tool_get_user_data(tool) == NULL); + + libinput_event_destroy(event); +} +END_TEST + START_TEST(pad_buttons_ignored) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; - struct libinput_event *event; struct axis_replacement axes[] = { { ABS_DISTANCE, 10 }, { ABS_PRESSURE, 0 }, @@ -1904,15 +2079,12 @@ START_TEST(pad_buttons_ignored) libinput_dispatch(li); } - while ((event = libinput_get_event(li))) { - ck_assert_int_ne(libinput_event_get_type(event), - LIBINPUT_EVENT_TABLET_TOOL_BUTTON); - libinput_event_destroy(event); - libinput_dispatch(li); - } + litest_assert_empty_queue(li); /* same thing while in prox */ litest_tablet_proximity_in(dev, 10, 10, axes); + litest_drain_events(li); + for (button = BTN_0; button < BTN_MOUSE; button++) { litest_event(dev, EV_KEY, button, 1); litest_event(dev, EV_SYN, SYN_REPORT, 0); @@ -1920,15 +2092,8 @@ START_TEST(pad_buttons_ignored) litest_event(dev, EV_SYN, SYN_REPORT, 0); libinput_dispatch(li); } - litest_tablet_proximity_out(dev); - libinput_dispatch(li); - while ((event = libinput_get_event(li))) { - ck_assert_int_ne(libinput_event_get_type(event), - LIBINPUT_EVENT_TABLET_TOOL_BUTTON); - libinput_event_destroy(event); - libinput_dispatch(li); - } + litest_assert_empty_queue(li); } END_TEST @@ -2104,6 +2269,16 @@ START_TEST(tool_delayed_serial) } END_TEST +START_TEST(tool_capability) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + + ck_assert(libinput_device_has_capability(device, + LIBINPUT_DEVICE_CAP_TABLET_TOOL)); +} +END_TEST + START_TEST(tool_capabilities) { struct libinput *li = litest_create_context(); @@ -3084,6 +3259,7 @@ START_TEST(tablet_pressure_min_max) libinput_dispatch(li); event = libinput_get_event(li); tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS); + ck_assert(libinput_event_tablet_tool_pressure_has_changed(tev)); p = libinput_event_tablet_tool_get_pressure(tev); ck_assert_double_ge(p, 0.0); libinput_event_destroy(event); @@ -3098,6 +3274,7 @@ START_TEST(tablet_pressure_min_max) libinput_dispatch(li); event = libinput_get_event(li); tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS); + ck_assert(libinput_event_tablet_tool_pressure_has_changed(tev)); p = libinput_event_tablet_tool_get_pressure(tev); ck_assert_double_ge(p, 1.0); libinput_event_destroy(event); @@ -3130,6 +3307,7 @@ START_TEST(tablet_pressure_range) event = libinput_get_event(li); tev = litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS); p = libinput_event_tablet_tool_get_pressure(tev); + p = libinput_event_tablet_tool_get_pressure(tev); ck_assert_double_ge(p, 0.0); ck_assert_double_le(p, 1.0); libinput_event_destroy(event); @@ -4009,10 +4187,13 @@ void litest_setup_tests_tablet(void) { litest_add("tablet:tool", tool_ref, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); + litest_add("tablet:tool", tool_user_data, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); + litest_add("tablet:tool", tool_capability, LITEST_TABLET, LITEST_ANY); litest_add_no_device("tablet:tool", tool_capabilities); litest_add("tablet:tool", tool_in_prox_before_start, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tool_serial", tool_unique, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); litest_add("tablet:tool_serial", tool_serial, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); + litest_add("tablet:tool_serial", tool_id, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); litest_add("tablet:tool_serial", serial_changes_tool, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); litest_add("tablet:tool_serial", invalid_serials, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY); litest_add_no_device("tablet:tool_serial", tools_with_serials); @@ -4029,6 +4210,8 @@ litest_setup_tests_tablet(void) litest_add("tablet:proximity", proximity_range_button_click, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY); litest_add("tablet:proximity", proximity_range_button_press, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY); litest_add("tablet:proximity", proximity_range_button_release, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY); + litest_add("tablet:button", button_down_up, LITEST_TABLET, LITEST_ANY); + litest_add("tablet:button", button_seat_count, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tip", tip_down_up, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tip", tip_down_prox_in, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tip", tip_up_prox_out, LITEST_TABLET, LITEST_ANY); diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c index 7acd0bad..abbcb7f0 100644 --- a/test/test-touchpad-tap.c +++ b/test/test-touchpad-tap.c @@ -1788,6 +1788,26 @@ START_TEST(touchpad_tap_default_map) } END_TEST +START_TEST(touchpad_tap_map_unsupported) +{ + struct litest_device *dev = litest_current_device(); + enum libinput_config_tap_button_map map; + enum libinput_config_status status; + + map = libinput_device_config_tap_get_button_map(dev->libinput_device); + ck_assert_int_eq(map, LIBINPUT_CONFIG_TAP_MAP_LRM); + map = libinput_device_config_tap_get_default_button_map(dev->libinput_device); + ck_assert_int_eq(map, LIBINPUT_CONFIG_TAP_MAP_LRM); + + status = libinput_device_config_tap_set_button_map(dev->libinput_device, + LIBINPUT_CONFIG_TAP_MAP_LMR); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + status = libinput_device_config_tap_set_button_map(dev->libinput_device, + LIBINPUT_CONFIG_TAP_MAP_LRM); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); +} +END_TEST + START_TEST(touchpad_tap_set_map) { struct litest_device *dev = litest_current_device(); @@ -1886,6 +1906,8 @@ START_TEST(touchpad_drag_default_disabled) ck_assert_int_eq(libinput_device_config_tap_get_default_drag_enabled(dev->libinput_device), LIBINPUT_CONFIG_DRAG_DISABLED); + ck_assert_int_eq(libinput_device_config_tap_get_drag_enabled(dev->libinput_device), + LIBINPUT_CONFIG_DRAG_DISABLED); } END_TEST @@ -1897,6 +1919,8 @@ START_TEST(touchpad_drag_default_enabled) ck_assert_int_eq(libinput_device_config_tap_get_default_drag_enabled(dev->libinput_device), LIBINPUT_CONFIG_DRAG_ENABLED); + ck_assert_int_eq(libinput_device_config_tap_get_drag_enabled(dev->libinput_device), + LIBINPUT_CONFIG_DRAG_ENABLED); } END_TEST @@ -1911,6 +1935,24 @@ START_TEST(touchpad_drag_config_invalid) } END_TEST +START_TEST(touchpad_drag_config_unsupported) +{ + struct litest_device *dev = litest_current_device(); + enum libinput_config_status status; + + ck_assert_int_eq(libinput_device_config_tap_get_default_drag_enabled(dev->libinput_device), + LIBINPUT_CONFIG_DRAG_DISABLED); + ck_assert_int_eq(libinput_device_config_tap_get_drag_enabled(dev->libinput_device), + LIBINPUT_CONFIG_DRAG_DISABLED); + status = libinput_device_config_tap_set_drag_enabled(dev->libinput_device, + LIBINPUT_CONFIG_DRAG_ENABLED); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + status = libinput_device_config_tap_set_drag_enabled(dev->libinput_device, + LIBINPUT_CONFIG_DRAG_DISABLED); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); +} +END_TEST + START_TEST(touchpad_drag_config_enabledisable) { struct litest_device *dev = litest_current_device(); @@ -2171,6 +2213,7 @@ litest_setup_tests_touchpad_tap(void) litest_add("tap:config", touchpad_tap_is_not_available, LITEST_ANY, LITEST_TOUCHPAD); litest_add("tap:config", touchpad_tap_default_map, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("tap:config", touchpad_tap_map_unsupported, LITEST_ANY, LITEST_TOUCHPAD); litest_add("tap:config", touchpad_tap_set_map, LITEST_TOUCHPAD, LITEST_ANY); litest_add("tap:config", touchpad_tap_set_map_no_tapping, LITEST_ANY, LITEST_TOUCHPAD); litest_add("tap:config", touchpad_tap_map_delayed, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); @@ -2184,6 +2227,7 @@ litest_setup_tests_touchpad_tap(void) litest_add("tap:drag", touchpad_drag_default_disabled, LITEST_ANY, LITEST_TOUCHPAD); litest_add("tap:drag", touchpad_drag_default_enabled, LITEST_TOUCHPAD, LITEST_BUTTON); litest_add("tap:drag", touchpad_drag_config_invalid, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("tap:drag", touchpad_drag_config_unsupported, LITEST_ANY, LITEST_TOUCHPAD); litest_add("tap:drag", touchpad_drag_config_enabledisable, LITEST_TOUCHPAD, LITEST_ANY); litest_add("tap:drag", touchpad_drag_disabled, LITEST_TOUCHPAD, LITEST_ANY); litest_add("tap:drag", touchpad_drag_disabled_immediate, LITEST_TOUCHPAD, LITEST_ANY); diff --git a/test/test-touchpad.c b/test/test-touchpad.c index 267d9a45..ee8cd7f7 100644 --- a/test/test-touchpad.c +++ b/test/test-touchpad.c @@ -1335,6 +1335,9 @@ START_TEST(touchpad_left_handed_clickpad) struct libinput *li = dev->libinput; enum libinput_config_status status; + if (!libinput_device_config_left_handed_is_available(d)) + return; + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); @@ -1386,6 +1389,9 @@ START_TEST(touchpad_left_handed_clickfinger) struct libinput *li = dev->libinput; enum libinput_config_status status; + if (!libinput_device_config_left_handed_is_available(d)) + return; + status = libinput_device_config_left_handed_set(d, 1); ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); @@ -1427,6 +1433,9 @@ START_TEST(touchpad_left_handed_tapping) struct libinput *li = dev->libinput; enum libinput_config_status status; + if (!libinput_device_config_left_handed_is_available(d)) + return; + litest_enable_tap(dev->libinput_device); status = libinput_device_config_left_handed_set(d, 1); @@ -1458,6 +1467,9 @@ START_TEST(touchpad_left_handed_tapping_2fg) struct libinput *li = dev->libinput; enum libinput_config_status status; + if (!libinput_device_config_left_handed_is_available(d)) + return; + litest_enable_tap(dev->libinput_device); status = libinput_device_config_left_handed_set(d, 1); @@ -1491,6 +1503,9 @@ START_TEST(touchpad_left_handed_delayed) struct libinput *li = dev->libinput; enum libinput_config_status status; + if (!libinput_device_config_left_handed_is_available(d)) + return; + litest_drain_events(li); litest_button_click(dev, BTN_LEFT, 1); libinput_dispatch(li); @@ -1543,6 +1558,9 @@ START_TEST(touchpad_left_handed_clickpad_delayed) struct libinput *li = dev->libinput; enum libinput_config_status status; + if (!libinput_device_config_left_handed_is_available(d)) + return; + litest_drain_events(li); litest_touch_down(dev, 0, 10, 90); litest_button_click(dev, BTN_LEFT, 1); diff --git a/test/test-udev.c b/test/test-udev.c index ba6a10d9..18627663 100644 --- a/test/test-udev.c +++ b/test/test-udev.c @@ -506,6 +506,60 @@ START_TEST(udev_seat_recycle) } END_TEST +START_TEST(udev_path_add_device) +{ + struct udev *udev; + struct libinput *li; + struct libinput_device *device; + + 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); + + litest_set_log_handler_bug(li); + device = libinput_path_add_device(li, "/dev/input/event0"); + ck_assert(device == NULL); + litest_restore_log_handler(li); + + libinput_unref(li); + udev_unref(udev); +} +END_TEST + +START_TEST(udev_path_remove_device) +{ + struct udev *udev; + struct libinput *li; + struct libinput_device *device; + struct libinput_event *event; + + 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); + + litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED, -1); + event = libinput_get_event(li); + device = libinput_event_get_device(event); + ck_assert(device != NULL); + + /* no effect bug a bug log msg */ + litest_set_log_handler_bug(li); + libinput_path_remove_device(device); + litest_restore_log_handler(li); + + libinput_event_destroy(event); + libinput_unref(li); + udev_unref(udev); +} +END_TEST + void litest_setup_tests_udev(void) { @@ -522,4 +576,7 @@ litest_setup_tests_udev(void) litest_add_for_device("udev:suspend", udev_suspend_resume, LITEST_SYNAPTICS_CLICKPAD_X220); litest_add_for_device("udev:device events", udev_device_sysname, LITEST_SYNAPTICS_CLICKPAD_X220); litest_add_for_device("udev:seat", udev_seat_recycle, LITEST_SYNAPTICS_CLICKPAD_X220); + + litest_add_no_device("udev:path", udev_path_add_device); + litest_add_for_device("udev:path", udev_path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220); }