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