Commit d93feba1 authored by Peter Hutterer's avatar Peter Hutterer

tablet: scale the available pressure range into the pressure thresholds

Pens that don't have a pressure offset (caused by a worn-out tip) still have
basic pressure thresholds to avoid tip events when we're still a bit away from
the tablet or barely touching it. That range is currently 5% of the pressure
for tip down, 1% for tip up.

This leaves us with 95% of the range and that needs to be scaled correctly,
otherwise the bottom 5% happen before a tip event and are inaccessible where
applications don't look at pressure before tip down.

Fixes #332Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent 78efec3d
Pipeline #54644 passed with stages
in 3 minutes and 28 seconds
......@@ -354,12 +354,32 @@ static inline double
normalize_pressure(const struct input_absinfo *absinfo,
struct libinput_tablet_tool *tool)
{
int offset = tool->has_pressure_offset ?
tool->pressure_offset : absinfo->minimum;
double range = absinfo->maximum - offset;
double value = (absinfo->value - offset) / range;
int offset;
double range;
double value;
/**
* If the tool has a pressure offset, we use that as the lower bound
* for the scaling range. If not, we use the upper threshold as the
* lower bound, so once we get past that minimum physical pressure
* we have logical 0 pressure.
*
* This means that there is a small range (lower-upper) where
* different physical pressure (default: 1-5%) result in the same
* logical pressure. This is, hopefully, not noticable.
*
* Note that that lower-upper range gives us a negative pressure, so
* we have to clip to 0 for those.
*/
return value;
if (tool->has_pressure_offset)
offset = tool->pressure_offset;
else
offset = tool->pressure_threshold.upper;
range = absinfo->maximum - offset;
value = (absinfo->value - offset) / range;
return max(0.0, value);
}
static inline double
......
......@@ -3348,10 +3348,11 @@ START_TEST(tablet_pressure_distance_exclusive)
};
double pressure, distance;
litest_tablet_proximity_in(dev, 5, 100, axes);
litest_tablet_proximity_in(dev, 5, 50, axes);
litest_drain_events(li);
litest_axis_set_value(axes, ABS_PRESSURE, 2);
/* We have pressure but we're still below the tip threshold */
litest_axis_set_value(axes, ABS_PRESSURE, 1);
litest_tablet_motion(dev, 70, 70, axes);
libinput_dispatch(li);
......@@ -3361,7 +3362,22 @@ START_TEST(tablet_pressure_distance_exclusive)
pressure = libinput_event_tablet_tool_get_pressure(tev);
distance = libinput_event_tablet_tool_get_distance(tev);
ck_assert_double_ne(pressure, 0.0);
ck_assert_double_eq(pressure, 0.0);
ck_assert_double_eq(distance, 0.0);
libinput_event_destroy(event);
/* We have pressure and we're above the threshold now */
litest_axis_set_value(axes, ABS_PRESSURE, 5.5);
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_TIP);
pressure = libinput_event_tablet_tool_get_pressure(tev);
distance = libinput_event_tablet_tool_get_distance(tev);
ck_assert_double_gt(pressure, 0.0);
ck_assert_double_eq(distance, 0.0);
libinput_event_destroy(event);
......@@ -3769,8 +3785,8 @@ START_TEST(tablet_pressure_min_max)
struct libinput_event *event;
struct libinput_event_tablet_tool *tev;
struct axis_replacement axes[] = {
{ ABS_DISTANCE, 0 },
{ ABS_PRESSURE, 2 },
{ ABS_DISTANCE, 10 },
{ ABS_PRESSURE, 0 },
{ -1, -1 },
};
double p;
......@@ -3782,7 +3798,8 @@ START_TEST(tablet_pressure_min_max)
litest_drain_events(li);
libinput_dispatch(li);
litest_axis_set_value(axes, ABS_PRESSURE, 0);
litest_axis_set_value(axes, ABS_DISTANCE, 0);
litest_axis_set_value(axes, ABS_PRESSURE, 1);
litest_tablet_motion(dev, 5, 50, axes);
libinput_dispatch(li);
event = libinput_get_event(li);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment