[PATCH v2 libinput] tablet: support tool-specific pressure offsets
Peter Hutterer
peter.hutterer at who-t.net
Thu Dec 10 21:01:14 PST 2015
On Thu, Dec 10, 2015 at 06:50:55PM -0800, Ping Cheng wrote:
> 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>
thanks, much appreciated
>
> 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?
atm we're just using BTN_TOUCH for the tip down/up events, but I've got this
on my todo list.
Cheers,
Peter
>
> > ---
> > 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