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