aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/evdev/evdev.c
diff options
context:
space:
mode:
authorVladimir Kondratyev <wulf@FreeBSD.org>2020-11-30 21:10:04 +0000
committerVladimir Kondratyev <wulf@FreeBSD.org>2021-01-07 23:18:44 +0000
commit3b2175fdb62c7f872e78ce732952f2ac2ff99c8d (patch)
treed6beaa0f41373d9a670024163e6c1d2ca760f442 /sys/dev/evdev/evdev.c
parent9be6b22da9b2df9903310a307f36f5297b1660b6 (diff)
Diffstat (limited to 'sys/dev/evdev/evdev.c')
-rw-r--r--sys/dev/evdev/evdev.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/sys/dev/evdev/evdev.c b/sys/dev/evdev/evdev.c
index e76abbc816d3..086ee36333dc 100644
--- a/sys/dev/evdev/evdev.c
+++ b/sys/dev/evdev/evdev.c
@@ -684,6 +684,7 @@ static void
evdev_modify_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
int32_t *value)
{
+ int32_t fuzz, old_value, abs_change;
EVDEV_LOCK_ASSERT(evdev);
@@ -710,7 +711,24 @@ evdev_modify_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
break;
case EV_ABS:
- /* TBD: implement fuzz */
+ fuzz = evdev->ev_absinfo[code].fuzz;
+ if (fuzz == 0 || code == ABS_MT_SLOT)
+ break;
+ else if (!ABS_IS_MT(code))
+ old_value = evdev->ev_absinfo[code].value;
+ else if (bit_test(evdev->ev_abs_flags, ABS_MT_SLOT))
+ old_value = evdev_get_mt_value(evdev,
+ evdev_get_last_mt_slot(evdev), code);
+ else /* Pass MT protocol type A events as is */
+ break;
+
+ abs_change = abs(*value - old_value);
+ if (abs_change < fuzz / 2)
+ *value = old_value;
+ else if (abs_change < fuzz)
+ *value = (old_value * 3 + *value) / 4;
+ else if (abs_change < fuzz * 2)
+ *value = (old_value + *value) / 2;
break;
}
}