[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