[PATCH v2 libinput] tablet: support tool-specific pressure offsets

Ping Cheng pinglinux at gmail.com
Thu Dec 10 18:50:55 PST 2015


On Thu, Dec 10, 2015 at 1:31 AM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> If a tool wears out, it may have a pre-loaded pressure offset. In that case,
> even when the tool is not physically in contact with the tablet surface it
> will send pressure events.
>
> Use automatic pressure offset detection, similar to what the X.Org wacom
> driver does. On proximity-in, check the pressure and if the distance is above
> 50% of the range and the pressure is nonzero but below 20% of the range, use
> that value as pressure offset.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

Patch looks good to me.

Reviewed-by: Ping Cheng <pingc at wacom.com>

Cheers,

Ping

PS, some users may want to use their tools until the pre-loaded
pressure reached 80% or more. But, that's their problems :-).

PPS, I remember somewhere you mentioned libinput doesn't support
click/pressure threshold. When do we send left button down event?

> ---
> Changes to v1:
> - don't use a static udev property, try to detect the offset on proximity in
>
>  doc/tablet-support.dox                   |  29 +++
>  src/evdev-tablet.c                       |  84 ++++++++-
>  src/evdev-tablet.h                       |  21 +++
>  src/libinput-private.h                   |   2 +
>  test/litest-device-wacom-intuos-tablet.c |   1 +
>  test/tablet.c                            | 313 ++++++++++++++++++++++++++++++-
>  6 files changed, 446 insertions(+), 4 deletions(-)
>
> diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
> index 24d08d2..5468c6f 100644
> --- a/doc/tablet-support.dox
> +++ b/doc/tablet-support.dox
> @@ -92,4 +92,33 @@ if (value < min) {
>  }
>  @endcode
>
> + at section tablet-pressure-offset Pressure offset on worn-out tools
> +
> +When a tool is used for an extended period it can wear down physically. A
> +worn-down tool may never return a zero pressure value. Even when hovering
> +above the surface, the pressure value returned by the tool is nonzero,
> +creating a fake surface touch and making interaction with the tablet less
> +predictable.
> +
> +libinput automatically detects pressure offsets and rescales the remaining
> +pressure range into the available range, making pressure-offsets transparent
> +to the caller. A tool with a pressure offset will thus send a 0 pressure
> +value for the detected offset and nonzero pressure values for values higher
> +than that offset.
> +
> +Some limitations apply to avoid misdetection of pressure offsets,
> +specifically:
> +- pressure offset is only detected on proximity in, and if a device is
> +  capable of detection distances,
> +- pressure offset is only detected if the distance between the tool and the
> +  tablet is high enough,
> +- pressure offset is only used if it is 20% or less of the pressure range
> +  available to the tool. A pressure offset higher than 20% indicates either
> +  a misdetection or a tool that should be replaced, and
> +- if a pressure value less than the current pressure offset is seen, the
> +  offset resets to that value.
> +
> +Pressure offsets are not detected on @ref LIBINPUT_TABLET_TOOL_TYPE_MOUSE
> +and @ref LIBINPUT_TABLET_TOOL_TYPE_LENS tools.
> +
>  */
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index cd208a8..909cc76 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -21,9 +21,11 @@
>   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
>  #include "config.h"
> +#include "libinput-version.h"
>  #include "evdev-tablet.h"
>
>  #include <assert.h>
> +#include <inttypes.h>
>  #include <stdbool.h>
>  #include <string.h>
>
> @@ -202,7 +204,7 @@ tablet_update_tool(struct tablet_dispatch *tablet,
>  }
>
>  static inline double
> -normalize_pressure_dist_slider(const struct input_absinfo *absinfo)
> +normalize_dist_slider(const struct input_absinfo *absinfo)
>  {
>         double range = absinfo->maximum - absinfo->minimum;
>         double value = (absinfo->value - absinfo->minimum) / range;
> @@ -211,6 +213,18 @@ normalize_pressure_dist_slider(const struct input_absinfo *absinfo)
>  }
>
>  static inline double
> +normalize_pressure(const struct input_absinfo *absinfo,
> +                  struct libinput_tablet_tool *tool)
> +{
> +       double range = absinfo->maximum - absinfo->minimum;
> +       int offset = tool->pressure_offset != INT_MIN ?
> +                       tool->pressure_offset : 0;
> +       double value = (absinfo->value - offset - absinfo->minimum) / range;
> +
> +       return value;
> +}
> +
> +static inline double
>  normalize_tilt(const struct input_absinfo *absinfo)
>  {
>         double range = absinfo->maximum - absinfo->minimum;
> @@ -405,10 +419,12 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
>                         else
>                                 tablet->axes[a] = absinfo->value;
>                         break;
> -               case LIBINPUT_TABLET_TOOL_AXIS_DISTANCE:
>                 case LIBINPUT_TABLET_TOOL_AXIS_PRESSURE:
> +                       tablet->axes[a] = normalize_pressure(absinfo, tool);
> +                       break;
> +               case LIBINPUT_TABLET_TOOL_AXIS_DISTANCE:
>                 case LIBINPUT_TABLET_TOOL_AXIS_SLIDER:
> -                       tablet->axes[a] = normalize_pressure_dist_slider(absinfo);
> +                       tablet->axes[a] = normalize_dist_slider(absinfo);
>                         break;
>                 case LIBINPUT_TABLET_TOOL_AXIS_TILT_X:
>                 case LIBINPUT_TABLET_TOOL_AXIS_TILT_Y:
> @@ -816,6 +832,7 @@ tablet_get_tool(struct tablet_dispatch *tablet,
>                         .refcount = 1,
>                 };
>
> +               tool->pressure_offset = INT_MIN;
>                 tool_set_bits(tablet, tool);
>
>                 list_insert(tool_list, &tool->link);
> @@ -929,6 +946,66 @@ sanitize_tablet_axes(struct tablet_dispatch *tablet)
>                 set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
>  }
>
> +static inline int
> +axis_range_percentage(const struct input_absinfo *a, int percent)
> +{
> +       return (a->maximum - a->minimum) * percent/100 + a->minimum;
> +}
> +
> +static void
> +detect_pressure_offset(struct tablet_dispatch *tablet,
> +                      struct evdev_device *device,
> +                      struct libinput_tablet_tool *tool)
> +{
> +       const struct input_absinfo *pressure, *distance;
> +       int offset;
> +
> +       if (!bit_is_set(tablet->changed_axes,
> +                       LIBINPUT_TABLET_TOOL_AXIS_PRESSURE))
> +               return;
> +
> +       pressure = libevdev_get_abs_info(device->evdev, ABS_PRESSURE);
> +       distance = libevdev_get_abs_info(device->evdev, ABS_DISTANCE);
> +
> +       if (!pressure || !distance)
> +               return;
> +
> +       offset = pressure->value - pressure->minimum;
> +
> +       if (tool->pressure_offset != INT_MIN) {
> +               if (offset < tool->pressure_offset)
> +                       tool->pressure_offset = offset;
> +               return;
> +       }
> +
> +       /* we only set a pressure offset on proximity in */
> +       if (!tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY))
> +               return;
> +
> +       /* If we're closer than 50% of the distance axis, skip pressure
> +        * offset detection, too likely to be wrong */
> +       if (distance->value < axis_range_percentage(distance, 50))
> +               return;
> +
> +       if (offset > axis_range_percentage(pressure, 20)) {
> +               log_error(device->base.seat->libinput,
> +                        "Ignoring pressure offset greater than 20%% detected on tool %s (serial %#x). "
> +                        "See http://wayland.freedesktop.org/libinput/doc/%s/tablet-support.html\n",
> +                        tablet_tool_type_to_string(tool->type),
> +                        tool->serial,
> +                        LIBINPUT_VERSION);
> +               return;
> +       }
> +
> +       log_info(device->base.seat->libinput,
> +                "Pressure offset detected on tool %s (serial %#x).  "
> +                "See http://wayland.freedesktop.org/libinput/doc/%s/tablet-support.html\n",
> +                tablet_tool_type_to_string(tool->type),
> +                tool->serial,
> +                LIBINPUT_VERSION);
> +       tool->pressure_offset = offset;
> +}
> +
>  static void
>  tablet_flush(struct tablet_dispatch *tablet,
>              struct evdev_device *device,
> @@ -953,6 +1030,7 @@ tablet_flush(struct tablet_dispatch *tablet,
>                         tablet_set_status(tablet, TABLET_TOOL_LEAVING_CONTACT);
>         } else if (tablet_has_status(tablet, TABLET_AXES_UPDATED) ||
>                    tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY)) {
> +               detect_pressure_offset(tablet, device, tool);
>                 sanitize_tablet_axes(tablet);
>                 tablet_check_notify_axes(tablet, device, time, tool);
>
> diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> index 162b536..4dcbccc 100644
> --- a/src/evdev-tablet.h
> +++ b/src/evdev-tablet.h
> @@ -178,4 +178,25 @@ tablet_tool_to_evcode(enum libinput_tablet_tool_type type)
>
>         return code;
>  }
> +
> +static inline const char *
> +tablet_tool_type_to_string(enum libinput_tablet_tool_type type)
> +{
> +       const char *str;
> +
> +       switch (type) {
> +       case LIBINPUT_TABLET_TOOL_TYPE_PEN:       str = "pen";          break;
> +       case LIBINPUT_TABLET_TOOL_TYPE_ERASER:    str = "eraser";       break;
> +       case LIBINPUT_TABLET_TOOL_TYPE_BRUSH:     str = "brush";        break;
> +       case LIBINPUT_TABLET_TOOL_TYPE_PENCIL:    str = "pencil";       break;
> +       case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:  str = "airbrush";     break;
> +       case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:     str = "mouse";        break;
> +       case LIBINPUT_TABLET_TOOL_TYPE_LENS:      str = "lens";         break;
> +       default:
> +               abort();
> +       }
> +
> +       return str;
> +}
> +
>  #endif
> diff --git a/src/libinput-private.h b/src/libinput-private.h
> index 38a14b8..091fd98 100644
> --- a/src/libinput-private.h
> +++ b/src/libinput-private.h
> @@ -259,6 +259,8 @@ struct libinput_tablet_tool {
>         unsigned char buttons[NCHARS(KEY_MAX) + 1];
>         int refcount;
>         void *user_data;
> +
> +       int pressure_offset;
>  };
>
>  struct libinput_event {
> diff --git a/test/litest-device-wacom-intuos-tablet.c b/test/litest-device-wacom-intuos-tablet.c
> index e0e1d44..ef0a1f1 100644
> --- a/test/litest-device-wacom-intuos-tablet.c
> +++ b/test/litest-device-wacom-intuos-tablet.c
> @@ -37,6 +37,7 @@ static struct input_event proximity_in[] = {
>         { .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_DISTANCE, .value = LITEST_AUTO_ASSIGN },
> +       { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },
>         { .type = EV_ABS, .code = ABS_TILT_X, .value = LITEST_AUTO_ASSIGN },
>         { .type = EV_ABS, .code = ABS_TILT_Y, .value = LITEST_AUTO_ASSIGN },
>         { .type = EV_ABS, .code = ABS_MISC, .value = 1050626 },
> diff --git a/test/tablet.c b/test/tablet.c
> index 18f08b2..9cfc42f 100644
> --- a/test/tablet.c
> +++ b/test/tablet.c
> @@ -2313,7 +2313,7 @@ START_TEST(tablet_pressure_distance_exclusive)
>         struct libinput_event_tablet_tool *tev;
>         struct axis_replacement axes[] = {
>                 { ABS_DISTANCE, 10 },
> -               { ABS_PRESSURE, 20 },
> +               { ABS_PRESSURE, 20 }, /* see the litest device */
>                 { -1, -1 },
>         };
>         double pressure, distance;
> @@ -2530,6 +2530,310 @@ START_TEST(tablet_calibration_set_matrix)
>  }
>  END_TEST
>
> +START_TEST(tablet_pressure_offset)
> +{
> +       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, 70 },
> +               { ABS_PRESSURE, 20 },
> +               { -1, -1 },
> +       };
> +       double pressure;
> +
> +       litest_tablet_proximity_in(dev, 5, 100, axes);
> +       litest_drain_events(li);
> +
> +       axes[0].value = 0;
> +       axes[1].value = 21;
> +       litest_push_event_frame(dev);
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       litest_event(dev, EV_KEY, BTN_TOUCH, 1);
> +       litest_pop_event_frame(dev);
> +       libinput_dispatch(li);
> +       litest_drain_events(li);
> +
> +       axes[1].value = 20;
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +       ck_assert_double_eq(pressure, 0.0);
> +
> +       libinput_event_destroy(event);
> +       litest_drain_events(li);
> +
> +       axes[1].value = 21;
> +       litest_tablet_motion(dev, 70, 70, axes);
> +
> +       libinput_dispatch(li);
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +
> +       /* can't use the double_eq here, the pressure value is too tiny */
> +       ck_assert(pressure > 0.0);
> +       ck_assert(pressure < 1.0);
> +       libinput_event_destroy(event);
> +}
> +END_TEST
> +
> +START_TEST(tablet_pressure_offset_decrease)
> +{
> +       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, 70 },
> +               { ABS_PRESSURE, 20 },
> +               { -1, -1 },
> +       };
> +       double pressure;
> +
> +       /* offset 20 on prox in */
> +       litest_tablet_proximity_in(dev, 5, 100, axes);
> +       litest_drain_events(li);
> +
> +       /* a reduced pressure value must reduce the offset */
> +       axes[0].value = 0;
> +       axes[1].value = 10;
> +       litest_push_event_frame(dev);
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       litest_event(dev, EV_KEY, BTN_TOUCH, 1);
> +       litest_pop_event_frame(dev);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +       ck_assert_double_eq(pressure, 0.0);
> +
> +       libinput_event_destroy(event);
> +       litest_drain_events(li);
> +
> +       axes[1].value = 11;
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +
> +       /* can't use the double_eq here, the pressure value is too tiny */
> +       ck_assert(pressure > 0.0);
> +       ck_assert(pressure < 1.0);
> +       libinput_event_destroy(event);
> +}
> +END_TEST
> +
> +START_TEST(tablet_pressure_offset_increase)
> +{
> +       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, 70 },
> +               { ABS_PRESSURE, 20 },
> +               { -1, -1 },
> +       };
> +       double pressure;
> +
> +       /* offset 20 on first prox in */
> +       litest_tablet_proximity_in(dev, 5, 100, axes);
> +       litest_tablet_proximity_out(dev);
> +       litest_drain_events(li);
> +
> +       /* offset 30 on second prox in - must not change the offset */
> +       axes[1].value = 30;
> +       litest_tablet_proximity_in(dev, 5, 100, axes);
> +       litest_drain_events(li);
> +
> +       axes[0].value = 0;
> +       axes[1].value = 31;
> +       litest_push_event_frame(dev);
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       litest_event(dev, EV_KEY, BTN_TOUCH, 1);
> +       litest_pop_event_frame(dev);
> +       libinput_dispatch(li);
> +       litest_drain_events(li);
> +
> +       axes[1].value = 30;
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +       /* can't use the double_eq here, the pressure value is too tiny */
> +       ck_assert(pressure > 0.0);
> +       ck_assert(pressure < 1.0);
> +       libinput_event_destroy(event);
> +
> +       litest_drain_events(li);
> +
> +       axes[1].value = 20;
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +
> +       ck_assert_double_eq(pressure, 0.0);
> +       libinput_event_destroy(event);
> +}
> +END_TEST
> +
> +START_TEST(tablet_pressure_offset_exceed_threshold)
> +{
> +       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, 70 },
> +               { ABS_PRESSURE, 30 },
> +               { -1, -1 },
> +       };
> +       double pressure;
> +
> +       litest_drain_events(li);
> +
> +       litest_disable_log_handler(li);
> +       litest_tablet_proximity_in(dev, 5, 100, axes);
> +       libinput_dispatch(li);
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +       ck_assert_double_eq(pressure, 0.0);
> +       libinput_event_destroy(event);
> +       litest_restore_log_handler(li);
> +
> +       axes[0].value = 0;
> +       axes[1].value = 31;
> +       litest_push_event_frame(dev);
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       litest_event(dev, EV_KEY, BTN_TOUCH, 1);
> +       litest_pop_event_frame(dev);
> +       libinput_dispatch(li);
> +       litest_drain_events(li);
> +
> +       axes[1].value = 30;
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +       ck_assert_double_gt(pressure, 0.0);
> +
> +       libinput_event_destroy(event);
> +}
> +END_TEST
> +
> +START_TEST(tablet_pressure_offset_none_for_zero_distance)
> +{
> +       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, 0 },
> +               { ABS_PRESSURE, 20 },
> +               { -1, -1 },
> +       };
> +       double pressure;
> +
> +       litest_drain_events(li);
> +
> +       /* we're going straight to touch on proximity, make sure we don't
> +        * offset the pressure here */
> +       litest_push_event_frame(dev);
> +       litest_tablet_proximity_in(dev, 5, 100, axes);
> +       litest_event(dev, EV_KEY, BTN_TOUCH, 1);
> +       litest_pop_event_frame(dev);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tev = litest_is_tablet_event(event,
> +                                    LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +       ck_assert_double_gt(pressure, 0.0);
> +
> +       libinput_event_destroy(event);
> +}
> +END_TEST
> +
> +START_TEST(tablet_pressure_offset_none_for_small_distance)
> +{
> +       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, 20 },
> +               { ABS_PRESSURE, 20 },
> +               { -1, -1 },
> +       };
> +       double pressure;
> +
> +       /* stylus too close to the tablet on the proximity in, ignore any
> +        * pressure offset */
> +       litest_tablet_proximity_in(dev, 5, 100, axes);
> +       litest_drain_events(li);
> +       libinput_dispatch(li);
> +
> +       axes[0].value = 0;
> +       axes[1].value = 21;
> +       litest_push_event_frame(dev);
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       litest_event(dev, EV_KEY, BTN_TOUCH, 1);
> +       litest_pop_event_frame(dev);
> +       litest_drain_events(li);
> +
> +       axes[1].value = 20;
> +       litest_tablet_motion(dev, 70, 70, axes);
> +       libinput_dispatch(li);
> +
> +       litest_wait_for_event_of_type(li,
> +                                     LIBINPUT_EVENT_TABLET_TOOL_AXIS,
> +                                     -1);
> +       event = libinput_get_event(li);
> +       tev = libinput_event_get_tablet_tool_event(event);
> +       pressure = libinput_event_tablet_tool_get_axis_value(tev,
> +                                                            LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
> +       ck_assert_double_gt(pressure, 0.0);
> +
> +       libinput_event_destroy(event);
> +}
> +END_TEST
> +
>  void
>  litest_setup_tests(void)
>  {
> @@ -2578,4 +2882,11 @@ litest_setup_tests(void)
>         litest_add("tablet:calibration", tablet_calibration_has_matrix, LITEST_TABLET, LITEST_ANY);
>         litest_add("tablet:calibration", tablet_calibration_set_matrix, LITEST_TABLET, LITEST_ANY);
>         litest_add("tablet:calibration", tablet_calibration_set_matrix_delta, LITEST_TABLET, LITEST_ANY);
> +
> +       litest_add_for_device("tablet:pressure", tablet_pressure_offset, LITEST_WACOM_INTUOS);
> +       litest_add_for_device("tablet:pressure", tablet_pressure_offset_decrease, LITEST_WACOM_INTUOS);
> +       litest_add_for_device("tablet:pressure", tablet_pressure_offset_increase, LITEST_WACOM_INTUOS);
> +       litest_add_for_device("tablet:pressure", tablet_pressure_offset_exceed_threshold, LITEST_WACOM_INTUOS);
> +       litest_add_for_device("tablet:pressure", tablet_pressure_offset_none_for_zero_distance, LITEST_WACOM_INTUOS);
> +       litest_add_for_device("tablet:pressure", tablet_pressure_offset_none_for_small_distance, LITEST_WACOM_INTUOS);
>  }
> --
> 2.5.0
>


More information about the wayland-devel mailing list