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