util: add a helper to normalize an axis to [0.0, 1.0]

Like the input axis, a normalized range has min/max inclusive so we
cannot use the absinfo_range() helper which assumes the max is exclusive.

Reverts parts of 4effe6b1b9
This commit is contained in:
Peter Hutterer 2024-01-16 14:44:12 +10:00
parent f20eefbc59
commit 72eca2db56
4 changed files with 58 additions and 14 deletions

View file

@ -335,17 +335,13 @@ tablet_update_tool(struct tablet_dispatch *tablet,
static inline double
normalize_slider(const struct input_absinfo *absinfo)
{
double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo);
return value * 2 - 1;
return absinfo_normalize(absinfo) * 2 - 1;
}
static inline double
normalize_distance(const struct input_absinfo *absinfo)
{
double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo);
return value;
return absinfo_normalize(absinfo);
}
static inline double
@ -363,11 +359,10 @@ normalize_pressure(const struct input_absinfo *absinfo,
* The axis is scaled into the range [lower, max] so that the lower
* threshold is 0 pressure.
*/
int base = tool->pressure.threshold.lower;
double range = absinfo->maximum - base;
double value = (absinfo->value - base) / range;
struct input_absinfo abs = *absinfo;
abs.minimum = tool->pressure.threshold.lower;
return max(0.0, value);
return absinfo_normalize(&abs);
}
static inline double

View file

@ -72,3 +72,15 @@ absinfo_range(const struct input_absinfo *abs)
{
return (double)(abs->maximum - abs->minimum + 1);
}
static inline double
absinfo_normalize_value(const struct input_absinfo *abs, int value)
{
return min(1.0, max(0.0, (double)(value - abs->minimum)/(abs->maximum - abs->minimum)));
}
static inline double
absinfo_normalize(const struct input_absinfo *abs)
{
return absinfo_normalize_value(abs, abs->value);
}

View file

@ -3464,8 +3464,6 @@ START_TEST(airbrush_slider)
struct libinput_event_tablet_tool *tev;
const struct input_absinfo *abs;
double val;
double scale;
double expected;
int v;
if (!libevdev_has_event_code(dev->evdev,
@ -3488,8 +3486,8 @@ START_TEST(airbrush_slider)
litest_drain_events(li);
scale = absinfo_range(abs);
for (v = abs->minimum; v < abs->maximum; v += 8) {
double expected = absinfo_normalize_value(abs, v) * 2 - 1;
litest_event(dev, EV_ABS, ABS_WHEEL, v);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
@ -3499,7 +3497,6 @@ START_TEST(airbrush_slider)
ck_assert(libinput_event_tablet_tool_slider_has_changed(tev));
val = libinput_event_tablet_tool_get_slider_position(tev);
expected = ((v - abs->minimum)/scale) * 2 - 1;
ck_assert_double_eq(val, expected);
ck_assert_double_ge(val, -1.0);
ck_assert_double_le(val, 1.0);

View file

@ -35,6 +35,7 @@
#include "util-bits.h"
#include "util-ratelimit.h"
#include "util-matrix.h"
#include "util-input-event.h"
#define TEST_VERSIONSORT
#include "libinput-versionsort.h"
@ -1582,6 +1583,43 @@ START_TEST(trunkname_test)
}
END_TEST
START_TEST(absinfo_normalize_value_test)
{
struct input_absinfo abs = {
.minimum = 0,
.maximum = 100,
};
ck_assert_double_eq(absinfo_normalize_value(&abs, -100), 0.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, -1), 0.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, 0), 0.0);
ck_assert_double_gt(absinfo_normalize_value(&abs, 1), 0.0);
ck_assert_double_lt(absinfo_normalize_value(&abs, 99), 1.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, 100), 1.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, 101), 1.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, 200), 1.0);
abs.minimum = -50;
abs.maximum = 50;
ck_assert_double_eq(absinfo_normalize_value(&abs, -51), 0.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, -50), 0.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, 0), 0.5);
ck_assert_double_eq(absinfo_normalize_value(&abs, 50), 1.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, 51), 1.0);
abs.minimum = -50;
abs.maximum = 0;
ck_assert_double_eq(absinfo_normalize_value(&abs, -51), 0.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, -50), 0.0);
ck_assert_double_gt(absinfo_normalize_value(&abs, -49), 0.0);
ck_assert_double_lt(absinfo_normalize_value(&abs, -1), 1.0);
ck_assert_double_eq(absinfo_normalize_value(&abs, 0), 1.0);
}
END_TEST
static Suite *
litest_utils_suite(void)
{
@ -1635,6 +1673,8 @@ litest_utils_suite(void)
tcase_add_test(tc, trunkname_test);
tcase_add_test(tc, basename_test);
tcase_add_test(tc, absinfo_normalize_value_test);
suite_add_tcase(s, tc);
return s;