tests: move existing gesture tests to functions to be able to reuse them
authorJosé Expósito <jose.exposito89@gmail.com>
Thu, 27 May 2021 17:20:11 +0000 (19:20 +0200)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 9 Jun 2021 01:18:58 +0000 (01:18 +0000)
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
test/test-gestures.c

index 21f53baf848cde875594ee591c92d11564b7bc1c..85edcea378a44f4dd8910903ed1bb57ce38a4dfa 100644 (file)
@@ -34,38 +34,14 @@ enum cardinal {
        N, NE, E, SE, S, SW, W, NW, NCARDINALS
 };
 
-START_TEST(gestures_cap)
-{
-       struct litest_device *dev = litest_current_device();
-       struct libinput_device *device = dev->libinput_device;
-
-       if (libevdev_has_property(dev->evdev, INPUT_PROP_SEMI_MT))
-               ck_assert(!libinput_device_has_capability(device,
-                                         LIBINPUT_DEVICE_CAP_GESTURE));
-       else
-               ck_assert(libinput_device_has_capability(device,
-                                        LIBINPUT_DEVICE_CAP_GESTURE));
-}
-END_TEST
-
-START_TEST(gestures_nocap)
-{
-       struct litest_device *dev = litest_current_device();
-       struct libinput_device *device = dev->libinput_device;
-
-       ck_assert(!libinput_device_has_capability(device,
-                                                 LIBINPUT_DEVICE_CAP_GESTURE));
-}
-END_TEST
-
-START_TEST(gestures_swipe_3fg)
+static void
+test_gesture_swipe_3fg(int cardinal)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
        struct libinput_event *event;
        struct libinput_event_gesture *gevent;
        double dx, dy;
-       int cardinal = _i; /* ranged test */
        double dir_x, dir_y;
        int cardinals[NCARDINALS][2] = {
                { 0, 30 },
@@ -155,169 +131,15 @@ START_TEST(gestures_swipe_3fg)
        ck_assert(!libinput_event_gesture_get_cancelled(gevent));
        libinput_event_destroy(event);
 }
-END_TEST
-
-START_TEST(gestures_swipe_3fg_btntool)
-{
-       struct litest_device *dev = litest_current_device();
-       struct libinput *li = dev->libinput;
-       struct libinput_event *event;
-       struct libinput_event_gesture *gevent;
-       double dx, dy;
-       int cardinal = _i; /* ranged test */
-       double dir_x, dir_y;
-       int cardinals[NCARDINALS][2] = {
-               { 0, 30 },
-               { 30, 30 },
-               { 30, 0 },
-               { 30, -30 },
-               { 0, -30 },
-               { -30, -30 },
-               { -30, 0 },
-               { -30, 30 },
-       };
-
-       if (litest_slot_count(dev) > 2 ||
-           !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP) ||
-           !libinput_device_has_capability(dev->libinput_device,
-                                           LIBINPUT_DEVICE_CAP_GESTURE))
-               return;
-
-       dir_x = cardinals[cardinal][0];
-       dir_y = cardinals[cardinal][1];
-
-       litest_drain_events(li);
-
-       litest_touch_down(dev, 0, 40, 40);
-       litest_touch_down(dev, 1, 50, 40);
-       litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
-       litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
-       litest_event(dev, EV_SYN, SYN_REPORT, 0);
-
-       libinput_dispatch(li);
-       litest_touch_move_two_touches(dev, 40, 40, 50, 40, dir_x, dir_y, 10);
-       libinput_dispatch(li);
-
-       event = libinput_get_event(li);
-       gevent = litest_is_gesture_event(event,
-                                        LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
-                                        3);
-       dx = libinput_event_gesture_get_dx(gevent);
-       dy = libinput_event_gesture_get_dy(gevent);
-       ck_assert(dx == 0.0);
-       ck_assert(dy == 0.0);
-       libinput_event_destroy(event);
-
-       while ((event = libinput_get_event(li)) != NULL) {
-               gevent = litest_is_gesture_event(event,
-                                                LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
-                                                3);
-
-               dx = libinput_event_gesture_get_dx(gevent);
-               dy = libinput_event_gesture_get_dy(gevent);
-               if (dir_x == 0.0)
-                       ck_assert(dx == 0.0);
-               else if (dir_x < 0.0)
-                       ck_assert(dx < 0.0);
-               else if (dir_x > 0.0)
-                       ck_assert(dx > 0.0);
-
-               if (dir_y == 0.0)
-                       ck_assert(dy == 0.0);
-               else if (dir_y < 0.0)
-                       ck_assert(dy < 0.0);
-               else if (dir_y > 0.0)
-                       ck_assert(dy > 0.0);
-
-               dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
-               dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
-               if (dir_x == 0.0)
-                       ck_assert(dx == 0.0);
-               else if (dir_x < 0.0)
-                       ck_assert(dx < 0.0);
-               else if (dir_x > 0.0)
-                       ck_assert(dx > 0.0);
-
-               if (dir_y == 0.0)
-                       ck_assert(dy == 0.0);
-               else if (dir_y < 0.0)
-                       ck_assert(dy < 0.0);
-               else if (dir_y > 0.0)
-                       ck_assert(dy > 0.0);
-
-               libinput_event_destroy(event);
-       }
-
-       litest_touch_up(dev, 0);
-       litest_touch_up(dev, 1);
-       libinput_dispatch(li);
-       event = libinput_get_event(li);
-       gevent = litest_is_gesture_event(event,
-                                        LIBINPUT_EVENT_GESTURE_SWIPE_END,
-                                        3);
-       ck_assert(!libinput_event_gesture_get_cancelled(gevent));
-       libinput_event_destroy(event);
-}
-END_TEST
-
-START_TEST(gestures_swipe_3fg_btntool_pinch_like)
-{
-       struct litest_device *dev = litest_current_device();
-       struct libinput *li = dev->libinput;
-       struct libinput_event *event;
-       struct libinput_event_gesture *gevent;
-
-       if (litest_slot_count(dev) > 2 ||
-           !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP) ||
-           !libinput_device_has_capability(dev->libinput_device,
-                                           LIBINPUT_DEVICE_CAP_GESTURE))
-               return;
-
-       litest_drain_events(li);
-
-       /* Technically a pinch position + pinch movement, but expect swipe
-        * for nfingers > nslots */
-       litest_touch_down(dev, 0, 20, 60);
-       litest_touch_down(dev, 1, 50, 20);
-       litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
-       litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
-       litest_event(dev, EV_SYN, SYN_REPORT, 0);
-
-       libinput_dispatch(li);
-       litest_touch_move_to(dev, 0, 20, 60, 10, 80, 20);
-       libinput_dispatch(li);
-
-       event = libinput_get_event(li);
-       litest_is_gesture_event(event, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 3);
-       libinput_event_destroy(event);
-
-       while ((event = libinput_get_event(li)) != NULL) {
-               litest_is_gesture_event(event,
-                                       LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
-                                       3);
-               libinput_event_destroy(event);
-       }
-
-       litest_touch_up(dev, 0);
-       litest_touch_up(dev, 1);
-       libinput_dispatch(li);
-       event = libinput_get_event(li);
-       gevent = litest_is_gesture_event(event,
-                                        LIBINPUT_EVENT_GESTURE_SWIPE_END,
-                                        3);
-       ck_assert(!libinput_event_gesture_get_cancelled(gevent));
-       libinput_event_destroy(event);
-}
-END_TEST
 
-START_TEST(gestures_swipe_4fg)
+static void
+test_gesture_swipe_4fg(int cardinal)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
        struct libinput_event *event;
        struct libinput_event_gesture *gevent;
        double dx, dy;
-       int cardinal = _i; /* ranged test */
        double dir_x, dir_y;
        int cardinals[NCARDINALS][2] = {
                { 0, 3 },
@@ -435,17 +257,19 @@ START_TEST(gestures_swipe_4fg)
        ck_assert(!libinput_event_gesture_get_cancelled(gevent));
        libinput_event_destroy(event);
 }
-END_TEST
 
-START_TEST(gestures_swipe_4fg_btntool)
+static void
+test_gesture_pinch_2fg(int cardinal)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
        struct libinput_event *event;
        struct libinput_event_gesture *gevent;
        double dx, dy;
-       int cardinal = _i; /* ranged test */
        double dir_x, dir_y;
+       int i;
+       double scale, oldscale;
+       double angle;
        int cardinals[NCARDINALS][2] = {
                { 0, 30 },
                { 30, 30 },
@@ -457,75 +281,81 @@ START_TEST(gestures_swipe_4fg_btntool)
                { -30, 30 },
        };
 
-       if (litest_slot_count(dev) > 2 ||
-           !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_QUADTAP) ||
+       if (litest_slot_count(dev) < 2 ||
            !libinput_device_has_capability(dev->libinput_device,
                                            LIBINPUT_DEVICE_CAP_GESTURE))
                return;
 
+       /* If the device is too small to provide a finger spread wide enough
+        * to avoid the scroll bias, skip the test */
+       if (cardinal == E || cardinal == W) {
+               double w = 0, h = 0;
+               libinput_device_get_size(dev->libinput_device, &w, &h);
+               /* 0.6 because the code below gives us points like 20/y and
+                * 80/y. 45 because the threshold in the code is 40mm */
+               if (w * 0.6 < 45)
+                       return;
+       }
+
        dir_x = cardinals[cardinal][0];
        dir_y = cardinals[cardinal][1];
 
        litest_drain_events(li);
 
-       litest_touch_down(dev, 0, 40, 40);
-       litest_touch_down(dev, 1, 50, 40);
-       litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
-       litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
-       litest_event(dev, EV_SYN, SYN_REPORT, 0);
-
-       libinput_dispatch(li);
-       litest_touch_move_two_touches(dev, 40, 40, 50, 40, dir_x, dir_y, 10);
+       litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
+       litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
        libinput_dispatch(li);
 
+       for (i = 0; i < 8; i++) {
+               litest_push_event_frame(dev);
+               if (dir_x > 0.0)
+                       dir_x -= 2;
+               else if (dir_x < 0.0)
+                       dir_x += 2;
+               if (dir_y > 0.0)
+                       dir_y -= 2;
+               else if (dir_y < 0.0)
+                       dir_y += 2;
+               litest_touch_move(dev,
+                                 0,
+                                 50 + dir_x,
+                                 50 + dir_y);
+               litest_touch_move(dev,
+                                 1,
+                                 50 - dir_x,
+                                 50 - dir_y);
+               litest_pop_event_frame(dev);
+               libinput_dispatch(li);
+       }
+
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
-                                        LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
-                                        4);
+                                        LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
+                                        2);
        dx = libinput_event_gesture_get_dx(gevent);
        dy = libinput_event_gesture_get_dy(gevent);
+       scale = libinput_event_gesture_get_scale(gevent);
        ck_assert(dx == 0.0);
        ck_assert(dy == 0.0);
+       ck_assert(scale == 1.0);
+
        libinput_event_destroy(event);
 
        while ((event = libinput_get_event(li)) != NULL) {
                gevent = litest_is_gesture_event(event,
-                                                LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
-                                                4);
+                                                LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
+                                                2);
 
-               dx = libinput_event_gesture_get_dx(gevent);
-               dy = libinput_event_gesture_get_dy(gevent);
-               if (dir_x == 0.0)
-                       ck_assert(dx == 0.0);
-               else if (dir_x < 0.0)
-                       ck_assert(dx < 0.0);
-               else if (dir_x > 0.0)
-                       ck_assert(dx > 0.0);
+               oldscale = scale;
+               scale = libinput_event_gesture_get_scale(gevent);
 
-               if (dir_y == 0.0)
-                       ck_assert(dy == 0.0);
-               else if (dir_y < 0.0)
-                       ck_assert(dy < 0.0);
-               else if (dir_y > 0.0)
-                       ck_assert(dy > 0.0);
-
-               dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
-               dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
-               if (dir_x == 0.0)
-                       ck_assert(dx == 0.0);
-               else if (dir_x < 0.0)
-                       ck_assert(dx < 0.0);
-               else if (dir_x > 0.0)
-                       ck_assert(dx > 0.0);
+               ck_assert(scale < oldscale);
 
-               if (dir_y == 0.0)
-                       ck_assert(dy == 0.0);
-               else if (dir_y < 0.0)
-                       ck_assert(dy < 0.0);
-               else if (dir_y > 0.0)
-                       ck_assert(dy > 0.0);
+               angle = libinput_event_gesture_get_angle_delta(gevent);
+               ck_assert_double_le(fabs(angle), 1.0);
 
                libinput_event_destroy(event);
+               libinput_dispatch(li);
        }
 
        litest_touch_up(dev, 0);
@@ -533,21 +363,20 @@ START_TEST(gestures_swipe_4fg_btntool)
        libinput_dispatch(li);
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
-                                        LIBINPUT_EVENT_GESTURE_SWIPE_END,
-                                        4);
+                                        LIBINPUT_EVENT_GESTURE_PINCH_END,
+                                        2);
        ck_assert(!libinput_event_gesture_get_cancelled(gevent));
        libinput_event_destroy(event);
 }
-END_TEST
 
-START_TEST(gestures_pinch)
+static void
+test_gesture_pinch_3fg(int cardinal)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
        struct libinput_event *event;
        struct libinput_event_gesture *gevent;
        double dx, dy;
-       int cardinal = _i; /* ranged test */
        double dir_x, dir_y;
        int i;
        double scale, oldscale;
@@ -563,22 +392,9 @@ START_TEST(gestures_pinch)
                { -30, 30 },
        };
 
-       if (litest_slot_count(dev) < 2 ||
-           !libinput_device_has_capability(dev->libinput_device,
-                                           LIBINPUT_DEVICE_CAP_GESTURE))
+       if (litest_slot_count(dev) < 3)
                return;
 
-       /* If the device is too small to provide a finger spread wide enough
-        * to avoid the scroll bias, skip the test */
-       if (cardinal == E || cardinal == W) {
-               double w = 0, h = 0;
-               libinput_device_get_size(dev->libinput_device, &w, &h);
-               /* 0.6 because the code below gives us points like 20/y and
-                * 80/y. 45 because the threshold in the code is 40mm */
-               if (w * 0.6 < 45)
-                       return;
-       }
-
        dir_x = cardinals[cardinal][0];
        dir_y = cardinals[cardinal][1];
 
@@ -586,6 +402,7 @@ START_TEST(gestures_pinch)
 
        litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
        litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
+       litest_touch_down(dev, 2, 51 - dir_x, 51 - dir_y);
        libinput_dispatch(li);
 
        for (i = 0; i < 8; i++) {
@@ -606,6 +423,10 @@ START_TEST(gestures_pinch)
                                  1,
                                  50 - dir_x,
                                  50 - dir_y);
+               litest_touch_move(dev,
+                                 2,
+                                 51 - dir_x,
+                                 51 - dir_y);
                litest_pop_event_frame(dev);
                libinput_dispatch(li);
        }
@@ -613,7 +434,7 @@ START_TEST(gestures_pinch)
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
                                         LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
-                                        2);
+                                        3);
        dx = libinput_event_gesture_get_dx(gevent);
        dy = libinput_event_gesture_get_dy(gevent);
        scale = libinput_event_gesture_get_scale(gevent);
@@ -626,7 +447,7 @@ START_TEST(gestures_pinch)
        while ((event = libinput_get_event(li)) != NULL) {
                gevent = litest_is_gesture_event(event,
                                                 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
-                                                2);
+                                                3);
 
                oldscale = scale;
                scale = libinput_event_gesture_get_scale(gevent);
@@ -642,24 +463,24 @@ START_TEST(gestures_pinch)
 
        litest_touch_up(dev, 0);
        litest_touch_up(dev, 1);
+       litest_touch_up(dev, 2);
        libinput_dispatch(li);
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
                                         LIBINPUT_EVENT_GESTURE_PINCH_END,
-                                        2);
+                                        3);
        ck_assert(!libinput_event_gesture_get_cancelled(gevent));
        libinput_event_destroy(event);
 }
-END_TEST
 
-START_TEST(gestures_pinch_3fg)
+static void
+test_gesture_pinch_4fg(int cardinal)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
        struct libinput_event *event;
        struct libinput_event_gesture *gevent;
        double dx, dy;
-       int cardinal = _i; /* ranged test */
        double dir_x, dir_y;
        int i;
        double scale, oldscale;
@@ -675,7 +496,7 @@ START_TEST(gestures_pinch_3fg)
                { -30, 30 },
        };
 
-       if (litest_slot_count(dev) < 3)
+       if (litest_slot_count(dev) < 4)
                return;
 
        dir_x = cardinals[cardinal][0];
@@ -686,9 +507,10 @@ START_TEST(gestures_pinch_3fg)
        litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
        litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
        litest_touch_down(dev, 2, 51 - dir_x, 51 - dir_y);
+       litest_touch_down(dev, 3, 52 - dir_x, 52 - dir_y);
        libinput_dispatch(li);
 
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < 7; i++) {
                litest_push_event_frame(dev);
                if (dir_x > 0.0)
                        dir_x -= 2;
@@ -710,6 +532,10 @@ START_TEST(gestures_pinch_3fg)
                                  2,
                                  51 - dir_x,
                                  51 - dir_y);
+               litest_touch_move(dev,
+                                 3,
+                                 52 - dir_x,
+                                 52 - dir_y);
                litest_pop_event_frame(dev);
                libinput_dispatch(li);
        }
@@ -717,7 +543,7 @@ START_TEST(gestures_pinch_3fg)
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
                                         LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
-                                        3);
+                                        4);
        dx = libinput_event_gesture_get_dx(gevent);
        dy = libinput_event_gesture_get_dy(gevent);
        scale = libinput_event_gesture_get_scale(gevent);
@@ -730,7 +556,7 @@ START_TEST(gestures_pinch_3fg)
        while ((event = libinput_get_event(li)) != NULL) {
                gevent = litest_is_gesture_event(event,
                                                 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
-                                                3);
+                                                4);
 
                oldscale = scale;
                scale = libinput_event_gesture_get_scale(gevent);
@@ -747,24 +573,24 @@ START_TEST(gestures_pinch_3fg)
        litest_touch_up(dev, 0);
        litest_touch_up(dev, 1);
        litest_touch_up(dev, 2);
+       litest_touch_up(dev, 3);
        libinput_dispatch(li);
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
                                         LIBINPUT_EVENT_GESTURE_PINCH_END,
-                                        3);
+                                        4);
        ck_assert(!libinput_event_gesture_get_cancelled(gevent));
        libinput_event_destroy(event);
 }
-END_TEST
 
-START_TEST(gestures_pinch_4fg)
+static void
+test_gesture_spread(int cardinal)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
        struct libinput_event *event;
        struct libinput_event_gesture *gevent;
        double dx, dy;
-       int cardinal = _i; /* ranged test */
        double dir_x, dir_y;
        int i;
        double scale, oldscale;
@@ -780,9 +606,22 @@ START_TEST(gestures_pinch_4fg)
                { -30, 30 },
        };
 
-       if (litest_slot_count(dev) < 4)
+       if (litest_slot_count(dev) < 2 ||
+           !libinput_device_has_capability(dev->libinput_device,
+                                           LIBINPUT_DEVICE_CAP_GESTURE))
                return;
 
+       /* If the device is too small to provide a finger spread wide enough
+        * to avoid the scroll bias, skip the test */
+       if (cardinal == E || cardinal == W) {
+               double w = 0, h = 0;
+               libinput_device_get_size(dev->libinput_device, &w, &h);
+               /* 0.6 because the code below gives us points like 20/y and
+                * 80/y. 45 because the threshold in the code is 40mm */
+               if (w * 0.6 < 45)
+                       return;
+       }
+
        dir_x = cardinals[cardinal][0];
        dir_y = cardinals[cardinal][1];
 
@@ -790,20 +629,18 @@ START_TEST(gestures_pinch_4fg)
 
        litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
        litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
-       litest_touch_down(dev, 2, 51 - dir_x, 51 - dir_y);
-       litest_touch_down(dev, 3, 52 - dir_x, 52 - dir_y);
        libinput_dispatch(li);
 
-       for (i = 0; i < 7; i++) {
+       for (i = 0; i < 15; i++) {
                litest_push_event_frame(dev);
                if (dir_x > 0.0)
-                       dir_x -= 2;
+                       dir_x += 1;
                else if (dir_x < 0.0)
-                       dir_x += 2;
+                       dir_x -= 1;
                if (dir_y > 0.0)
-                       dir_y -= 2;
+                       dir_y += 1;
                else if (dir_y < 0.0)
-                       dir_y += 2;
+                       dir_y -= 1;
                litest_touch_move(dev,
                                  0,
                                  50 + dir_x,
@@ -812,14 +649,6 @@ START_TEST(gestures_pinch_4fg)
                                  1,
                                  50 - dir_x,
                                  50 - dir_y);
-               litest_touch_move(dev,
-                                 2,
-                                 51 - dir_x,
-                                 51 - dir_y);
-               litest_touch_move(dev,
-                                 3,
-                                 52 - dir_x,
-                                 52 - dir_y);
                litest_pop_event_frame(dev);
                libinput_dispatch(li);
        }
@@ -827,7 +656,7 @@ START_TEST(gestures_pinch_4fg)
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
                                         LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
-                                        4);
+                                        2);
        dx = libinput_event_gesture_get_dx(gevent);
        dy = libinput_event_gesture_get_dy(gevent);
        scale = libinput_event_gesture_get_scale(gevent);
@@ -840,12 +669,10 @@ START_TEST(gestures_pinch_4fg)
        while ((event = libinput_get_event(li)) != NULL) {
                gevent = litest_is_gesture_event(event,
                                                 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
-                                                4);
-
+                                                2);
                oldscale = scale;
                scale = libinput_event_gesture_get_scale(gevent);
-
-               ck_assert(scale < oldscale);
+               ck_assert(scale > oldscale);
 
                angle = libinput_event_gesture_get_angle_delta(gevent);
                ck_assert_double_le(fabs(angle), 1.0);
@@ -856,19 +683,73 @@ START_TEST(gestures_pinch_4fg)
 
        litest_touch_up(dev, 0);
        litest_touch_up(dev, 1);
-       litest_touch_up(dev, 2);
-       litest_touch_up(dev, 3);
        libinput_dispatch(li);
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
                                         LIBINPUT_EVENT_GESTURE_PINCH_END,
-                                        4);
+                                        2);
        ck_assert(!libinput_event_gesture_get_cancelled(gevent));
        libinput_event_destroy(event);
 }
+
+static void
+test_gesture_3fg_buttonarea_scroll(void)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput *li = dev->libinput;
+
+       if (litest_slot_count(dev) < 3)
+               return;
+
+       litest_enable_buttonareas(dev);
+       litest_enable_2fg_scroll(dev);
+       litest_drain_events(li);
+
+       litest_touch_down(dev, 0, 40, 20);
+       litest_touch_down(dev, 1, 30, 20);
+       /* third finger in btnarea */
+       litest_touch_down(dev, 2, 50, 99);
+       libinput_dispatch(li);
+       litest_touch_move_two_touches(dev, 40, 20, 30, 20, 0, 40, 10);
+
+       litest_touch_up(dev, 0);
+       litest_touch_up(dev, 1);
+       libinput_dispatch(li);
+       litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
+}
+
+START_TEST(gestures_cap)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput_device *device = dev->libinput_device;
+
+       if (libevdev_has_property(dev->evdev, INPUT_PROP_SEMI_MT))
+               ck_assert(!libinput_device_has_capability(device,
+                                         LIBINPUT_DEVICE_CAP_GESTURE));
+       else
+               ck_assert(libinput_device_has_capability(device,
+                                        LIBINPUT_DEVICE_CAP_GESTURE));
+}
 END_TEST
 
-START_TEST(gestures_spread)
+START_TEST(gestures_nocap)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput_device *device = dev->libinput_device;
+
+       ck_assert(!libinput_device_has_capability(device,
+                                                 LIBINPUT_DEVICE_CAP_GESTURE));
+}
+END_TEST
+
+START_TEST(gestures_swipe_3fg)
+{
+       int cardinal = _i; /* ranged test */
+       test_gesture_swipe_3fg(cardinal);
+}
+END_TEST
+
+START_TEST(gestures_swipe_3fg_btntool)
 {
        struct litest_device *dev = litest_current_device();
        struct libinput *li = dev->libinput;
@@ -877,9 +758,6 @@ START_TEST(gestures_spread)
        double dx, dy;
        int cardinal = _i; /* ranged test */
        double dir_x, dir_y;
-       int i;
-       double scale, oldscale;
-       double angle;
        int cardinals[NCARDINALS][2] = {
                { 0, 30 },
                { 30, 30 },
@@ -891,79 +769,235 @@ START_TEST(gestures_spread)
                { -30, 30 },
        };
 
-       if (litest_slot_count(dev) < 2 ||
+       if (litest_slot_count(dev) > 2 ||
+           !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP) ||
            !libinput_device_has_capability(dev->libinput_device,
                                            LIBINPUT_DEVICE_CAP_GESTURE))
                return;
 
-       /* If the device is too small to provide a finger spread wide enough
-        * to avoid the scroll bias, skip the test */
-       if (cardinal == E || cardinal == W) {
-               double w = 0, h = 0;
-               libinput_device_get_size(dev->libinput_device, &w, &h);
-               /* 0.6 because the code below gives us points like 20/y and
-                * 80/y. 45 because the threshold in the code is 40mm */
-               if (w * 0.6 < 45)
-                       return;
-       }
-
        dir_x = cardinals[cardinal][0];
        dir_y = cardinals[cardinal][1];
 
        litest_drain_events(li);
 
-       litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
-       litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
+       litest_touch_down(dev, 0, 40, 40);
+       litest_touch_down(dev, 1, 50, 40);
+       litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
+       litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
+       litest_event(dev, EV_SYN, SYN_REPORT, 0);
+
+       libinput_dispatch(li);
+       litest_touch_move_two_touches(dev, 40, 40, 50, 40, dir_x, dir_y, 10);
        libinput_dispatch(li);
 
-       for (i = 0; i < 15; i++) {
-               litest_push_event_frame(dev);
-               if (dir_x > 0.0)
-                       dir_x += 1;
+       event = libinput_get_event(li);
+       gevent = litest_is_gesture_event(event,
+                                        LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
+                                        3);
+       dx = libinput_event_gesture_get_dx(gevent);
+       dy = libinput_event_gesture_get_dy(gevent);
+       ck_assert(dx == 0.0);
+       ck_assert(dy == 0.0);
+       libinput_event_destroy(event);
+
+       while ((event = libinput_get_event(li)) != NULL) {
+               gevent = litest_is_gesture_event(event,
+                                                LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
+                                                3);
+
+               dx = libinput_event_gesture_get_dx(gevent);
+               dy = libinput_event_gesture_get_dy(gevent);
+               if (dir_x == 0.0)
+                       ck_assert(dx == 0.0);
                else if (dir_x < 0.0)
-                       dir_x -= 1;
-               if (dir_y > 0.0)
-                       dir_y += 1;
+                       ck_assert(dx < 0.0);
+               else if (dir_x > 0.0)
+                       ck_assert(dx > 0.0);
+
+               if (dir_y == 0.0)
+                       ck_assert(dy == 0.0);
                else if (dir_y < 0.0)
-                       dir_y -= 1;
-               litest_touch_move(dev,
-                                 0,
-                                 50 + dir_x,
-                                 50 + dir_y);
-               litest_touch_move(dev,
-                                 1,
-                                 50 - dir_x,
-                                 50 - dir_y);
-               litest_pop_event_frame(dev);
-               libinput_dispatch(li);
+                       ck_assert(dy < 0.0);
+               else if (dir_y > 0.0)
+                       ck_assert(dy > 0.0);
+
+               dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
+               dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
+               if (dir_x == 0.0)
+                       ck_assert(dx == 0.0);
+               else if (dir_x < 0.0)
+                       ck_assert(dx < 0.0);
+               else if (dir_x > 0.0)
+                       ck_assert(dx > 0.0);
+
+               if (dir_y == 0.0)
+                       ck_assert(dy == 0.0);
+               else if (dir_y < 0.0)
+                       ck_assert(dy < 0.0);
+               else if (dir_y > 0.0)
+                       ck_assert(dy > 0.0);
+
+               libinput_event_destroy(event);
        }
 
+       litest_touch_up(dev, 0);
+       litest_touch_up(dev, 1);
+       libinput_dispatch(li);
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
-                                        LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
-                                        2);
+                                        LIBINPUT_EVENT_GESTURE_SWIPE_END,
+                                        3);
+       ck_assert(!libinput_event_gesture_get_cancelled(gevent));
+       libinput_event_destroy(event);
+}
+END_TEST
+
+START_TEST(gestures_swipe_3fg_btntool_pinch_like)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput *li = dev->libinput;
+       struct libinput_event *event;
+       struct libinput_event_gesture *gevent;
+
+       if (litest_slot_count(dev) > 2 ||
+           !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP) ||
+           !libinput_device_has_capability(dev->libinput_device,
+                                           LIBINPUT_DEVICE_CAP_GESTURE))
+               return;
+
+       litest_drain_events(li);
+
+       /* Technically a pinch position + pinch movement, but expect swipe
+        * for nfingers > nslots */
+       litest_touch_down(dev, 0, 20, 60);
+       litest_touch_down(dev, 1, 50, 20);
+       litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
+       litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
+       litest_event(dev, EV_SYN, SYN_REPORT, 0);
+
+       libinput_dispatch(li);
+       litest_touch_move_to(dev, 0, 20, 60, 10, 80, 20);
+       libinput_dispatch(li);
+
+       event = libinput_get_event(li);
+       litest_is_gesture_event(event, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 3);
+       libinput_event_destroy(event);
+
+       while ((event = libinput_get_event(li)) != NULL) {
+               litest_is_gesture_event(event,
+                                       LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
+                                       3);
+               libinput_event_destroy(event);
+       }
+
+       litest_touch_up(dev, 0);
+       litest_touch_up(dev, 1);
+       libinput_dispatch(li);
+       event = libinput_get_event(li);
+       gevent = litest_is_gesture_event(event,
+                                        LIBINPUT_EVENT_GESTURE_SWIPE_END,
+                                        3);
+       ck_assert(!libinput_event_gesture_get_cancelled(gevent));
+       libinput_event_destroy(event);
+}
+END_TEST
+
+START_TEST(gestures_swipe_4fg)
+{
+       int cardinal = _i; /* ranged test */
+       test_gesture_swipe_4fg(cardinal);
+}
+END_TEST
+
+START_TEST(gestures_swipe_4fg_btntool)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput *li = dev->libinput;
+       struct libinput_event *event;
+       struct libinput_event_gesture *gevent;
+       double dx, dy;
+       int cardinal = _i; /* ranged test */
+       double dir_x, dir_y;
+       int cardinals[NCARDINALS][2] = {
+               { 0, 30 },
+               { 30, 30 },
+               { 30, 0 },
+               { 30, -30 },
+               { 0, -30 },
+               { -30, -30 },
+               { -30, 0 },
+               { -30, 30 },
+       };
+
+       if (litest_slot_count(dev) > 2 ||
+           !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_QUADTAP) ||
+           !libinput_device_has_capability(dev->libinput_device,
+                                           LIBINPUT_DEVICE_CAP_GESTURE))
+               return;
+
+       dir_x = cardinals[cardinal][0];
+       dir_y = cardinals[cardinal][1];
+
+       litest_drain_events(li);
+
+       litest_touch_down(dev, 0, 40, 40);
+       litest_touch_down(dev, 1, 50, 40);
+       litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
+       litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
+       litest_event(dev, EV_SYN, SYN_REPORT, 0);
+
+       libinput_dispatch(li);
+       litest_touch_move_two_touches(dev, 40, 40, 50, 40, dir_x, dir_y, 10);
+       libinput_dispatch(li);
+
+       event = libinput_get_event(li);
+       gevent = litest_is_gesture_event(event,
+                                        LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
+                                        4);
        dx = libinput_event_gesture_get_dx(gevent);
        dy = libinput_event_gesture_get_dy(gevent);
-       scale = libinput_event_gesture_get_scale(gevent);
        ck_assert(dx == 0.0);
        ck_assert(dy == 0.0);
-       ck_assert(scale == 1.0);
-
        libinput_event_destroy(event);
 
        while ((event = libinput_get_event(li)) != NULL) {
                gevent = litest_is_gesture_event(event,
-                                                LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
-                                                2);
-               oldscale = scale;
-               scale = libinput_event_gesture_get_scale(gevent);
-               ck_assert(scale > oldscale);
+                                                LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
+                                                4);
 
-               angle = libinput_event_gesture_get_angle_delta(gevent);
-               ck_assert_double_le(fabs(angle), 1.0);
+               dx = libinput_event_gesture_get_dx(gevent);
+               dy = libinput_event_gesture_get_dy(gevent);
+               if (dir_x == 0.0)
+                       ck_assert(dx == 0.0);
+               else if (dir_x < 0.0)
+                       ck_assert(dx < 0.0);
+               else if (dir_x > 0.0)
+                       ck_assert(dx > 0.0);
+
+               if (dir_y == 0.0)
+                       ck_assert(dy == 0.0);
+               else if (dir_y < 0.0)
+                       ck_assert(dy < 0.0);
+               else if (dir_y > 0.0)
+                       ck_assert(dy > 0.0);
+
+               dx = libinput_event_gesture_get_dx_unaccelerated(gevent);
+               dy = libinput_event_gesture_get_dy_unaccelerated(gevent);
+               if (dir_x == 0.0)
+                       ck_assert(dx == 0.0);
+               else if (dir_x < 0.0)
+                       ck_assert(dx < 0.0);
+               else if (dir_x > 0.0)
+                       ck_assert(dx > 0.0);
+
+               if (dir_y == 0.0)
+                       ck_assert(dy == 0.0);
+               else if (dir_y < 0.0)
+                       ck_assert(dy < 0.0);
+               else if (dir_y > 0.0)
+                       ck_assert(dy > 0.0);
 
                libinput_event_destroy(event);
-               libinput_dispatch(li);
        }
 
        litest_touch_up(dev, 0);
@@ -971,13 +1005,41 @@ START_TEST(gestures_spread)
        libinput_dispatch(li);
        event = libinput_get_event(li);
        gevent = litest_is_gesture_event(event,
-                                        LIBINPUT_EVENT_GESTURE_PINCH_END,
-                                        2);
+                                        LIBINPUT_EVENT_GESTURE_SWIPE_END,
+                                        4);
        ck_assert(!libinput_event_gesture_get_cancelled(gevent));
        libinput_event_destroy(event);
 }
 END_TEST
 
+START_TEST(gestures_pinch)
+{
+       int cardinal = _i; /* ranged test */
+       test_gesture_pinch_2fg(cardinal);
+}
+END_TEST
+
+START_TEST(gestures_pinch_3fg)
+{
+       int cardinal = _i; /* ranged test */
+       test_gesture_pinch_3fg(cardinal);
+}
+END_TEST
+
+START_TEST(gestures_pinch_4fg)
+{
+       int cardinal = _i; /* ranged test */
+       test_gesture_pinch_4fg(cardinal);
+}
+END_TEST
+
+START_TEST(gestures_spread)
+{
+       int cardinal = _i; /* ranged test */
+       test_gesture_spread(cardinal);
+}
+END_TEST
+
 START_TEST(gestures_time_usec)
 {
        struct litest_device *dev = litest_current_device();
@@ -1012,27 +1074,7 @@ END_TEST
 
 START_TEST(gestures_3fg_buttonarea_scroll)
 {
-       struct litest_device *dev = litest_current_device();
-       struct libinput *li = dev->libinput;
-
-       if (litest_slot_count(dev) < 3)
-               return;
-
-       litest_enable_buttonareas(dev);
-       litest_enable_2fg_scroll(dev);
-       litest_drain_events(li);
-
-       litest_touch_down(dev, 0, 40, 20);
-       litest_touch_down(dev, 1, 30, 20);
-       /* third finger in btnarea */
-       litest_touch_down(dev, 2, 50, 99);
-       libinput_dispatch(li);
-       litest_touch_move_two_touches(dev, 40, 20, 30, 20, 0, 40, 10);
-
-       litest_touch_up(dev, 0);
-       litest_touch_up(dev, 1);
-       libinput_dispatch(li);
-       litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
+       test_gesture_3fg_buttonarea_scroll();
 }
 END_TEST