diff --git a/test/Makefile.am b/test/Makefile.am index c1c73b77..8b3d4dba 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,7 +16,7 @@ liblitest_la_SOURCES = \ litest-wacom-touch.c \ litest.c -run_tests = test-udev test-path +run_tests = test-udev test-path test-pointer build_tests = test-build-linker test-build-pedantic-c99 test-build-std-gnuc90 noinst_PROGRAMS = $(build_tests) $(run_tests) @@ -32,6 +32,11 @@ test_path_CFLAGS = $(AM_CPPFLAGS) test_path_LDADD = $(TEST_LIBS) test_path_LDFLAGS = -static +test_pointer_SOURCES = pointer.c +test_pointer_CFLAGS = $(AM_CPPFLAGS) +test_pointer_LDADD = $(TEST_LIBS) +test_pointer_LDFLAGS = -static + # build-test only test_build_pedantic_c99_SOURCES = build-pedantic.c test_build_pedantic_c99_CFLAGS = $(AM_CPPFLAGS) -std=c99 -pedantic -Werror diff --git a/test/pointer.c b/test/pointer.c new file mode 100644 index 00000000..e864169c --- /dev/null +++ b/test/pointer.c @@ -0,0 +1,193 @@ +/* + * Copyright © 2013 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include "libinput-util.h" +#include "litest.h" + +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); +} + +START_TEST(pointer_motion_relative) +{ + struct litest_device *dev = litest_current_device(); + + litest_drain_events(dev->libinput); + + test_relative_event(dev, 1, 0); + test_relative_event(dev, 1, 1); + test_relative_event(dev, 1, -1); + test_relative_event(dev, 0, 1); + + test_relative_event(dev, -1, 0); + test_relative_event(dev, -1, 1); + test_relative_event(dev, -1, -1); + test_relative_event(dev, 0, -1); +} +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); +} + +START_TEST(pointer_button) +{ + struct litest_device *dev = litest_current_device(); + + litest_drain_events(dev->libinput); + + test_button_event(dev, BTN_LEFT, 1); + test_button_event(dev, BTN_LEFT, 0); + + /* press it twice for good measure */ + test_button_event(dev, BTN_LEFT, 1); + test_button_event(dev, BTN_LEFT, 0); + + if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_RIGHT)) { + test_button_event(dev, BTN_RIGHT, 1); + test_button_event(dev, BTN_RIGHT, 0); + } + + if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) { + test_button_event(dev, BTN_MIDDLE, 1); + test_button_event(dev, BTN_MIDDLE, 0); + } +} +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); +} + +START_TEST(pointer_scroll_wheel) +{ + struct litest_device *dev = litest_current_device(); + + litest_drain_events(dev->libinput); + + test_wheel_event(dev, REL_WHEEL, -1); + test_wheel_event(dev, REL_WHEEL, 1); + + test_wheel_event(dev, REL_WHEEL, -5); + test_wheel_event(dev, REL_WHEEL, 6); + + if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) { + test_wheel_event(dev, REL_HWHEEL, -1); + test_wheel_event(dev, REL_HWHEEL, 1); + + test_wheel_event(dev, REL_HWHEEL, -5); + test_wheel_event(dev, REL_HWHEEL, 6); + } +} +END_TEST + +int main (int argc, char **argv) { + + litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, LITEST_ANY); + litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_ANY); + litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY); + + return litest_run(argc, argv); +}