xref: /freebsd-13-stable/sys/dev/evdev/evdev_mt.c (revision f8167e0404dab9ffeaca95853dd237ab7c587f82)
1 /*-
2  * Copyright (c) 2016, 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
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 /*-
27  * Copyright (c) 2015, 2016 Ulf Brosziewski
28  *
29  * Permission to use, copy, modify, and distribute this software for any
30  * purpose with or without fee is hereby granted, provided that the above
31  * copyright notice and this permission notice appear in all copies.
32  *
33  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
34  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
35  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
36  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
37  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
38  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
39  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40  */
41 
42 #include <sys/param.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mutex.h>
46 #include <sys/systm.h>
47 
48 #include <dev/evdev/evdev.h>
49 #include <dev/evdev/evdev_private.h>
50 #include <dev/evdev/input.h>
51 
52 #ifdef DEBUG
53 #define	debugf(fmt, args...)	printf("evdev: " fmt "\n", ##args)
54 #else
55 #define	debugf(fmt, args...)
56 #endif
57 
58 typedef	u_int	slotset_t;
59 
60 _Static_assert(MAX_MT_SLOTS < sizeof(slotset_t) * 8, "MAX_MT_SLOTS too big");
61 
62 #define FOREACHBIT(v, i) \
63 	for ((i) = ffs(v) - 1; (i) != -1; (i) = ffs((v) & (~1 << (i))) - 1)
64 
65 struct {
66 	uint16_t	mt;
67 	uint16_t	st;
68 	int32_t		max;
69 } static evdev_mtstmap[] = {
70 	{ ABS_MT_POSITION_X,	ABS_X,		0 },
71 	{ ABS_MT_POSITION_Y,	ABS_Y,		0 },
72 	{ ABS_MT_PRESSURE,	ABS_PRESSURE,	255 },
73 	{ ABS_MT_TOUCH_MAJOR,	ABS_TOOL_WIDTH,	15 },
74 };
75 
76 struct evdev_mt {
77 	int			last_reported_slot;
78 	uint16_t		tracking_id;
79 	int32_t			tracking_ids[MAX_MT_SLOTS];
80 	bool			type_a;
81 	u_int			mtst_events;
82 	/* the set of slots with active touches */
83 	slotset_t		touches;
84 	/* the set of slots with unsynchronized state */
85 	slotset_t		frame;
86 	/* the set of slots to match with active touches */
87 	slotset_t		match_frame;
88 	int			match_slot;
89 	union evdev_mt_slot	*match_slots;
90 	int			*matrix;
91 	union evdev_mt_slot	slots[];
92 };
93 
94 static void	evdev_mt_send_st_compat(struct evdev_dev *);
95 static void	evdev_mt_send_autorel(struct evdev_dev *);
96 static void	evdev_mt_replay_events(struct evdev_dev *);
97 
98 static inline int
ffc_slot(struct evdev_dev * evdev,slotset_t slots)99 ffc_slot(struct evdev_dev *evdev, slotset_t slots)
100 {
101 	return (ffs(~slots & ((2U << MAXIMAL_MT_SLOT(evdev)) - 1)) - 1);
102 }
103 
104 void
evdev_mt_init(struct evdev_dev * evdev)105 evdev_mt_init(struct evdev_dev *evdev)
106 {
107 	struct evdev_mt *mt;
108 	size_t size = offsetof(struct evdev_mt, slots);
109 	int slot, slots;
110 	bool type_a;
111 
112 	type_a = !bit_test(evdev->ev_abs_flags, ABS_MT_SLOT);
113 	if (type_a) {
114 		/* Add events produced by MT type A to type B converter */
115 		evdev_support_abs(evdev,
116 		    ABS_MT_SLOT, 0, MAX_MT_SLOTS - 1, 0, 0, 0);
117 		evdev_support_abs(evdev,
118 		    ABS_MT_TRACKING_ID, -1, MAX_MT_SLOTS - 1, 0, 0, 0);
119 	}
120 
121 	slots = MAXIMAL_MT_SLOT(evdev) + 1;
122 	size += sizeof(mt->slots[0]) * slots;
123 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_TRACK)) {
124 		size += sizeof(mt->match_slots[0]) * slots;
125 		size += sizeof(mt->matrix[0]) * (slots + 6) * slots;
126 	}
127 
128 	mt = malloc(size, M_EVDEV, M_WAITOK | M_ZERO);
129 	evdev->ev_mt = mt;
130 	mt->type_a = type_a;
131 
132 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_TRACK)) {
133 		mt->match_slots = mt->slots + slots;
134 		mt->matrix = (int *)(mt->match_slots + slots);
135 	}
136 
137 	/* Initialize multitouch protocol type B states */
138 	for (slot = 0; slot < slots; slot++)
139 		mt->slots[slot].id = -1;
140 
141 	if (!bit_test(evdev->ev_flags, EVDEV_FLAG_MT_KEEPID))
142 		evdev_support_abs(evdev,
143 		    ABS_MT_TRACKING_ID, -1, UINT16_MAX, 0, 0, 0);
144 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
145 		evdev_support_mt_compat(evdev);
146 }
147 
148 void
evdev_mt_free(struct evdev_dev * evdev)149 evdev_mt_free(struct evdev_dev *evdev)
150 {
151 	free(evdev->ev_mt, M_EVDEV);
152 }
153 
154 void
evdev_mt_sync_frame(struct evdev_dev * evdev)155 evdev_mt_sync_frame(struct evdev_dev *evdev)
156 {
157 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_TRACK))
158 		evdev_mt_replay_events(evdev);
159 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_AUTOREL))
160 		evdev_mt_send_autorel(evdev);
161 	if (evdev->ev_report_opened &&
162 	    bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
163 		evdev_mt_send_st_compat(evdev);
164 	evdev->ev_mt->frame = 0;
165 }
166 
167 static void
evdev_mt_send_slot(struct evdev_dev * evdev,int slot,union evdev_mt_slot * state)168 evdev_mt_send_slot(struct evdev_dev *evdev, int slot,
169     union evdev_mt_slot *state)
170 {
171 	int i;
172 	bool type_a = !bit_test(evdev->ev_abs_flags, ABS_MT_SLOT);
173 
174 	EVDEV_LOCK_ASSERT(evdev);
175 	MPASS(type_a || (slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev)));
176 	MPASS(!type_a || state != NULL);
177 
178 	if (!type_a) {
179 		evdev_send_event(evdev, EV_ABS, ABS_MT_SLOT, slot);
180 		if (state == NULL) {
181 			evdev_send_event(evdev, EV_ABS, ABS_MT_TRACKING_ID, -1);
182 			return;
183 		}
184 	}
185 	bit_foreach_at(evdev->ev_abs_flags, ABS_MT_FIRST, ABS_MT_LAST + 1, i)
186 		evdev_send_event(evdev, EV_ABS, i,
187 		    state->val[ABS_MT_INDEX(i)]);
188 	if (type_a)
189 		evdev_send_event(evdev, EV_SYN, SYN_MT_REPORT, 1);
190 }
191 
192 int
evdev_mt_push_slot(struct evdev_dev * evdev,int slot,union evdev_mt_slot * state)193 evdev_mt_push_slot(struct evdev_dev *evdev, int slot,
194     union evdev_mt_slot *state)
195 {
196 	struct evdev_mt *mt = evdev->ev_mt;
197 	bool type_a = !bit_test(evdev->ev_abs_flags, ABS_MT_SLOT);
198 
199 	if ((type_a || (mt != NULL && mt->type_a)) && state == NULL)
200 		return (EINVAL);
201 	if (!type_a && (slot < 0 || slot > MAXIMAL_MT_SLOT(evdev)))
202 		return (EINVAL);
203 
204 	EVDEV_ENTER(evdev);
205 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_TRACK) && mt->type_a) {
206 		mt->match_slots[mt->match_slot] = *state;
207 		evdev_mt_record_event(evdev, EV_SYN, SYN_MT_REPORT, 1);
208 	} else if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_TRACK)) {
209 		evdev_mt_record_event(evdev, EV_ABS, ABS_MT_SLOT, slot);
210 		if (state != NULL)
211 			mt->match_slots[mt->match_slot] = *state;
212 		else
213 			evdev_mt_record_event(evdev, EV_ABS,
214 			    ABS_MT_TRACKING_ID, -1);
215 	} else
216 		evdev_mt_send_slot(evdev, slot, state);
217 	EVDEV_EXIT(evdev);
218 
219 	return (0);
220 }
221 
222 /*
223  * Find a minimum-weight matching for an m-by-n matrix.
224  *
225  * m must be greater than or equal to n. The size of the buffer must be
226  * at least 3m + 3n.
227  *
228  * On return, the first m elements of the buffer contain the row-to-
229  * column mappings, i.e., buffer[i] is the column index for row i, or -1
230  * if there is no assignment for that row (which may happen if n < m).
231  *
232  * Wrong results because of overflows will not occur with input values
233  * in the range of 0 to INT_MAX / 2 inclusive.
234  *
235  * The function applies the Dinic-Kronrod algorithm. It is not modern or
236  * popular, but it seems to be a good choice for small matrices at least.
237  * The original form of the algorithm is modified as follows: There is no
238  * initial search for row minima, the initial assignments are in a
239  * "virtual" column with the index -1 and zero values. This permits inputs
240  * with n < m, and it simplifies the reassignments.
241  */
242 static void
evdev_mt_matching(int * matrix,int m,int n,int * buffer)243 evdev_mt_matching(int *matrix, int m, int n, int *buffer)
244 {
245 	int i, j, k, d, e, row, col, delta;
246 	int *p;
247 	int *r2c = buffer;	/* row-to-column assignments */
248 	int *red = r2c + m;	/* reduced values of the assignments */
249 	int *mc = red + m;	/* row-wise minimal elements of cs */
250 	int *cs = mc + m;	/* the column set */
251 	int *c2r = cs + n;	/* column-to-row assignments in cs */
252 	int *cd = c2r + n;	/* column deltas (reduction) */
253 
254 	for (p = r2c; p < red; *p++ = -1) {}
255 	for (; p < mc; *p++ = 0) {}
256 	for (col = 0; col < n; col++) {
257 		delta = INT_MAX;
258 		for (i = 0, p = matrix + col; i < m; i++, p += n) {
259 			d = *p - red[i];
260 			if (d < delta || (d == delta && r2c[i] < 0)) {
261 				delta = d;
262 				row = i;
263 			}
264 		}
265 		cd[col] = delta;
266 		if (r2c[row] < 0) {
267 			r2c[row] = col;
268 			continue;
269 		}
270 		for (p = mc; p < cs; *p++ = col) {}
271 		for (k = 0; (j = r2c[row]) >= 0;) {
272 			cs[k++] = j;
273 			c2r[j] = row;
274 			mc[row] -= n;
275 			delta = INT_MAX;
276 			for (i = 0, p = matrix; i < m; i++, p += n)
277 				if (mc[i] >= 0) {
278 					d = p[mc[i]] - cd[mc[i]];
279 					e = p[j] - cd[j];
280 					if (e < d) {
281 						d = e;
282 						mc[i] = j;
283 					}
284 					d -= red[i];
285 					if (d < delta || (d == delta
286 					    && r2c[i] < 0)) {
287 						delta = d;
288 						row = i;
289 					}
290 				}
291 			cd[col] += delta;
292 			for (i = 0; i < k; i++) {
293 				cd[cs[i]] += delta;
294 				red[c2r[cs[i]]] -= delta;
295 			}
296 		}
297 		for (j = mc[row]; (r2c[row] = j) != col;) {
298 			row = c2r[j];
299 			j = mc[row] + n;
300 		}
301 	}
302 }
303 
304 /*
305  * Assign tracking IDs to the points in the pt array.  The tracking ID
306  * assignment pairs the points with points of the previous frame in
307  * such a way that the sum of the squared distances is minimal.  Using
308  * squares instead of simple distances favours assignments with more uniform
309  * distances, and it is faster.
310  * Set tracking id to -1 for unassigned (new) points.
311  */
312 void
evdev_mt_match_frame(struct evdev_dev * evdev,union evdev_mt_slot * pt,int size)313 evdev_mt_match_frame(struct evdev_dev *evdev, union evdev_mt_slot *pt,
314     int size)
315 {
316 	struct evdev_mt *mt = evdev->ev_mt;
317 	int i, j, m, n, dx, dy, slot, num_touches;
318 	int *p, *r2c, *c2r;
319 
320 	EVDEV_LOCK_ASSERT(evdev);
321 	MPASS(mt->matrix != NULL);
322 	MPASS(size >= 0 && size <= MAXIMAL_MT_SLOT(evdev) + 1);
323 
324 	if (size == 0)
325 		return;
326 
327 	p = mt->matrix;
328 	num_touches = bitcount(mt->touches);
329 	if (num_touches >= size) {
330 		FOREACHBIT(mt->touches, slot)
331 			for (i = 0; i < size; i++) {
332 				dx = pt[i].x - mt->slots[slot].x;
333 				dy = pt[i].y - mt->slots[slot].y;
334 				*p++ = dx * dx + dy * dy;
335 			}
336 		m = num_touches;
337 		n = size;
338 	} else {
339 		for (i = 0; i < size; i++)
340 			FOREACHBIT(mt->touches, slot) {
341 				dx = pt[i].x - mt->slots[slot].x;
342 				dy = pt[i].y - mt->slots[slot].y;
343 				*p++ = dx * dx + dy * dy;
344 			}
345 		m = size;
346 		n = num_touches;
347 	}
348 	evdev_mt_matching(mt->matrix, m, n, p);
349 
350 	r2c = p;
351 	c2r = p + m;
352 	for (i = 0; i < m; i++)
353 		if ((j = r2c[i]) >= 0)
354 			c2r[j] = i;
355 
356 	p = (n == size ? c2r : r2c);
357 	for (i = 0; i < size; i++)
358 		if (*p++ < 0)
359 			pt[i].id = -1;
360 
361 	p = (n == size ? r2c : c2r);
362 	FOREACHBIT(mt->touches, slot)
363 		if ((i = *p++) >= 0)
364 			pt[i].id = mt->tracking_ids[slot];
365 }
366 
367 static void
evdev_mt_send_frame(struct evdev_dev * evdev,union evdev_mt_slot * pt,int size)368 evdev_mt_send_frame(struct evdev_dev *evdev, union evdev_mt_slot *pt, int size)
369 {
370 	struct evdev_mt *mt = evdev->ev_mt;
371 	union evdev_mt_slot *slot;
372 
373 	EVDEV_LOCK_ASSERT(evdev);
374 	MPASS(size >= 0 && size <= MAXIMAL_MT_SLOT(evdev) + 1);
375 
376 	/*
377 	 * While MT-matching assign tracking IDs of new contacts to be equal
378 	 * to a slot number to make things simpler.
379 	 */
380 	for (slot = pt; slot < pt + size; slot++) {
381 		if (slot->id < 0)
382 			slot->id = ffc_slot(evdev, mt->touches | mt->frame);
383 		if (slot->id >= 0)
384 			evdev_mt_send_slot(evdev, slot->id, slot);
385 	}
386 }
387 
388 int
evdev_mt_push_frame(struct evdev_dev * evdev,union evdev_mt_slot * pt,int size)389 evdev_mt_push_frame(struct evdev_dev *evdev, union evdev_mt_slot *pt, int size)
390 {
391 	if (size < 0 || size > MAXIMAL_MT_SLOT(evdev) + 1)
392 		return (EINVAL);
393 
394 	EVDEV_ENTER(evdev);
395 	evdev_mt_send_frame(evdev, pt, size);
396 	EVDEV_EXIT(evdev);
397 
398 	return (0);
399 }
400 
401 bool
evdev_mt_record_event(struct evdev_dev * evdev,uint16_t type,uint16_t code,int32_t value)402 evdev_mt_record_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
403     int32_t value)
404 {
405 	struct evdev_mt *mt = evdev->ev_mt;
406 
407 	EVDEV_LOCK_ASSERT(evdev);
408 
409 	switch (type) {
410 	case EV_SYN:
411 		if (code == SYN_MT_REPORT) {
412 			/* MT protocol type A support */
413 			KASSERT(mt->type_a, ("Not a MT type A protocol"));
414 			mt->match_frame |= 1U << mt->match_slot;
415 			mt->match_slot++;
416 			return (true);
417 		}
418 		break;
419 	case EV_ABS:
420 		if (code == ABS_MT_SLOT) {
421 			/* MT protocol type B support */
422 			KASSERT(!mt->type_a, ("Not a MT type B protocol"));
423 			KASSERT(value >= 0, ("Negative slot number"));
424 			mt->match_slot = value;
425 			mt->match_frame |= 1U << mt->match_slot;
426 			return (true);
427 		} else if (code == ABS_MT_TRACKING_ID) {
428 			KASSERT(!mt->type_a, ("Not a MT type B protocol"));
429 			if (value == -1)
430 				mt->match_frame &= ~(1U << mt->match_slot);
431 			return (true);
432 		} else if (ABS_IS_MT(code)) {
433 			KASSERT(mt->match_slot >= 0, ("Negative slot"));
434 			KASSERT(mt->match_slot <= MAXIMAL_MT_SLOT(evdev),
435 			    ("Slot number too big"));
436 			mt->match_slots[mt->match_slot].
437 			    val[ABS_MT_INDEX(code)] = value;
438 			return (true);
439 		}
440 		break;
441 	default:
442 		break;
443 	}
444 
445 	return (false);
446 }
447 
448 static void
evdev_mt_replay_events(struct evdev_dev * evdev)449 evdev_mt_replay_events(struct evdev_dev *evdev)
450 {
451 	struct evdev_mt *mt = evdev->ev_mt;
452 	int slot, size = 0;
453 
454 	EVDEV_LOCK_ASSERT(evdev);
455 
456 	FOREACHBIT(mt->match_frame, slot) {
457 		if (slot != size)
458 			mt->match_slots[size] = mt->match_slots[slot];
459 		size++;
460 	}
461 	evdev_mt_match_frame(evdev, mt->match_slots, size);
462 	evdev_mt_send_frame(evdev, mt->match_slots, size);
463 	mt->match_slot = 0;
464 	mt->match_frame = 0;
465 }
466 
467 union evdev_mt_slot *
evdev_mt_get_match_slots(struct evdev_dev * evdev)468 evdev_mt_get_match_slots(struct evdev_dev *evdev)
469 {
470 	return (evdev->ev_mt->match_slots);
471 }
472 
473 int
evdev_mt_get_last_slot(struct evdev_dev * evdev)474 evdev_mt_get_last_slot(struct evdev_dev *evdev)
475 {
476 	return (evdev->ev_mt->last_reported_slot);
477 }
478 
479 void
evdev_mt_set_last_slot(struct evdev_dev * evdev,int slot)480 evdev_mt_set_last_slot(struct evdev_dev *evdev, int slot)
481 {
482 	struct evdev_mt *mt = evdev->ev_mt;
483 
484 	MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev));
485 
486 	mt->frame |= 1U << slot;
487 	mt->last_reported_slot = slot;
488 }
489 
490 int32_t
evdev_mt_get_value(struct evdev_dev * evdev,int slot,int16_t code)491 evdev_mt_get_value(struct evdev_dev *evdev, int slot, int16_t code)
492 {
493 	struct evdev_mt *mt = evdev->ev_mt;
494 
495 	MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev));
496 
497 	return (mt->slots[slot].val[ABS_MT_INDEX(code)]);
498 }
499 
500 void
evdev_mt_set_value(struct evdev_dev * evdev,int slot,int16_t code,int32_t value)501 evdev_mt_set_value(struct evdev_dev *evdev, int slot, int16_t code,
502     int32_t value)
503 {
504 	struct evdev_mt *mt = evdev->ev_mt;
505 
506 	MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev));
507 
508 	if (code == ABS_MT_TRACKING_ID) {
509 		if (value != -1)
510 			mt->touches |= 1U << slot;
511 		else
512 			mt->touches &= ~(1U << slot);
513 	}
514 	mt->slots[slot].val[ABS_MT_INDEX(code)] = value;
515 }
516 
517 int
evdev_get_mt_slot_by_tracking_id(struct evdev_dev * evdev,int32_t tracking_id)518 evdev_get_mt_slot_by_tracking_id(struct evdev_dev *evdev, int32_t tracking_id)
519 {
520 	struct evdev_mt *mt = evdev->ev_mt;
521 	int slot;
522 
523 	KASSERT(!mt->type_a, ("Not a MT type B protocol"));
524 
525 	/*
526 	 * Ignore tracking_id if slot assignment is performed by evdev.
527 	 * Events are written sequentially to temporary matching buffer.
528 	 */
529 	if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_TRACK))
530 		return (ffc_slot(evdev, mt->match_frame));
531 
532 	FOREACHBIT(mt->touches, slot)
533 		if (mt->tracking_ids[slot] == tracking_id)
534 			return (slot);
535 	/*
536 	 * Do not allow allocation of new slot in a place of just
537 	 * released one within the same report.
538 	 */
539 	return (ffc_slot(evdev, mt->touches | mt->frame));
540 }
541 
542 int32_t
evdev_mt_reassign_id(struct evdev_dev * evdev,int slot,int32_t id)543 evdev_mt_reassign_id(struct evdev_dev *evdev, int slot, int32_t id)
544 {
545 	struct evdev_mt *mt = evdev->ev_mt;
546 	int32_t nid;
547 
548 	if (id == -1 || bit_test(evdev->ev_flags, EVDEV_FLAG_MT_KEEPID)) {
549 		mt->tracking_ids[slot] = id;
550 		return (id);
551 	}
552 
553 	nid = evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID);
554 	if (nid != -1) {
555 		KASSERT(id == mt->tracking_ids[slot],
556 		    ("MT-slot tracking id has changed"));
557 		return (nid);
558 	}
559 
560 	mt->tracking_ids[slot] = id;
561 again:
562 	nid = mt->tracking_id++;
563 	FOREACHBIT(mt->touches, slot)
564 		if (evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID) == nid)
565 			goto again;
566 
567 	return (nid);
568 }
569 
570 static inline int32_t
evdev_mt_normalize(int32_t value,int32_t mtmin,int32_t mtmax,int32_t stmax)571 evdev_mt_normalize(int32_t value, int32_t mtmin, int32_t mtmax, int32_t stmax)
572 {
573 	if (stmax != 0 && mtmax != mtmin) {
574 		value = (value - mtmin) * stmax / (mtmax - mtmin);
575 		value = MAX(MIN(value, stmax), 0);
576 	}
577 	return (value);
578 }
579 
580 void
evdev_support_mt_compat(struct evdev_dev * evdev)581 evdev_support_mt_compat(struct evdev_dev *evdev)
582 {
583 	struct input_absinfo *ai;
584 	int i;
585 
586 	if (evdev->ev_absinfo == NULL)
587 		return;
588 
589 	evdev_support_event(evdev, EV_KEY);
590 	evdev_support_key(evdev, BTN_TOUCH);
591 
592 	/* Touchscreens should not advertise tap tool capabilities */
593 	if (!bit_test(evdev->ev_prop_flags, INPUT_PROP_DIRECT))
594 		evdev_support_nfingers(evdev, MAXIMAL_MT_SLOT(evdev) + 1);
595 
596 	/* Echo 0-th MT-slot as ST-slot */
597 	for (i = 0; i < nitems(evdev_mtstmap); i++) {
598 		if (!bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].mt) ||
599 		     bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].st))
600 			continue;
601 		ai = evdev->ev_absinfo + evdev_mtstmap[i].mt;
602 		evdev->ev_mt->mtst_events |= 1U << i;
603 		if (evdev_mtstmap[i].max != 0)
604 			evdev_support_abs(evdev, evdev_mtstmap[i].st,
605 			    0,
606 			    evdev_mtstmap[i].max,
607 			    0,
608 			    evdev_mt_normalize(
609 			      ai->flat, 0, ai->maximum, evdev_mtstmap[i].max),
610 			    0);
611 		else
612 			evdev_support_abs(evdev, evdev_mtstmap[i].st,
613 			    ai->minimum,
614 			    ai->maximum,
615 			    0,
616 			    ai->flat,
617 			    ai->resolution);
618 	}
619 }
620 
621 static void
evdev_mt_send_st_compat(struct evdev_dev * evdev)622 evdev_mt_send_st_compat(struct evdev_dev *evdev)
623 {
624 	struct evdev_mt *mt = evdev->ev_mt;
625 	int nfingers, i, st_slot;
626 
627 	EVDEV_LOCK_ASSERT(evdev);
628 
629 	nfingers = bitcount(mt->touches);
630 	evdev_send_event(evdev, EV_KEY, BTN_TOUCH, nfingers > 0);
631 
632 	/* Send first active MT-slot state as single touch report */
633 	st_slot = ffs(mt->touches) - 1;
634 	if (st_slot != -1)
635 		FOREACHBIT(mt->mtst_events, i)
636 			evdev_send_event(evdev, EV_ABS, evdev_mtstmap[i].st,
637 			    evdev_mt_normalize(evdev_mt_get_value(evdev,
638 			      st_slot, evdev_mtstmap[i].mt),
639 			      evdev->ev_absinfo[evdev_mtstmap[i].mt].minimum,
640 			      evdev->ev_absinfo[evdev_mtstmap[i].mt].maximum,
641 			      evdev_mtstmap[i].max));
642 
643 	/* Touchscreens should not report tool taps */
644 	if (!bit_test(evdev->ev_prop_flags, INPUT_PROP_DIRECT))
645 		evdev_send_nfingers(evdev, nfingers);
646 
647 	if (nfingers == 0)
648 		evdev_send_event(evdev, EV_ABS, ABS_PRESSURE, 0);
649 }
650 
651 void
evdev_push_mt_compat(struct evdev_dev * evdev)652 evdev_push_mt_compat(struct evdev_dev *evdev)
653 {
654 
655 	EVDEV_ENTER(evdev);
656 	evdev_mt_send_st_compat(evdev);
657 	EVDEV_EXIT(evdev);
658 }
659 
660 static void
evdev_mt_send_autorel(struct evdev_dev * evdev)661 evdev_mt_send_autorel(struct evdev_dev *evdev)
662 {
663 	struct evdev_mt *mt = evdev->ev_mt;
664 	int slot;
665 
666 	EVDEV_LOCK_ASSERT(evdev);
667 	KASSERT(mt->match_frame == 0, ("Unmatched events exist"));
668 
669 	FOREACHBIT(mt->touches & ~mt->frame, slot)
670 		evdev_mt_send_slot(evdev, slot, NULL);
671 }
672 
673 void
evdev_mt_push_autorel(struct evdev_dev * evdev)674 evdev_mt_push_autorel(struct evdev_dev *evdev)
675 {
676 	EVDEV_ENTER(evdev);
677 	evdev_mt_send_autorel(evdev);
678 	EVDEV_EXIT(evdev);
679 }
680