git: 127e54deb6d8 - main - evdev: Normalize width and pressure of single touch compat events
Vladimir Kondratyev
wulf at FreeBSD.org
Tue Aug 24 23:04:17 UTC 2021
The branch main has been updated by wulf:
URL: https://cgit.FreeBSD.org/src/commit/?id=127e54deb6d8899e1dc1bc6251d512e19f21b0f1
commit 127e54deb6d8899e1dc1bc6251d512e19f21b0f1
Author: Vladimir Kondratyev <wulf at FreeBSD.org>
AuthorDate: 2021-08-24 22:46:49 +0000
Commit: Vladimir Kondratyev <wulf at FreeBSD.org>
CommitDate: 2021-08-24 22:46:49 +0000
evdev: Normalize width and pressure of single touch compat events
to match Synaptics touchpad reporting range.
MFC after: 2 weeks
---
sys/dev/evdev/evdev_mt.c | 67 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 49 insertions(+), 18 deletions(-)
diff --git a/sys/dev/evdev/evdev_mt.c b/sys/dev/evdev/evdev_mt.c
index 0b5d2cb6bb85..a3600e837960 100644
--- a/sys/dev/evdev/evdev_mt.c
+++ b/sys/dev/evdev/evdev_mt.c
@@ -49,11 +49,15 @@ _Static_assert(MAX_MT_SLOTS < sizeof(slotset_t) * 8, "MAX_MT_SLOTS too big");
#define FOREACHBIT(v, i) \
for ((i) = ffs(v) - 1; (i) != -1; (i) = ffs((v) & (~1 << (i))) - 1)
-static uint16_t evdev_mtstmap[][2] = {
- { ABS_MT_POSITION_X, ABS_X },
- { ABS_MT_POSITION_Y, ABS_Y },
- { ABS_MT_PRESSURE, ABS_PRESSURE },
- { ABS_MT_TOUCH_MAJOR, ABS_TOOL_WIDTH },
+struct {
+ uint16_t mt;
+ uint16_t st;
+ int32_t max;
+} static evdev_mtstmap[] = {
+ { ABS_MT_POSITION_X, ABS_X, 0 },
+ { ABS_MT_POSITION_Y, ABS_Y, 0 },
+ { ABS_MT_PRESSURE, ABS_PRESSURE, 255 },
+ { ABS_MT_TOUCH_MAJOR, ABS_TOOL_WIDTH, 15 },
};
struct evdev_mt_slot {
@@ -62,6 +66,7 @@ struct evdev_mt_slot {
struct evdev_mt {
int last_reported_slot;
+ u_int mtst_events;
/* the set of slots with active touches */
slotset_t touches;
/* the set of slots with unsynchronized state */
@@ -175,9 +180,20 @@ evdev_get_mt_slot_by_tracking_id(struct evdev_dev *evdev, int32_t tracking_id)
return (ffc_slot(evdev, mt->touches | mt->frame));
}
+static inline int32_t
+evdev_mt_normalize(int32_t value, int32_t mtmin, int32_t mtmax, int32_t stmax)
+{
+ if (stmax != 0 && mtmax != mtmin) {
+ value = (value - mtmin) * stmax / (mtmax - mtmin);
+ value = MAX(MIN(value, stmax), 0);
+ }
+ return (value);
+}
+
void
evdev_support_mt_compat(struct evdev_dev *evdev)
{
+ struct input_absinfo *ai;
int i;
if (evdev->ev_absinfo == NULL)
@@ -191,14 +207,28 @@ evdev_support_mt_compat(struct evdev_dev *evdev)
evdev_support_nfingers(evdev, MAXIMAL_MT_SLOT(evdev) + 1);
/* Echo 0-th MT-slot as ST-slot */
- for (i = 0; i < nitems(evdev_mtstmap); i++)
- if (bit_test(evdev->ev_abs_flags, evdev_mtstmap[i][0]))
- evdev_support_abs(evdev, evdev_mtstmap[i][1],
- evdev->ev_absinfo[evdev_mtstmap[i][0]].minimum,
- evdev->ev_absinfo[evdev_mtstmap[i][0]].maximum,
+ for (i = 0; i < nitems(evdev_mtstmap); i++) {
+ if (!bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].mt) ||
+ bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].st))
+ continue;
+ ai = evdev->ev_absinfo + evdev_mtstmap[i].mt;
+ evdev->ev_mt->mtst_events |= 1U << i;
+ if (evdev_mtstmap[i].max != 0)
+ evdev_support_abs(evdev, evdev_mtstmap[i].st,
0,
- evdev->ev_absinfo[evdev_mtstmap[i][0]].flat,
- evdev->ev_absinfo[evdev_mtstmap[i][0]].resolution);
+ evdev_mtstmap[i].max,
+ 0,
+ evdev_mt_normalize(
+ ai->flat, 0, ai->maximum, evdev_mtstmap[i].max),
+ 0);
+ else
+ evdev_support_abs(evdev, evdev_mtstmap[i].st,
+ ai->minimum,
+ ai->maximum,
+ 0,
+ ai->flat,
+ ai->resolution);
+ }
}
static void
@@ -215,12 +245,13 @@ evdev_mt_send_st_compat(struct evdev_dev *evdev)
/* Send first active MT-slot state as single touch report */
st_slot = ffs(mt->touches) - 1;
if (st_slot != -1)
- for (i = 0; i < nitems(evdev_mtstmap); i++)
- if (bit_test(evdev->ev_abs_flags, evdev_mtstmap[i][1]))
- evdev_send_event(evdev, EV_ABS,
- evdev_mtstmap[i][1],
- evdev_mt_get_value(evdev, st_slot,
- evdev_mtstmap[i][0]));
+ FOREACHBIT(mt->mtst_events, i)
+ evdev_send_event(evdev, EV_ABS, evdev_mtstmap[i].st,
+ evdev_mt_normalize(evdev_mt_get_value(evdev,
+ st_slot, evdev_mtstmap[i].mt),
+ evdev->ev_absinfo[evdev_mtstmap[i].mt].minimum,
+ evdev->ev_absinfo[evdev_mtstmap[i].mt].maximum,
+ evdev_mtstmap[i].max));
/* Touchscreens should not report tool taps */
if (!bit_test(evdev->ev_prop_flags, INPUT_PROP_DIRECT))
More information about the dev-commits-src-all
mailing list