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 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 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 154 evdev_mt_free(struct evdev_dev *evdev) 155 { 156 kfree(evdev->ev_mt, M_EVDEV); 157 } 158 159 void 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 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 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 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 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 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 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 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 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 * 475 evdev_mt_get_match_slots(struct evdev_dev *evdev) 476 { 477 return (evdev->ev_mt->match_slots); 478 } 479 480 int 481 evdev_mt_get_last_slot(struct evdev_dev *evdev) 482 { 483 484 return (evdev->ev_mt->last_reported_slot); 485 } 486 487 void 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 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 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 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 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 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 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 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 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 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