diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index 18c8fbee..943b5284 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -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; - return 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. + */ + + 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 diff --git a/test/test-tablet.c b/test/test-tablet.c index d05e7480..90b81a7f 100644 --- a/test/test-tablet.c +++ b/test/test-tablet.c @@ -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);