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 } 674