xref: /freebsd-14.2/sys/dev/evdev/evdev_mt.c (revision 66bd52f5)
1 /*-
2  * Copyright (c) 2016 Vladimir Kondratyev <[email protected]>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #include <sys/param.h>
30 #include <sys/lock.h>
31 #include <sys/malloc.h>
32 #include <sys/mutex.h>
33 #include <sys/systm.h>
34 
35 #include <dev/evdev/evdev.h>
36 #include <dev/evdev/evdev_private.h>
37 #include <dev/evdev/input.h>
38 
39 #ifdef DEBUG
40 #define	debugf(fmt, args...)	printf("evdev: " fmt "\n", ##args)
41 #else
42 #define	debugf(fmt, args...)
43 #endif
44 
45 typedef	u_int	slotset_t;
46 
47 _Static_assert(MAX_MT_SLOTS < sizeof(slotset_t) * 8, "MAX_MT_SLOTS too big");
48 
49 #define FOREACHBIT(v, i) \
50 	for ((i) = ffs(v) - 1; (i) != -1; (i) = ffs((v) & (~1 << (i))) - 1)
51 
52 struct {
53 	uint16_t	mt;
54 	uint16_t	st;
55 	int32_t		max;
56 } static evdev_mtstmap[] = {
57 	{ ABS_MT_POSITION_X,	ABS_X,		0 },
58 	{ ABS_MT_POSITION_Y,	ABS_Y,		0 },
59 	{ ABS_MT_PRESSURE,	ABS_PRESSURE,	255 },
60 	{ ABS_MT_TOUCH_MAJOR,	ABS_TOOL_WIDTH,	15 },
61 };
62 
63 struct evdev_mt {
64 	int			last_reported_slot;
65 	uint16_t		tracking_id;
66 	int32_t			tracking_ids[MAX_MT_SLOTS];
67 	u_int			mtst_events;
68 	/* the set of slots with active touches */
69 	slotset_t		touches;
70 	/* the set of slots with unsynchronized state */
71 	slotset_t		frame;
72 	union evdev_mt_slot	slots[];
73 };
74 
75 static void	evdev_mt_send_st_compat(struct evdev_dev *);
76 static void	evdev_mt_send_autorel(struct evdev_dev *);
77 
78 static inline int
79 ffc_slot(struct evdev_dev *evdev, slotset_t slots)
80 {
81 	return (ffs(~slots & (2U << MAXIMAL_MT_SLOT(evdev)) - 1) - 1);
82 }
83 
84 void
85 evdev_mt_init(struct evdev_dev *evdev)
86 {
87 	int slot, slots;
88 
89 	slots = MAXIMAL_MT_SLOT(evdev) + 1;
90 
91 	evdev->ev_mt = malloc(offsetof(struct evdev_mt, slots) +
92 	     sizeof(union evdev_mt_slot) * slots, M_EVDEV, M_WAITOK | M_ZERO);
93 
94 	/* Initialize multitouch protocol type B states */
95 	for (slot = 0; slot < slots; slot++)
96 		evdev->ev_mt->slots[slot].id = -1;
97 
98 	if (!bit_test(evdev->ev_flags, EVDEV_FLAG_MT_KEEPID))
99 		evdev_support_abs(evdev,
100 		    ABS_MT_TRACKING_ID, -1, UINT16_MAX, 0, 0, 0);
101 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
102 		evdev_support_mt_compat(evdev);
103 }
104 
105 void
106 evdev_mt_free(struct evdev_dev *evdev)
107 {
108 	free(evdev->ev_mt, M_EVDEV);
109 }
110 
111 void
112 evdev_mt_sync_frame(struct evdev_dev *evdev)
113 {
114 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_AUTOREL))
115 		evdev_mt_send_autorel(evdev);
116 	if (evdev->ev_report_opened &&
117 	    bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
118 		evdev_mt_send_st_compat(evdev);
119 	evdev->ev_mt->frame = 0;
120 }
121 
122 static void
123 evdev_mt_send_slot(struct evdev_dev *evdev, int slot,
124     union evdev_mt_slot *state)
125 {
126 	int i;
127 	bool type_a = !bit_test(evdev->ev_abs_flags, ABS_MT_SLOT);
128 
129 	EVDEV_LOCK_ASSERT(evdev);
130 	MPASS(type_a || (slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev)));
131 	MPASS(!type_a || state != NULL);
132 
133 	if (!type_a) {
134 		evdev_send_event(evdev, EV_ABS, ABS_MT_SLOT, slot);
135 		if (state == NULL) {
136 			evdev_send_event(evdev, EV_ABS, ABS_MT_TRACKING_ID, -1);
137 			return;
138 		}
139 	}
140 	bit_foreach_at(evdev->ev_abs_flags, ABS_MT_FIRST, ABS_MT_LAST + 1, i)
141 		evdev_send_event(evdev, EV_ABS, i,
142 		    state->val[ABS_MT_INDEX(i)]);
143 	if (type_a)
144 		evdev_send_event(evdev, EV_SYN, SYN_MT_REPORT, 1);
145 }
146 
147 int
148 evdev_mt_push_slot(struct evdev_dev *evdev, int slot,
149     union evdev_mt_slot *state)
150 {
151 	bool type_a = !bit_test(evdev->ev_abs_flags, ABS_MT_SLOT);
152 
153 	if (type_a && state == NULL)
154 		return (EINVAL);
155 	if (!type_a && (slot < 0 || slot > MAXIMAL_MT_SLOT(evdev)))
156 		return (EINVAL);
157 
158 	EVDEV_ENTER(evdev);
159 	evdev_mt_send_slot(evdev, slot, state);
160 	EVDEV_EXIT(evdev);
161 
162 	return (0);
163 }
164 
165 int
166 evdev_mt_get_last_slot(struct evdev_dev *evdev)
167 {
168 	return (evdev->ev_mt->last_reported_slot);
169 }
170 
171 void
172 evdev_mt_set_last_slot(struct evdev_dev *evdev, int slot)
173 {
174 	struct evdev_mt *mt = evdev->ev_mt;
175 
176 	MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev));
177 
178 	mt->frame |= 1U << slot;
179 	mt->last_reported_slot = slot;
180 }
181 
182 int32_t
183 evdev_mt_get_value(struct evdev_dev *evdev, int slot, int16_t code)
184 {
185 	struct evdev_mt *mt = evdev->ev_mt;
186 
187 	MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev));
188 
189 	return (mt->slots[slot].val[ABS_MT_INDEX(code)]);
190 }
191 
192 void
193 evdev_mt_set_value(struct evdev_dev *evdev, int slot, int16_t code,
194     int32_t value)
195 {
196 	struct evdev_mt *mt = evdev->ev_mt;
197 
198 	MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev));
199 
200 	if (code == ABS_MT_TRACKING_ID) {
201 		if (value != -1)
202 			mt->touches |= 1U << slot;
203 		else
204 			mt->touches &= ~(1U << slot);
205 	}
206 	mt->slots[slot].val[ABS_MT_INDEX(code)] = value;
207 }
208 
209 int
210 evdev_get_mt_slot_by_tracking_id(struct evdev_dev *evdev, int32_t tracking_id)
211 {
212 	struct evdev_mt *mt = evdev->ev_mt;
213 	int slot;
214 
215 	FOREACHBIT(mt->touches, slot)
216 		if (mt->tracking_ids[slot] == tracking_id)
217 			return (slot);
218 	/*
219 	 * Do not allow allocation of new slot in a place of just
220 	 * released one within the same report.
221 	 */
222 	return (ffc_slot(evdev, mt->touches | mt->frame));
223 }
224 
225 int32_t
226 evdev_mt_reassign_id(struct evdev_dev *evdev, int slot, int32_t id)
227 {
228 	struct evdev_mt *mt = evdev->ev_mt;
229 	int32_t nid;
230 
231 	if (id == -1 || bit_test(evdev->ev_flags, EVDEV_FLAG_MT_KEEPID)) {
232 		mt->tracking_ids[slot] = id;
233 		return (id);
234 	}
235 
236 	nid = evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID);
237 	if (nid != -1) {
238 		KASSERT(id == mt->tracking_ids[slot],
239 		    ("MT-slot tracking id has changed"));
240 		return (nid);
241 	}
242 
243 	mt->tracking_ids[slot] = id;
244 again:
245 	nid = mt->tracking_id++;
246 	FOREACHBIT(mt->touches, slot)
247 		if (evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID) == nid)
248 			goto again;
249 
250 	return (nid);
251 }
252 
253 static inline int32_t
254 evdev_mt_normalize(int32_t value, int32_t mtmin, int32_t mtmax, int32_t stmax)
255 {
256 	if (stmax != 0 && mtmax != mtmin) {
257 		value = (value - mtmin) * stmax / (mtmax - mtmin);
258 		value = MAX(MIN(value, stmax), 0);
259 	}
260 	return (value);
261 }
262 
263 void
264 evdev_support_mt_compat(struct evdev_dev *evdev)
265 {
266 	struct input_absinfo *ai;
267 	int i;
268 
269 	if (evdev->ev_absinfo == NULL)
270 		return;
271 
272 	evdev_support_event(evdev, EV_KEY);
273 	evdev_support_key(evdev, BTN_TOUCH);
274 
275 	/* Touchscreens should not advertise tap tool capabilities */
276 	if (!bit_test(evdev->ev_prop_flags, INPUT_PROP_DIRECT))
277 		evdev_support_nfingers(evdev, MAXIMAL_MT_SLOT(evdev) + 1);
278 
279 	/* Echo 0-th MT-slot as ST-slot */
280 	for (i = 0; i < nitems(evdev_mtstmap); i++) {
281 		if (!bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].mt) ||
282 		     bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].st))
283 			continue;
284 		ai = evdev->ev_absinfo + evdev_mtstmap[i].mt;
285 		evdev->ev_mt->mtst_events |= 1U << i;
286 		if (evdev_mtstmap[i].max != 0)
287 			evdev_support_abs(evdev, evdev_mtstmap[i].st,
288 			    0,
289 			    evdev_mtstmap[i].max,
290 			    0,
291 			    evdev_mt_normalize(
292 			      ai->flat, 0, ai->maximum, evdev_mtstmap[i].max),
293 			    0);
294 		else
295 			evdev_support_abs(evdev, evdev_mtstmap[i].st,
296 			    ai->minimum,
297 			    ai->maximum,
298 			    0,
299 			    ai->flat,
300 			    ai->resolution);
301 	}
302 }
303 
304 static void
305 evdev_mt_send_st_compat(struct evdev_dev *evdev)
306 {
307 	struct evdev_mt *mt = evdev->ev_mt;
308 	int nfingers, i, st_slot;
309 
310 	EVDEV_LOCK_ASSERT(evdev);
311 
312 	nfingers = bitcount(mt->touches);
313 	evdev_send_event(evdev, EV_KEY, BTN_TOUCH, nfingers > 0);
314 
315 	/* Send first active MT-slot state as single touch report */
316 	st_slot = ffs(mt->touches) - 1;
317 	if (st_slot != -1)
318 		FOREACHBIT(mt->mtst_events, i)
319 			evdev_send_event(evdev, EV_ABS, evdev_mtstmap[i].st,
320 			    evdev_mt_normalize(evdev_mt_get_value(evdev,
321 			      st_slot, evdev_mtstmap[i].mt),
322 			      evdev->ev_absinfo[evdev_mtstmap[i].mt].minimum,
323 			      evdev->ev_absinfo[evdev_mtstmap[i].mt].maximum,
324 			      evdev_mtstmap[i].max));
325 
326 	/* Touchscreens should not report tool taps */
327 	if (!bit_test(evdev->ev_prop_flags, INPUT_PROP_DIRECT))
328 		evdev_send_nfingers(evdev, nfingers);
329 
330 	if (nfingers == 0)
331 		evdev_send_event(evdev, EV_ABS, ABS_PRESSURE, 0);
332 }
333 
334 void
335 evdev_push_mt_compat(struct evdev_dev *evdev)
336 {
337 
338 	EVDEV_ENTER(evdev);
339 	evdev_mt_send_st_compat(evdev);
340 	EVDEV_EXIT(evdev);
341 }
342 
343 static void
344 evdev_mt_send_autorel(struct evdev_dev *evdev)
345 {
346 	struct evdev_mt *mt = evdev->ev_mt;
347 	int slot;
348 
349 	EVDEV_LOCK_ASSERT(evdev);
350 
351 	FOREACHBIT(mt->touches & ~mt->frame, slot)
352 		evdev_mt_send_slot(evdev, slot, NULL);
353 }
354 
355 void
356 evdev_mt_push_autorel(struct evdev_dev *evdev)
357 {
358 	EVDEV_ENTER(evdev);
359 	evdev_mt_send_autorel(evdev);
360 	EVDEV_EXIT(evdev);
361 }
362