From 5af33e16c9f2a783106abedc910dcec776243eb3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 21 Mar 2014 14:41:32 +1000 Subject: [PATCH] test: add a couple of touchpad tests Signed-off-by: Peter Hutterer --- test/Makefile.am | 7 +- test/touchpad.c | 373 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 379 insertions(+), 1 deletion(-) create mode 100644 test/touchpad.c diff --git a/test/Makefile.am b/test/Makefile.am index a986c0b5..7bf02d18 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -17,7 +17,7 @@ liblitest_la_SOURCES = \ litest-generic-highres-touch.c \ litest.c -run_tests = test-udev test-path test-pointer test-touch test-log +run_tests = test-udev test-path test-pointer test-touch test-log test-touchpad build_tests = test-build-linker test-build-pedantic-c99 test-build-std-gnuc90 noinst_PROGRAMS = $(build_tests) $(run_tests) @@ -48,6 +48,11 @@ test_log_CFLAGS = $(AM_CPPFLAGS) test_log_LDADD = $(TEST_LIBS) test_log_LDFLAGS = -static +test_touchpad_SOURCES = touchpad.c +test_touchpad_CFLAGS = $(AM_CPPFLAGS) +test_touchpad_LDADD = $(TEST_LIBS) +test_touchpad_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/touchpad.c b/test/touchpad.c new file mode 100644 index 00000000..d32a296a --- /dev/null +++ b/test/touchpad.c @@ -0,0 +1,373 @@ +/* + * Copyright © 2014 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" + +START_TEST(touchpad_1fg_motion) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_move_to(dev, 0, 50, 50, 80, 50, 5); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + + event = libinput_get_event(li); + ck_assert(event != NULL); + + while (event) { + ck_assert_int_eq(libinput_event_get_type(event), + LIBINPUT_EVENT_POINTER_MOTION); + + ptrev = libinput_event_get_pointer_event(event); + ck_assert_int_ge(libinput_event_pointer_get_dx(ptrev), 0); + ck_assert_int_eq(libinput_event_pointer_get_dy(ptrev), 0); + libinput_event_destroy(event); + event = libinput_get_event(li); + } +} +END_TEST + +START_TEST(touchpad_2fg_no_motion) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 70, 70); + litest_touch_move_to(dev, 0, 50, 50, 80, 50, 5); + litest_touch_move_to(dev, 1, 70, 70, 80, 50, 5); + litest_touch_up(dev, 0); + litest_touch_up(dev, 1); + + libinput_dispatch(li); + + event = libinput_get_event(li); + while (event) { + ck_assert_int_ne(libinput_event_get_type(event), + LIBINPUT_EVENT_POINTER_MOTION); + libinput_event_destroy(event); + event = libinput_get_event(li); + } +} +END_TEST + +static void +assert_button_event(struct libinput *li, int button, + enum libinput_pointer_button_state state) +{ + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + 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_int_eq(libinput_event_pointer_get_button(ptrev), + button); + ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrev), + state); + libinput_event_destroy(event); +} + +START_TEST(touchpad_1fg_tap) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); + usleep(300000); /* tap-n-drag timeout */ + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); + + libinput_dispatch(li); + event = libinput_get_event(li); + ck_assert(event == NULL); +} +END_TEST + +START_TEST(touchpad_1fg_tap_n_drag) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_up(dev, 0); + litest_touch_down(dev, 0, 50, 50); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); + + libinput_dispatch(li); + while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { + event = libinput_get_event(li); + libinput_event_destroy(event); + libinput_dispatch(li); + } + + ck_assert_int_eq(libinput_next_event_type(li), LIBINPUT_EVENT_NONE); + + /* lift finger, set down again, should continue dragging */ + litest_touch_down(dev, 0, 50, 50); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { + event = libinput_get_event(li); + libinput_event_destroy(event); + libinput_dispatch(li); + } + + ck_assert_int_eq(libinput_next_event_type(li), LIBINPUT_EVENT_NONE); + + usleep(300000); /* tap-n-drag timeout */ + + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); + + libinput_dispatch(li); + event = libinput_get_event(li); + ck_assert(event == NULL); +} +END_TEST + +START_TEST(touchpad_2fg_tap) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + + litest_drain_events(dev->libinput); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 70, 70); + litest_touch_up(dev, 0); + litest_touch_up(dev, 1); + + libinput_dispatch(li); + + assert_button_event(li, BTN_RIGHT, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); + usleep(300000); /* tap-n-drag timeout */ + assert_button_event(li, BTN_RIGHT, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); + + libinput_dispatch(li); + event = libinput_get_event(li); + ck_assert(event == NULL); +} +END_TEST + +START_TEST(touchpad_1fg_clickfinger) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_event(dev, EV_KEY, BTN_LEFT, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_LEFT, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); +} +END_TEST + +START_TEST(touchpad_2fg_clickfinger) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 70, 70); + litest_event(dev, EV_KEY, BTN_LEFT, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_LEFT, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_touch_up(dev, 0); + litest_touch_up(dev, 1); + + libinput_dispatch(li); + + assert_button_event(li, BTN_RIGHT, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); + assert_button_event(li, BTN_RIGHT, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); +} +END_TEST + +START_TEST(touchpad_btn_left) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + enum libinput_pointer_button_state btnstate; + + litest_drain_events(li); + + litest_event(dev, EV_KEY, BTN_LEFT, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_LEFT, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + + libinput_dispatch(li); + + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); +} +END_TEST + +START_TEST(clickpad_btn_left) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(li); + + /* A clickpad always needs a finger down to tell where the + click happens */ + litest_event(dev, EV_KEY, BTN_LEFT, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_LEFT, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + + libinput_dispatch(li); + ck_assert_int_eq(libinput_next_event_type(li), LIBINPUT_EVENT_NONE); +} +END_TEST + +START_TEST(clickpad_click_n_drag) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_event(dev, EV_KEY, BTN_LEFT, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + + libinput_dispatch(li); + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_PRESSED); + + libinput_dispatch(li); + ck_assert_int_eq(libinput_next_event_type(li), LIBINPUT_EVENT_NONE); + + /* now put a second finger down */ + litest_touch_down(dev, 1, 70, 70); + litest_touch_move_to(dev, 1, 70, 70, 80, 50, 5); + litest_touch_up(dev, 1); + + libinput_dispatch(li); + ck_assert_int_eq(libinput_next_event_type(li), + LIBINPUT_EVENT_POINTER_MOTION); + do { + event = libinput_get_event(li); + libinput_event_destroy(event); + libinput_dispatch(li); + } while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION); + + litest_event(dev, EV_KEY, BTN_LEFT, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_touch_up(dev, 0); + + assert_button_event(li, BTN_LEFT, + LIBINPUT_POINTER_BUTTON_STATE_RELEASED); +} +END_TEST + +int main(int argc, char **argv) { + + litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_ANY); + + litest_add("touchpad:tap", touchpad_1fg_tap, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("touchpad:tap", touchpad_1fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_ANY); + + litest_add("touchpad:clickfinger", touchpad_1fg_clickfinger, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("touchpad:clickfinger", touchpad_2fg_clickfinger, LITEST_TOUCHPAD, LITEST_ANY); + + litest_add("touchpad:click", touchpad_btn_left, LITEST_TOUCHPAD, LITEST_CLICKPAD); + litest_add("touchpad:click", clickpad_btn_left, LITEST_CLICKPAD, LITEST_ANY); + litest_add("touchpad:click", clickpad_click_n_drag, LITEST_CLICKPAD, LITEST_ANY); + + return litest_run(argc, argv); +}