On Sunday, December 13, 2015, Peter Hutterer <<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.net</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">If a tool wears out, it may have a pre-loaded pressure offset. In that case,<br>
even when the tool is not physically in contact with the tablet surface it<br>
will send pressure events.<br>
<br>
Use automatic pressure offset detection, similar to what the X.Org wacom<br>
driver does. On proximity-in, check the pressure and if the distance is above<br>
50% of the range and the pressure is nonzero but below 20% of the range, use<br>
that value as pressure offset.<br>
<br>
Signed-off-by: Peter Hutterer <<a href="javascript:;" onclick="_e(event, 'cvml', 'peter.hutterer@who-t.net')">peter.hutterer@who-t.net</a>></blockquote><div><span style="color:rgb(34,34,34);font-size:14px"><br></span></div><div><span style="color:rgb(34,34,34);font-size:14px">There is no logical change in this version. So, it is still</span></div><div><span style="color:rgb(34,34,34);font-size:14px"><br></span></div><div><span style="color:rgb(34,34,34);font-size:14px">Reviewed-by: Ping Cheng <</span><a style="color:rgb(17,85,204);font-size:14px">pingc@wacom.com</a><span style="color:rgb(34,34,34);font-size:14px">></span><br></div><br style="color:rgb(34,34,34);font-size:14px"><span style="color:rgb(34,34,34);font-size:14px">Ping</span><br style="color:rgb(34,34,34);font-size:14px"><br style="color:rgb(34,34,34);font-size:14px"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> ---<br>
Changes to v2:<br>
- rather than using offset != INT_MIN everywhere, add a has_pressure_offset<br>
boolean and check that. Makes the code much nicer<br>
<br>
doc/tablet-support.dox | 29 +++<br>
src/evdev-tablet.c | 86 ++++++++-<br>
src/evdev-tablet.h | 21 +++<br>
src/libinput-private.h | 3 +<br>
test/litest-device-wacom-intuos-tablet.c | 1 +<br>
test/tablet.c | 313 ++++++++++++++++++++++++++++++-<br>
6 files changed, 449 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox<br>
index 24d08d2..5468c6f 100644<br>
--- a/doc/tablet-support.dox<br>
+++ b/doc/tablet-support.dox<br>
@@ -92,4 +92,33 @@ if (value < min) {<br>
}<br>
@endcode<br>
<br>
+@section tablet-pressure-offset Pressure offset on worn-out tools<br>
+<br>
+When a tool is used for an extended period it can wear down physically. A<br>
+worn-down tool may never return a zero pressure value. Even when hovering<br>
+above the surface, the pressure value returned by the tool is nonzero,<br>
+creating a fake surface touch and making interaction with the tablet less<br>
+predictable.<br>
+<br>
+libinput automatically detects pressure offsets and rescales the remaining<br>
+pressure range into the available range, making pressure-offsets transparent<br>
+to the caller. A tool with a pressure offset will thus send a 0 pressure<br>
+value for the detected offset and nonzero pressure values for values higher<br>
+than that offset.<br>
+<br>
+Some limitations apply to avoid misdetection of pressure offsets,<br>
+specifically:<br>
+- pressure offset is only detected on proximity in, and if a device is<br>
+ capable of detection distances,<br>
+- pressure offset is only detected if the distance between the tool and the<br>
+ tablet is high enough,<br>
+- pressure offset is only used if it is 20% or less of the pressure range<br>
+ available to the tool. A pressure offset higher than 20% indicates either<br>
+ a misdetection or a tool that should be replaced, and<br>
+- if a pressure value less than the current pressure offset is seen, the<br>
+ offset resets to that value.<br>
+<br>
+Pressure offsets are not detected on @ref LIBINPUT_TABLET_TOOL_TYPE_MOUSE<br>
+and @ref LIBINPUT_TABLET_TOOL_TYPE_LENS tools.<br>
+<br>
*/<br>
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c<br>
index cd208a8..2a45575 100644<br>
--- a/src/evdev-tablet.c<br>
+++ b/src/evdev-tablet.c<br>
@@ -21,9 +21,11 @@<br>
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.<br>
*/<br>
#include "config.h"<br>
+#include "libinput-version.h"<br>
#include "evdev-tablet.h"<br>
<br>
#include <assert.h><br>
+#include <inttypes.h><br>
#include <stdbool.h><br>
#include <string.h><br>
<br>
@@ -202,7 +204,7 @@ tablet_update_tool(struct tablet_dispatch *tablet,<br>
}<br>
<br>
static inline double<br>
-normalize_pressure_dist_slider(const struct input_absinfo *absinfo)<br>
+normalize_dist_slider(const struct input_absinfo *absinfo)<br>
{<br>
double range = absinfo->maximum - absinfo->minimum;<br>
double value = (absinfo->value - absinfo->minimum) / range;<br>
@@ -211,6 +213,18 @@ normalize_pressure_dist_slider(const struct input_absinfo *absinfo)<br>
}<br>
<br>
static inline double<br>
+normalize_pressure(const struct input_absinfo *absinfo,<br>
+ struct libinput_tablet_tool *tool)<br>
+{<br>
+ double range = absinfo->maximum - absinfo->minimum;<br>
+ int offset = tool->has_pressure_offset ?<br>
+ tool->pressure_offset : 0;<br>
+ double value = (absinfo->value - offset - absinfo->minimum) / range;<br>
+<br>
+ return value;<br>
+}<br>
+<br>
+static inline double<br>
normalize_tilt(const struct input_absinfo *absinfo)<br>
{<br>
double range = absinfo->maximum - absinfo->minimum;<br>
@@ -405,10 +419,12 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,<br>
else<br>
tablet->axes[a] = absinfo->value;<br>
break;<br>
- case LIBINPUT_TABLET_TOOL_AXIS_DISTANCE:<br>
case LIBINPUT_TABLET_TOOL_AXIS_PRESSURE:<br>
+ tablet->axes[a] = normalize_pressure(absinfo, tool);<br>
+ break;<br>
+ case LIBINPUT_TABLET_TOOL_AXIS_DISTANCE:<br>
case LIBINPUT_TABLET_TOOL_AXIS_SLIDER:<br>
- tablet->axes[a] = normalize_pressure_dist_slider(absinfo);<br>
+ tablet->axes[a] = normalize_dist_slider(absinfo);<br>
break;<br>
case LIBINPUT_TABLET_TOOL_AXIS_TILT_X:<br>
case LIBINPUT_TABLET_TOOL_AXIS_TILT_Y:<br>
@@ -816,6 +832,8 @@ tablet_get_tool(struct tablet_dispatch *tablet,<br>
.refcount = 1,<br>
};<br>
<br>
+ tool->pressure_offset = 0;<br>
+ tool->has_pressure_offset = false;<br>
tool_set_bits(tablet, tool);<br>
<br>
list_insert(tool_list, &tool->link);<br>
@@ -929,6 +947,67 @@ sanitize_tablet_axes(struct tablet_dispatch *tablet)<br>
set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);<br>
}<br>
<br>
+static inline int<br>
+axis_range_percentage(const struct input_absinfo *a, int percent)<br>
+{<br>
+ return (a->maximum - a->minimum) * percent/100 + a->minimum;<br>
+}<br>
+<br>
+static void<br>
+detect_pressure_offset(struct tablet_dispatch *tablet,<br>
+ struct evdev_device *device,<br>
+ struct libinput_tablet_tool *tool)<br>
+{<br>
+ const struct input_absinfo *pressure, *distance;<br>
+ int offset;<br>
+<br>
+ if (!bit_is_set(tablet->changed_axes,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE))<br>
+ return;<br>
+<br>
+ pressure = libevdev_get_abs_info(device->evdev, ABS_PRESSURE);<br>
+ distance = libevdev_get_abs_info(device->evdev, ABS_DISTANCE);<br>
+<br>
+ if (!pressure || !distance)<br>
+ return;<br>
+<br>
+ offset = pressure->value - pressure->minimum;<br>
+<br>
+ if (tool->has_pressure_offset) {<br>
+ if (offset < tool->pressure_offset)<br>
+ tool->pressure_offset = offset;<br>
+ return;<br>
+ }<br>
+<br>
+ /* we only set a pressure offset on proximity in */<br>
+ if (!tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY))<br>
+ return;<br>
+<br>
+ /* If we're closer than 50% of the distance axis, skip pressure<br>
+ * offset detection, too likely to be wrong */<br>
+ if (distance->value < axis_range_percentage(distance, 50))<br>
+ return;<br>
+<br>
+ if (offset > axis_range_percentage(pressure, 20)) {<br>
+ log_error(device->base.seat->libinput,<br>
+ "Ignoring pressure offset greater than 20%% detected on tool %s (serial %#x). "<br>
+ "See <a href="http://wayland.freedesktop.org/libinput/doc/%s/tablet-support.html\n" target="_blank">http://wayland.freedesktop.org/libinput/doc/%s/tablet-support.html\n</a>",<br>
+ tablet_tool_type_to_string(tool->type),<br>
+ tool->serial,<br>
+ LIBINPUT_VERSION);<br>
+ return;<br>
+ }<br>
+<br>
+ log_info(device->base.seat->libinput,<br>
+ "Pressure offset detected on tool %s (serial %#x). "<br>
+ "See <a href="http://wayland.freedesktop.org/libinput/doc/%s/tablet-support.html\n" target="_blank">http://wayland.freedesktop.org/libinput/doc/%s/tablet-support.html\n</a>",<br>
+ tablet_tool_type_to_string(tool->type),<br>
+ tool->serial,<br>
+ LIBINPUT_VERSION);<br>
+ tool->pressure_offset = offset;<br>
+ tool->has_pressure_offset = true;<br>
+}<br>
+<br>
static void<br>
tablet_flush(struct tablet_dispatch *tablet,<br>
struct evdev_device *device,<br>
@@ -953,6 +1032,7 @@ tablet_flush(struct tablet_dispatch *tablet,<br>
tablet_set_status(tablet, TABLET_TOOL_LEAVING_CONTACT);<br>
} else if (tablet_has_status(tablet, TABLET_AXES_UPDATED) ||<br>
tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY)) {<br>
+ detect_pressure_offset(tablet, device, tool);<br>
sanitize_tablet_axes(tablet);<br>
tablet_check_notify_axes(tablet, device, time, tool);<br>
<br>
diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h<br>
index 162b536..4dcbccc 100644<br>
--- a/src/evdev-tablet.h<br>
+++ b/src/evdev-tablet.h<br>
@@ -178,4 +178,25 @@ tablet_tool_to_evcode(enum libinput_tablet_tool_type type)<br>
<br>
return code;<br>
}<br>
+<br>
+static inline const char *<br>
+tablet_tool_type_to_string(enum libinput_tablet_tool_type type)<br>
+{<br>
+ const char *str;<br>
+<br>
+ switch (type) {<br>
+ case LIBINPUT_TABLET_TOOL_TYPE_PEN: str = "pen"; break;<br>
+ case LIBINPUT_TABLET_TOOL_TYPE_ERASER: str = "eraser"; break;<br>
+ case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: str = "brush"; break;<br>
+ case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: str = "pencil"; break;<br>
+ case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: str = "airbrush"; break;<br>
+ case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: str = "mouse"; break;<br>
+ case LIBINPUT_TABLET_TOOL_TYPE_LENS: str = "lens"; break;<br>
+ default:<br>
+ abort();<br>
+ }<br>
+<br>
+ return str;<br>
+}<br>
+<br>
#endif<br>
diff --git a/src/libinput-private.h b/src/libinput-private.h<br>
index 38a14b8..f5b2648 100644<br>
--- a/src/libinput-private.h<br>
+++ b/src/libinput-private.h<br>
@@ -259,6 +259,9 @@ struct libinput_tablet_tool {<br>
unsigned char buttons[NCHARS(KEY_MAX) + 1];<br>
int refcount;<br>
void *user_data;<br>
+<br>
+ int pressure_offset;<br>
+ bool has_pressure_offset;<br>
};<br>
<br>
struct libinput_event {<br>
diff --git a/test/litest-device-wacom-intuos-tablet.c b/test/litest-device-wacom-intuos-tablet.c<br>
index e0e1d44..ef0a1f1 100644<br>
--- a/test/litest-device-wacom-intuos-tablet.c<br>
+++ b/test/litest-device-wacom-intuos-tablet.c<br>
@@ -37,6 +37,7 @@ static struct input_event proximity_in[] = {<br>
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },<br>
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },<br>
{ .type = EV_ABS, .code = ABS_DISTANCE, .value = LITEST_AUTO_ASSIGN },<br>
+ { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },<br>
{ .type = EV_ABS, .code = ABS_TILT_X, .value = LITEST_AUTO_ASSIGN },<br>
{ .type = EV_ABS, .code = ABS_TILT_Y, .value = LITEST_AUTO_ASSIGN },<br>
{ .type = EV_ABS, .code = ABS_MISC, .value = 1050626 },<br>
diff --git a/test/tablet.c b/test/tablet.c<br>
index 18f08b2..9cfc42f 100644<br>
--- a/test/tablet.c<br>
+++ b/test/tablet.c<br>
@@ -2313,7 +2313,7 @@ START_TEST(tablet_pressure_distance_exclusive)<br>
struct libinput_event_tablet_tool *tev;<br>
struct axis_replacement axes[] = {<br>
{ ABS_DISTANCE, 10 },<br>
- { ABS_PRESSURE, 20 },<br>
+ { ABS_PRESSURE, 20 }, /* see the litest device */<br>
{ -1, -1 },<br>
};<br>
double pressure, distance;<br>
@@ -2530,6 +2530,310 @@ START_TEST(tablet_calibration_set_matrix)<br>
}<br>
END_TEST<br>
<br>
+START_TEST(tablet_pressure_offset)<br>
+{<br>
+ struct litest_device *dev = litest_current_device();<br>
+ struct libinput *li = dev->libinput;<br>
+ struct libinput_event *event;<br>
+ struct libinput_event_tablet_tool *tev;<br>
+ struct axis_replacement axes[] = {<br>
+ { ABS_DISTANCE, 70 },<br>
+ { ABS_PRESSURE, 20 },<br>
+ { -1, -1 },<br>
+ };<br>
+ double pressure;<br>
+<br>
+ litest_tablet_proximity_in(dev, 5, 100, axes);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[0].value = 0;<br>
+ axes[1].value = 21;<br>
+ litest_push_event_frame(dev);<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ litest_event(dev, EV_KEY, BTN_TOUCH, 1);<br>
+ litest_pop_event_frame(dev);<br>
+ libinput_dispatch(li);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[1].value = 20;<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ libinput_dispatch(li);<br>
+<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS);<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+ ck_assert_double_eq(pressure, 0.0);<br>
+<br>
+ libinput_event_destroy(event);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[1].value = 21;<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+<br>
+ libinput_dispatch(li);<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS);<br>
+<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+<br>
+ /* can't use the double_eq here, the pressure value is too tiny */<br>
+ ck_assert(pressure > 0.0);<br>
+ ck_assert(pressure < 1.0);<br>
+ libinput_event_destroy(event);<br>
+}<br>
+END_TEST<br>
+<br>
+START_TEST(tablet_pressure_offset_decrease)<br>
+{<br>
+ struct litest_device *dev = litest_current_device();<br>
+ struct libinput *li = dev->libinput;<br>
+ struct libinput_event *event;<br>
+ struct libinput_event_tablet_tool *tev;<br>
+ struct axis_replacement axes[] = {<br>
+ { ABS_DISTANCE, 70 },<br>
+ { ABS_PRESSURE, 20 },<br>
+ { -1, -1 },<br>
+ };<br>
+ double pressure;<br>
+<br>
+ /* offset 20 on prox in */<br>
+ litest_tablet_proximity_in(dev, 5, 100, axes);<br>
+ litest_drain_events(li);<br>
+<br>
+ /* a reduced pressure value must reduce the offset */<br>
+ axes[0].value = 0;<br>
+ axes[1].value = 10;<br>
+ litest_push_event_frame(dev);<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ litest_event(dev, EV_KEY, BTN_TOUCH, 1);<br>
+ litest_pop_event_frame(dev);<br>
+ libinput_dispatch(li);<br>
+<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS);<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+ ck_assert_double_eq(pressure, 0.0);<br>
+<br>
+ libinput_event_destroy(event);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[1].value = 11;<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ libinput_dispatch(li);<br>
+<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS);<br>
+<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+<br>
+ /* can't use the double_eq here, the pressure value is too tiny */<br>
+ ck_assert(pressure > 0.0);<br>
+ ck_assert(pressure < 1.0);<br>
+ libinput_event_destroy(event);<br>
+}<br>
+END_TEST<br>
+<br>
+START_TEST(tablet_pressure_offset_increase)<br>
+{<br>
+ struct litest_device *dev = litest_current_device();<br>
+ struct libinput *li = dev->libinput;<br>
+ struct libinput_event *event;<br>
+ struct libinput_event_tablet_tool *tev;<br>
+ struct axis_replacement axes[] = {<br>
+ { ABS_DISTANCE, 70 },<br>
+ { ABS_PRESSURE, 20 },<br>
+ { -1, -1 },<br>
+ };<br>
+ double pressure;<br>
+<br>
+ /* offset 20 on first prox in */<br>
+ litest_tablet_proximity_in(dev, 5, 100, axes);<br>
+ litest_tablet_proximity_out(dev);<br>
+ litest_drain_events(li);<br>
+<br>
+ /* offset 30 on second prox in - must not change the offset */<br>
+ axes[1].value = 30;<br>
+ litest_tablet_proximity_in(dev, 5, 100, axes);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[0].value = 0;<br>
+ axes[1].value = 31;<br>
+ litest_push_event_frame(dev);<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ litest_event(dev, EV_KEY, BTN_TOUCH, 1);<br>
+ litest_pop_event_frame(dev);<br>
+ libinput_dispatch(li);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[1].value = 30;<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ libinput_dispatch(li);<br>
+<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS);<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+ /* can't use the double_eq here, the pressure value is too tiny */<br>
+ ck_assert(pressure > 0.0);<br>
+ ck_assert(pressure < 1.0);<br>
+ libinput_event_destroy(event);<br>
+<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[1].value = 20;<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ libinput_dispatch(li);<br>
+<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS);<br>
+<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+<br>
+ ck_assert_double_eq(pressure, 0.0);<br>
+ libinput_event_destroy(event);<br>
+}<br>
+END_TEST<br>
+<br>
+START_TEST(tablet_pressure_offset_exceed_threshold)<br>
+{<br>
+ struct litest_device *dev = litest_current_device();<br>
+ struct libinput *li = dev->libinput;<br>
+ struct libinput_event *event;<br>
+ struct libinput_event_tablet_tool *tev;<br>
+ struct axis_replacement axes[] = {<br>
+ { ABS_DISTANCE, 70 },<br>
+ { ABS_PRESSURE, 30 },<br>
+ { -1, -1 },<br>
+ };<br>
+ double pressure;<br>
+<br>
+ litest_drain_events(li);<br>
+<br>
+ litest_disable_log_handler(li);<br>
+ litest_tablet_proximity_in(dev, 5, 100, axes);<br>
+ libinput_dispatch(li);<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+ ck_assert_double_eq(pressure, 0.0);<br>
+ libinput_event_destroy(event);<br>
+ litest_restore_log_handler(li);<br>
+<br>
+ axes[0].value = 0;<br>
+ axes[1].value = 31;<br>
+ litest_push_event_frame(dev);<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ litest_event(dev, EV_KEY, BTN_TOUCH, 1);<br>
+ litest_pop_event_frame(dev);<br>
+ libinput_dispatch(li);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[1].value = 30;<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ libinput_dispatch(li);<br>
+<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS);<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+ ck_assert_double_gt(pressure, 0.0);<br>
+<br>
+ libinput_event_destroy(event);<br>
+}<br>
+END_TEST<br>
+<br>
+START_TEST(tablet_pressure_offset_none_for_zero_distance)<br>
+{<br>
+ struct litest_device *dev = litest_current_device();<br>
+ struct libinput *li = dev->libinput;<br>
+ struct libinput_event *event;<br>
+ struct libinput_event_tablet_tool *tev;<br>
+ struct axis_replacement axes[] = {<br>
+ { ABS_DISTANCE, 0 },<br>
+ { ABS_PRESSURE, 20 },<br>
+ { -1, -1 },<br>
+ };<br>
+ double pressure;<br>
+<br>
+ litest_drain_events(li);<br>
+<br>
+ /* we're going straight to touch on proximity, make sure we don't<br>
+ * offset the pressure here */<br>
+ litest_push_event_frame(dev);<br>
+ litest_tablet_proximity_in(dev, 5, 100, axes);<br>
+ litest_event(dev, EV_KEY, BTN_TOUCH, 1);<br>
+ litest_pop_event_frame(dev);<br>
+ libinput_dispatch(li);<br>
+<br>
+ event = libinput_get_event(li);<br>
+ tev = litest_is_tablet_event(event,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+ ck_assert_double_gt(pressure, 0.0);<br>
+<br>
+ libinput_event_destroy(event);<br>
+}<br>
+END_TEST<br>
+<br>
+START_TEST(tablet_pressure_offset_none_for_small_distance)<br>
+{<br>
+ struct litest_device *dev = litest_current_device();<br>
+ struct libinput *li = dev->libinput;<br>
+ struct libinput_event *event;<br>
+ struct libinput_event_tablet_tool *tev;<br>
+ struct axis_replacement axes[] = {<br>
+ { ABS_DISTANCE, 20 },<br>
+ { ABS_PRESSURE, 20 },<br>
+ { -1, -1 },<br>
+ };<br>
+ double pressure;<br>
+<br>
+ /* stylus too close to the tablet on the proximity in, ignore any<br>
+ * pressure offset */<br>
+ litest_tablet_proximity_in(dev, 5, 100, axes);<br>
+ litest_drain_events(li);<br>
+ libinput_dispatch(li);<br>
+<br>
+ axes[0].value = 0;<br>
+ axes[1].value = 21;<br>
+ litest_push_event_frame(dev);<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ litest_event(dev, EV_KEY, BTN_TOUCH, 1);<br>
+ litest_pop_event_frame(dev);<br>
+ litest_drain_events(li);<br>
+<br>
+ axes[1].value = 20;<br>
+ litest_tablet_motion(dev, 70, 70, axes);<br>
+ libinput_dispatch(li);<br>
+<br>
+ litest_wait_for_event_of_type(li,<br>
+ LIBINPUT_EVENT_TABLET_TOOL_AXIS,<br>
+ -1);<br>
+ event = libinput_get_event(li);<br>
+ tev = libinput_event_get_tablet_tool_event(event);<br>
+ pressure = libinput_event_tablet_tool_get_axis_value(tev,<br>
+ LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);<br>
+ ck_assert_double_gt(pressure, 0.0);<br>
+<br>
+ libinput_event_destroy(event);<br>
+}<br>
+END_TEST<br>
+<br>
void<br>
litest_setup_tests(void)<br>
{<br>
@@ -2578,4 +2882,11 @@ litest_setup_tests(void)<br>
litest_add("tablet:calibration", tablet_calibration_has_matrix, LITEST_TABLET, LITEST_ANY);<br>
litest_add("tablet:calibration", tablet_calibration_set_matrix, LITEST_TABLET, LITEST_ANY);<br>
litest_add("tablet:calibration", tablet_calibration_set_matrix_delta, LITEST_TABLET, LITEST_ANY);<br>
+<br>
+ litest_add_for_device("tablet:pressure", tablet_pressure_offset, LITEST_WACOM_INTUOS);<br>
+ litest_add_for_device("tablet:pressure", tablet_pressure_offset_decrease, LITEST_WACOM_INTUOS);<br>
+ litest_add_for_device("tablet:pressure", tablet_pressure_offset_increase, LITEST_WACOM_INTUOS);<br>
+ litest_add_for_device("tablet:pressure", tablet_pressure_offset_exceed_threshold, LITEST_WACOM_INTUOS);<br>
+ litest_add_for_device("tablet:pressure", tablet_pressure_offset_none_for_zero_distance, LITEST_WACOM_INTUOS);<br>
+ litest_add_for_device("tablet:pressure", tablet_pressure_offset_none_for_small_distance, LITEST_WACOM_INTUOS);<br>
}<br>
--<br>
2.5.0<br>
<br>
</blockquote>