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 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 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 150 evdev_mt_free(struct evdev_dev *evdev) 151 { 152 free(evdev->ev_mt, M_EVDEV); 153 } 154 155 void 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 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 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 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 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 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 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 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 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 * 469 evdev_mt_get_match_slots(struct evdev_dev *evdev) 470 { 471 return (evdev->ev_mt->match_slots); 472 } 473 474 int 475 evdev_mt_get_last_slot(struct evdev_dev *evdev) 476 { 477 return (evdev->ev_mt->last_reported_slot); 478 } 479 480 void 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 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 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 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 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 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 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 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 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 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