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