test: set the elan test device to always double up on tool bits
authorPeter Hutterer <peter.hutterer@who-t.net>
Thu, 10 Sep 2020 23:54:24 +0000 (09:54 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 22 Sep 2020 07:35:41 +0000 (17:35 +1000)
This is the device from
https://gitlab.freedesktop.org/libinput/libinput/-/issues/259 which sets
BTN_TOOL_PEN in addition to the real tool. Integrate this into the test device
proper so it always does this to catch various outliers.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
test/litest-device-elan-tablet.c
test/litest-int.h
test/litest.c
test/test-tablet.c

index 433a03c..a55635d 100644 (file)
@@ -26,7 +26,7 @@
 #include "litest.h"
 #include "litest-int.h"
 
-static struct input_event proximity_in[] = {
+static struct input_event proximity_in_events[] = {
        { .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
        { .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
        { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },
@@ -35,13 +35,13 @@ static struct input_event proximity_in[] = {
        { .type = -1, .code = -1 },
 };
 
-static struct input_event proximity_out[] = {
+static struct input_event proximity_out_events[] = {
        { .type = EV_KEY, .code = LITEST_BTN_TOOL_AUTO, .value = 0 },
        { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
        { .type = -1, .code = -1 },
 };
 
-static struct input_event motion[] = {
+static struct input_event motion_events[] = {
        { .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
        { .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
        { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },
@@ -49,6 +49,42 @@ static struct input_event motion[] = {
        { .type = -1, .code = -1 },
 };
 
+static bool
+proximity_in(struct litest_device *d,
+            unsigned int tool_type,
+            double x, double y,
+            struct axis_replacement *axes)
+{
+       /* nothing special needed for the pen tool, so let litest handle
+        * this */
+       if (tool_type == BTN_TOOL_PEN)
+               return false;
+
+       /* a non-pen tool requires the pen to be in proximity as well.  */
+       x = litest_scale(d, ABS_X, x);
+       y = litest_scale(d, ABS_Y, y);
+       litest_event(d, EV_ABS, ABS_X, x);
+       litest_event(d, EV_ABS, ABS_X, y);
+       litest_event(d, EV_KEY, BTN_TOOL_PEN, 1);
+       litest_event(d, EV_SYN, SYN_REPORT, 0);
+
+       /* litest will append the proximity_in_events if we return false,
+        * including the right tool event */
+       return false;
+}
+
+static bool
+proximity_out(struct litest_device *d, unsigned int tool_type)
+{
+       /* a non-pen tool requires the pen to go out of proximity as well.
+        * litest will append the proximity_out_events if we return false
+        */
+       if (tool_type != BTN_TOOL_PEN)
+               litest_event(d, EV_KEY, BTN_TOOL_PEN, 0);
+
+       return false;
+}
+
 static int
 get_axis_default(struct litest_device *d, unsigned int evcode, int32_t *value)
 {
@@ -61,9 +97,11 @@ get_axis_default(struct litest_device *d, unsigned int evcode, int32_t *value)
 }
 
 static struct litest_device_interface interface = {
-       .tablet_proximity_in_events = proximity_in,
-       .tablet_proximity_out_events = proximity_out,
-       .tablet_motion_events = motion,
+       .tablet_proximity_in_events = proximity_in_events,
+       .tablet_proximity_out_events = proximity_out_events,
+       .tablet_motion_events = motion_events,
+       .tablet_proximity_in = proximity_in,
+       .tablet_proximity_out = proximity_out,
 
        .get_axis_default = get_axis_default,
 };
@@ -82,6 +120,11 @@ static struct input_id input_id = {
        .version = 0x100,
 };
 
+/* Note: this tablet is one that sets both BTN_TOOL_PEN and BTN_TOOL_RUBBER,
+ * see https://gitlab.freedesktop.org/libinput/libinput/-/issues/259
+ * The one in the issue isn't the exact same model, but only the pid and x/y
+ * axis max differs differs.
+ */
 static int events[] = {
        EV_KEY, BTN_TOOL_PEN,
        EV_KEY, BTN_TOOL_RUBBER,
index 5bc62d9..06717d1 100644 (file)
@@ -114,6 +114,12 @@ struct litest_device_interface {
        struct input_event *tablet_proximity_out_events;
        struct input_event *tablet_motion_events;
 
+       bool (*tablet_proximity_in)(struct litest_device *d,
+                                   unsigned int tool_type,
+                                   double x, double y,
+                                   struct axis_replacement *axes);
+       bool (*tablet_proximity_out)(struct litest_device *d, unsigned int tool_type);
+
        /**
         * Pad events, LITEST_AUTO_ASSIGN is allowed on event values
         * for ABS_WHEEL
index 4011123..cd5df72 100644 (file)
@@ -2478,6 +2478,12 @@ litest_tablet_proximity_in(struct litest_device *d, int x, int y, struct axis_re
 {
        struct input_event *ev;
 
+       /* If the test device overrides proximity_in and says it didn't
+        * handle the event, let's continue normally */
+       if (d->interface->tablet_proximity_in &&
+           d->interface->tablet_proximity_in(d, d->interface->tool_type, x, y, axes))
+               return;
+
        ev = d->interface->tablet_proximity_in_events;
        while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
                int value;
@@ -2500,6 +2506,12 @@ litest_tablet_proximity_out(struct litest_device *d)
 {
        struct input_event *ev;
 
+       /* If the test device overrides proximity_out and says it didn't
+        * handle the event, let's continue normally */
+       if (d->interface->tablet_proximity_out &&
+           d->interface->tablet_proximity_out(d, d->interface->tool_type))
+               return;
+
        ev = d->interface->tablet_proximity_out_events;
        while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
                int value;
index 7feeb22..a0a8de8 100644 (file)
@@ -2812,6 +2812,8 @@ START_TEST(tool_type)
        litest_drain_events(li);
 
        for (tt = types; tt->code != -1; tt++) {
+               enum libinput_tablet_tool_type type;
+
                if (!libevdev_has_event_code(dev->evdev,
                                             EV_KEY,
                                             tt->code))
@@ -2829,9 +2831,27 @@ START_TEST(tool_type)
                t = litest_is_tablet_event(event,
                                   LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
                tool = libinput_event_tablet_tool_get_tool(t);
+               type = libinput_tablet_tool_get_type(tool);
+
+               /* Devices with doubled-up tool bits send the pen
+                * in-prox and immediately out-of-prox before the real tool
+                * type. Drop those two and continue with what we expect is
+                * the real prox in event */
+               if (tt->type != LIBINPUT_TABLET_TOOL_TYPE_PEN &&
+                   type == LIBINPUT_TABLET_TOOL_TYPE_PEN) {
+                       libinput_event_destroy(event);
+                       event = libinput_get_event(li);
+                       t = litest_is_tablet_event(event,
+                                          LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+                       libinput_event_destroy(event);
+                       event = libinput_get_event(li);
+                       t = litest_is_tablet_event(event,
+                                          LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+                       tool = libinput_event_tablet_tool_get_tool(t);
+                       type = libinput_tablet_tool_get_type(tool);
+               }
 
-               ck_assert_int_eq(libinput_tablet_tool_get_type(tool),
-                                tt->type);
+               ck_assert_int_eq(type, tt->type);
 
                libinput_event_destroy(event);
                litest_assert_empty_queue(li);