1/* 2 * Copyright © 2015 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include "config.h" 25 26#include <math.h> 27#include <stdbool.h> 28 29#include "evdev-mt-touchpad.h" 30 31#define QUICK_GESTURE_HOLD_TIMEOUT ms2us(40) 32#define DEFAULT_GESTURE_HOLD_TIMEOUT ms2us(180) 33#define DEFAULT_GESTURE_SWITCH_TIMEOUT ms2us(100) 34#define DEFAULT_GESTURE_SWIPE_TIMEOUT ms2us(150) 35#define DEFAULT_GESTURE_PINCH_TIMEOUT ms2us(300) 36 37#define HOLD_AND_MOTION_THRESHOLD 0.5 /* mm */ 38#define PINCH_DISAMBIGUATION_MOVE_THRESHOLD 1.5 /* mm */ 39 40enum gesture_event { 41 GESTURE_EVENT_RESET, 42 GESTURE_EVENT_FINGER_DETECTED, 43 GESTURE_EVENT_HOLD_TIMEOUT, 44 GESTURE_EVENT_HOLD_AND_MOTION, 45 GESTURE_EVENT_POINTER_MOTION, 46 GESTURE_EVENT_SCROLL, 47 GESTURE_EVENT_SWIPE, 48 GESTURE_EVENT_PINCH, 49}; 50 51/***************************************** 52 * DO NOT EDIT THIS FILE! 53 * 54 * Look at the state diagram in doc/touchpad-gestures-state-machine.svg 55 * (generated with https://www.diagrams.net) 56 * 57 * Any changes in this file must be represented in the diagram. 58 */ 59 60static inline const char* 61gesture_state_to_str(enum tp_gesture_state state) 62{ 63 switch (state) { 64 CASE_RETURN_STRING(GESTURE_STATE_NONE); 65 CASE_RETURN_STRING(GESTURE_STATE_UNKNOWN); 66 CASE_RETURN_STRING(GESTURE_STATE_HOLD); 67 CASE_RETURN_STRING(GESTURE_STATE_HOLD_AND_MOTION); 68 CASE_RETURN_STRING(GESTURE_STATE_POINTER_MOTION); 69 CASE_RETURN_STRING(GESTURE_STATE_SCROLL); 70 CASE_RETURN_STRING(GESTURE_STATE_PINCH); 71 CASE_RETURN_STRING(GESTURE_STATE_SWIPE); 72 } 73 return NULL; 74} 75 76static inline const char* 77gesture_event_to_str(enum gesture_event event) 78{ 79 switch(event) { 80 CASE_RETURN_STRING(GESTURE_EVENT_RESET); 81 CASE_RETURN_STRING(GESTURE_EVENT_FINGER_DETECTED); 82 CASE_RETURN_STRING(GESTURE_EVENT_HOLD_TIMEOUT); 83 CASE_RETURN_STRING(GESTURE_EVENT_HOLD_AND_MOTION); 84 CASE_RETURN_STRING(GESTURE_EVENT_POINTER_MOTION); 85 CASE_RETURN_STRING(GESTURE_EVENT_SCROLL); 86 CASE_RETURN_STRING(GESTURE_EVENT_SWIPE); 87 CASE_RETURN_STRING(GESTURE_EVENT_PINCH); 88 } 89 return NULL; 90} 91 92static struct device_float_coords 93tp_get_touches_delta(struct tp_dispatch *tp, bool average) 94{ 95 struct tp_touch *t; 96 unsigned int i, nactive = 0; 97 struct device_float_coords delta = {0.0, 0.0}; 98 99 for (i = 0; i < tp->num_slots; i++) { 100 t = &tp->touches[i]; 101 102 if (!tp_touch_active_for_gesture(tp, t)) 103 continue; 104 105 nactive++; 106 107 if (t->dirty) { 108 struct device_coords d; 109 110 d = tp_get_delta(t); 111 112 delta.x += d.x; 113 delta.y += d.y; 114 } 115 } 116 117 if (!average || nactive == 0) 118 return delta; 119 120 delta.x /= nactive; 121 delta.y /= nactive; 122 123 return delta; 124} 125 126static void 127tp_gesture_init_scroll(struct tp_dispatch *tp) 128{ 129 struct phys_coords zero = {0.0, 0.0}; 130 tp->scroll.active.h = false; 131 tp->scroll.active.v = false; 132 tp->scroll.duration.h = 0; 133 tp->scroll.duration.v = 0; 134 tp->scroll.vector = zero; 135 tp->scroll.time_prev = 0; 136} 137 138static inline struct device_float_coords 139tp_get_combined_touches_delta(struct tp_dispatch *tp) 140{ 141 return tp_get_touches_delta(tp, false); 142} 143 144static inline struct device_float_coords 145tp_get_average_touches_delta(struct tp_dispatch *tp) 146{ 147 return tp_get_touches_delta(tp, true); 148} 149 150static void 151tp_gesture_start(struct tp_dispatch *tp, uint64_t time) 152{ 153 const struct normalized_coords zero = { 0.0, 0.0 }; 154 155 if (tp->gesture.started) 156 return; 157 158 switch (tp->gesture.state) { 159 case GESTURE_STATE_NONE: 160 case GESTURE_STATE_UNKNOWN: 161 evdev_log_bug_libinput(tp->device, 162 "%s in unknown gesture mode\n", 163 __func__); 164 break; 165 case GESTURE_STATE_HOLD: 166 case GESTURE_STATE_HOLD_AND_MOTION: 167 gesture_notify_hold(&tp->device->base, time, 168 tp->gesture.finger_count); 169 break; 170 case GESTURE_STATE_SCROLL: 171 tp_gesture_init_scroll(tp); 172 break; 173 case GESTURE_STATE_PINCH: 174 gesture_notify_pinch(&tp->device->base, time, 175 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 176 tp->gesture.finger_count, 177 &zero, &zero, 1.0, 0.0); 178 break; 179 case GESTURE_STATE_SWIPE: 180 gesture_notify_swipe(&tp->device->base, time, 181 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 182 tp->gesture.finger_count, 183 &zero, &zero); 184 break; 185 case GESTURE_STATE_POINTER_MOTION: 186 break; 187 } 188 189 tp->gesture.started = true; 190} 191 192static struct device_float_coords 193tp_get_raw_pointer_motion(struct tp_dispatch *tp) 194{ 195 struct device_float_coords raw; 196 197 /* When a clickpad is clicked, combine motion of all active touches */ 198 if (tp->buttons.is_clickpad && tp->buttons.state) 199 raw = tp_get_combined_touches_delta(tp); 200 else 201 raw = tp_get_average_touches_delta(tp); 202 203 return raw; 204} 205 206static bool 207tp_has_pending_pointer_motion(struct tp_dispatch *tp, uint64_t time) 208{ 209 struct device_float_coords raw; 210 211 if (!(tp->queued & TOUCHPAD_EVENT_MOTION)) 212 return false; 213 214 /* Checking for raw pointer motion is enough in this case. 215 * Calling tp_filter_motion is intentionally omitted to avoid calling 216 * it twice (here and in tp_gesture_post_pointer_motion) with the same 217 * event. 218 */ 219 raw = tp_get_raw_pointer_motion(tp); 220 return !device_float_is_zero(raw); 221} 222 223static void 224tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time) 225{ 226 struct device_float_coords raw; 227 struct normalized_coords delta; 228 229 raw = tp_get_raw_pointer_motion(tp); 230 delta = tp_filter_motion(tp, &raw, time); 231 232 if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) { 233 struct device_float_coords unaccel; 234 235 unaccel = tp_scale_to_xaxis(tp, raw); 236 pointer_notify_motion(&tp->device->base, 237 time, 238 &delta, 239 &unaccel); 240 } 241} 242 243static unsigned int 244tp_gesture_get_active_touches(const struct tp_dispatch *tp, 245 struct tp_touch **touches, 246 unsigned int count) 247{ 248 unsigned int n = 0; 249 struct tp_touch *t; 250 251 memset(touches, 0, count * sizeof(struct tp_touch *)); 252 253 tp_for_each_touch(tp, t) { 254 if (tp_touch_active_for_gesture(tp, t)) { 255 touches[n++] = t; 256 if (n == count) 257 return count; 258 } 259 } 260 261 /* 262 * This can happen when the user does .e.g: 263 * 1) Put down 1st finger in center (so active) 264 * 2) Put down 2nd finger in a button area (so inactive) 265 * 3) Put down 3th finger somewhere, gets reported as a fake finger, 266 * so gets same coordinates as 1st -> active 267 * 268 * We could avoid this by looking at all touches, be we really only 269 * want to look at real touches. 270 */ 271 return n; 272} 273 274static inline int 275tp_gesture_same_directions(int dir1, int dir2) 276{ 277 /* 278 * In some cases (semi-mt touchpads) we may seen one finger move 279 * e.g. N/NE and the other W/NW so we not only check for overlapping 280 * directions, but also for neighboring bits being set. 281 * The ((dira & 0x80) && (dirb & 0x01)) checks are to check for bit 0 282 * and 7 being set as they also represent neighboring directions. 283 */ 284 return ((dir1 | (dir1 >> 1)) & dir2) || 285 ((dir2 | (dir2 >> 1)) & dir1) || 286 ((dir1 & 0x80) && (dir2 & 0x01)) || 287 ((dir2 & 0x80) && (dir1 & 0x01)); 288} 289 290static struct phys_coords 291tp_gesture_mm_moved(struct tp_dispatch *tp, struct tp_touch *t) 292{ 293 struct device_coords delta; 294 295 delta.x = abs(t->point.x - t->gesture.initial.x); 296 delta.y = abs(t->point.y - t->gesture.initial.y); 297 298 return evdev_device_unit_delta_to_mm(tp->device, &delta); 299} 300 301static uint32_t 302tp_gesture_get_direction(struct tp_dispatch *tp, struct tp_touch *touch) 303{ 304 struct phys_coords mm; 305 struct device_float_coords delta; 306 307 delta = device_delta(touch->point, touch->gesture.initial); 308 mm = tp_phys_delta(tp, delta); 309 310 return phys_get_direction(mm); 311} 312 313static void 314tp_gesture_get_pinch_info(struct tp_dispatch *tp, 315 double *distance, 316 double *angle, 317 struct device_float_coords *center) 318{ 319 struct normalized_coords normalized; 320 struct device_float_coords delta; 321 struct tp_touch *first = tp->gesture.touches[0], 322 *second = tp->gesture.touches[1]; 323 324 delta = device_delta(first->point, second->point); 325 normalized = tp_normalize_delta(tp, delta); 326 *distance = normalized_length(normalized); 327 *angle = atan2(normalized.y, normalized.x) * 180.0 / M_PI; 328 329 *center = device_average(first->point, second->point); 330} 331 332static inline void 333tp_gesture_init_pinch(struct tp_dispatch *tp) 334{ 335 tp_gesture_get_pinch_info(tp, 336 &tp->gesture.initial_distance, 337 &tp->gesture.angle, 338 &tp->gesture.center); 339 tp->gesture.prev_scale = 1.0; 340} 341 342static void 343tp_gesture_set_scroll_buildup(struct tp_dispatch *tp) 344{ 345 struct device_float_coords d0, d1; 346 struct device_float_coords average; 347 struct tp_touch *first = tp->gesture.touches[0], 348 *second = tp->gesture.touches[1]; 349 350 d0 = device_delta(first->point, first->gesture.initial); 351 d1 = device_delta(second->point, second->gesture.initial); 352 353 average = device_float_average(d0, d1); 354 tp->device->scroll.buildup = tp_normalize_delta(tp, average); 355} 356 357static void 358tp_gesture_apply_scroll_constraints(struct tp_dispatch *tp, 359 struct device_float_coords *raw, 360 struct normalized_coords *delta, 361 uint64_t time) 362{ 363 uint64_t tdelta = 0; 364 struct phys_coords delta_mm, vector; 365 double vector_decay, vector_length, slope; 366 367 const uint64_t ACTIVE_THRESHOLD = ms2us(100), 368 INACTIVE_THRESHOLD = ms2us(50), 369 EVENT_TIMEOUT = ms2us(100); 370 371 /* Both axes active == true means free scrolling is enabled */ 372 if (tp->scroll.active.h && tp->scroll.active.v) 373 return; 374 375 /* Determine time delta since last movement event */ 376 if (tp->scroll.time_prev != 0) 377 tdelta = time - tp->scroll.time_prev; 378 if (tdelta > EVENT_TIMEOUT) 379 tdelta = 0; 380 tp->scroll.time_prev = time; 381 382 /* Delta since last movement event in mm */ 383 delta_mm = tp_phys_delta(tp, *raw); 384 385 /* Old vector data "fades" over time. This is a two-part linear 386 * approximation of an exponential function - for example, for 387 * EVENT_TIMEOUT of 100, vector_decay = (0.97)^tdelta. This linear 388 * approximation allows easier tweaking of EVENT_TIMEOUT and is faster. 389 */ 390 if (tdelta > 0) { 391 double recent, later; 392 recent = ((EVENT_TIMEOUT / 2.0) - tdelta) / 393 (EVENT_TIMEOUT / 2.0); 394 later = (EVENT_TIMEOUT - tdelta) / 395 (EVENT_TIMEOUT * 2.0); 396 vector_decay = tdelta <= (0.33 * EVENT_TIMEOUT) ? 397 recent : later; 398 } else { 399 vector_decay = 0.0; 400 } 401 402 /* Calculate windowed vector from delta + weighted historic data */ 403 vector.x = (tp->scroll.vector.x * vector_decay) + delta_mm.x; 404 vector.y = (tp->scroll.vector.y * vector_decay) + delta_mm.y; 405 vector_length = hypot(vector.x, vector.y); 406 tp->scroll.vector = vector; 407 408 /* We care somewhat about distance and speed, but more about 409 * consistency of direction over time. Keep track of the time spent 410 * primarily along each axis. If one axis is active, time spent NOT 411 * moving much in the other axis is subtracted, allowing a switch of 412 * axes in a single scroll + ability to "break out" and go diagonal. 413 * 414 * Slope to degree conversions (infinity = 90°, 0 = 0°): 415 */ 416 const double DEGREE_75 = 3.73; 417 const double DEGREE_60 = 1.73; 418 const double DEGREE_30 = 0.57; 419 const double DEGREE_15 = 0.27; 420 slope = (vector.x != 0) ? fabs(vector.y / vector.x) : INFINITY; 421 422 /* Ensure vector is big enough (in mm per EVENT_TIMEOUT) to be confident 423 * of direction. Larger = harder to enable diagonal/free scrolling. 424 */ 425 const double MIN_VECTOR = 0.15; 426 427 if (slope >= DEGREE_30 && vector_length > MIN_VECTOR) { 428 tp->scroll.duration.v += tdelta; 429 if (tp->scroll.duration.v > ACTIVE_THRESHOLD) 430 tp->scroll.duration.v = ACTIVE_THRESHOLD; 431 if (slope >= DEGREE_75) { 432 if (tp->scroll.duration.h > tdelta) 433 tp->scroll.duration.h -= tdelta; 434 else 435 tp->scroll.duration.h = 0; 436 } 437 } 438 if (slope < DEGREE_60 && vector_length > MIN_VECTOR) { 439 tp->scroll.duration.h += tdelta; 440 if (tp->scroll.duration.h > ACTIVE_THRESHOLD) 441 tp->scroll.duration.h = ACTIVE_THRESHOLD; 442 if (slope < DEGREE_15) { 443 if (tp->scroll.duration.v > tdelta) 444 tp->scroll.duration.v -= tdelta; 445 else 446 tp->scroll.duration.v = 0; 447 } 448 } 449 450 if (tp->scroll.duration.h == ACTIVE_THRESHOLD) { 451 tp->scroll.active.h = true; 452 if (tp->scroll.duration.v < INACTIVE_THRESHOLD) 453 tp->scroll.active.v = false; 454 } 455 if (tp->scroll.duration.v == ACTIVE_THRESHOLD) { 456 tp->scroll.active.v = true; 457 if (tp->scroll.duration.h < INACTIVE_THRESHOLD) 458 tp->scroll.active.h = false; 459 } 460 461 /* If vector is big enough in a diagonal direction, always unlock 462 * both axes regardless of thresholds 463 */ 464 if (vector_length > 5.0 && slope < 1.73 && slope >= 0.57) { 465 tp->scroll.active.v = true; 466 tp->scroll.active.h = true; 467 } 468 469 /* If only one axis is active, constrain motion accordingly. If both 470 * are set, we've detected deliberate diagonal movement; enable free 471 * scrolling for the life of the gesture. 472 */ 473 if (!tp->scroll.active.h && tp->scroll.active.v) 474 delta->x = 0.0; 475 if (tp->scroll.active.h && !tp->scroll.active.v) 476 delta->y = 0.0; 477 478 /* If we haven't determined an axis, use the slope in the meantime */ 479 if (!tp->scroll.active.h && !tp->scroll.active.v) { 480 delta->x = (slope >= DEGREE_60) ? 0.0 : delta->x; 481 delta->y = (slope < DEGREE_30) ? 0.0 : delta->y; 482 } 483} 484 485static inline void 486log_gesture_bug(struct tp_dispatch *tp, enum gesture_event event) 487{ 488 evdev_log_bug_libinput(tp->device, 489 "invalid gesture event %s in state %s\n", 490 gesture_event_to_str(event), 491 gesture_state_to_str(tp->gesture.state)); 492} 493 494static bool 495tp_gesture_is_quick_hold(struct tp_dispatch *tp) 496{ 497 /* When 1 or 2 fingers are used to hold, always use a "quick" hold to 498 * make the hold to stop kinetic scrolling user interaction feel more 499 * natural. 500 */ 501 return (tp->gesture.finger_count == 1) || 502 (tp->gesture.finger_count == 2); 503} 504 505static bool 506tp_gesture_use_hold_timer(struct tp_dispatch *tp) 507{ 508 /* When tap is not enabled, always use the timer */ 509 if (!tp->tap.enabled) 510 return true; 511 512 /* Always use the timer if it is a quick hold */ 513 if (tp_gesture_is_quick_hold(tp)) 514 return true; 515 516 /* If the number of fingers on the touchpad exceeds the number of 517 * allowed fingers to tap, use the timer. 518 */ 519 if (tp->gesture.finger_count > 3) 520 return true; 521 522 /* If the tap state machine is already in a hold status, for example 523 * when holding with 3 fingers and then holding with 2, use the timer. 524 */ 525 if (tp->tap.state == TAP_STATE_HOLD || 526 tp->tap.state == TAP_STATE_TOUCH_2_HOLD || 527 tp->tap.state == TAP_STATE_TOUCH_3_HOLD) 528 return true; 529 530 /* If the tap state machine is in dead status, use the timer. This 531 * happens when the user holds after cancelling a gesture/scroll. 532 */ 533 if (tp->tap.state == TAP_STATE_DEAD) 534 return true; 535 536 /* Otherwise, sync the hold notification with the tap state machine */ 537 return false; 538} 539 540static void 541tp_gesture_set_hold_timer(struct tp_dispatch *tp, uint64_t time) 542{ 543 uint64_t timeout; 544 545 if (!tp->gesture.hold_enabled) 546 return; 547 548 if (tp_gesture_use_hold_timer(tp)) { 549 timeout = tp_gesture_is_quick_hold(tp) ? 550 QUICK_GESTURE_HOLD_TIMEOUT : 551 DEFAULT_GESTURE_HOLD_TIMEOUT; 552 553 libinput_timer_set(&tp->gesture.hold_timer, time + timeout); 554 } 555} 556 557static void 558tp_gesture_handle_event_on_state_none(struct tp_dispatch *tp, 559 enum gesture_event event, 560 uint64_t time) 561{ 562 switch(event) { 563 case GESTURE_EVENT_RESET: 564 libinput_timer_cancel(&tp->gesture.hold_timer); 565 break; 566 case GESTURE_EVENT_FINGER_DETECTED: 567 tp_gesture_set_hold_timer(tp, time); 568 tp->gesture.state = GESTURE_STATE_UNKNOWN; 569 break; 570 case GESTURE_EVENT_HOLD_TIMEOUT: 571 break; 572 case GESTURE_EVENT_POINTER_MOTION: 573 tp->gesture.state = GESTURE_STATE_POINTER_MOTION; 574 break; 575 case GESTURE_EVENT_SCROLL: 576 tp->gesture.state = GESTURE_STATE_SCROLL; 577 break; 578 case GESTURE_EVENT_HOLD_AND_MOTION: 579 case GESTURE_EVENT_SWIPE: 580 case GESTURE_EVENT_PINCH: 581 log_gesture_bug(tp, event); 582 break; 583 } 584} 585 586static void 587tp_gesture_handle_event_on_state_unknown(struct tp_dispatch *tp, 588 enum gesture_event event, 589 uint64_t time) 590{ 591 switch(event) { 592 case GESTURE_EVENT_RESET: 593 libinput_timer_cancel(&tp->gesture.hold_timer); 594 tp->gesture.state = GESTURE_STATE_NONE; 595 break; 596 case GESTURE_EVENT_HOLD_TIMEOUT: 597 tp->gesture.state = GESTURE_STATE_HOLD; 598 tp_gesture_start(tp, time); 599 break; 600 case GESTURE_EVENT_POINTER_MOTION: 601 /* Don't cancel the hold timer. This pointer motion can end up 602 * being recognised as hold and motion. */ 603 tp->gesture.state = GESTURE_STATE_POINTER_MOTION; 604 break; 605 case GESTURE_EVENT_SCROLL: 606 libinput_timer_cancel(&tp->gesture.hold_timer); 607 tp_gesture_set_scroll_buildup(tp); 608 tp->gesture.state = GESTURE_STATE_SCROLL; 609 break; 610 case GESTURE_EVENT_SWIPE: 611 libinput_timer_cancel(&tp->gesture.hold_timer); 612 tp->gesture.state = GESTURE_STATE_SWIPE; 613 break; 614 case GESTURE_EVENT_PINCH: 615 libinput_timer_cancel(&tp->gesture.hold_timer); 616 tp_gesture_init_pinch(tp); 617 tp->gesture.state = GESTURE_STATE_PINCH; 618 break; 619 case GESTURE_EVENT_HOLD_AND_MOTION: 620 case GESTURE_EVENT_FINGER_DETECTED: 621 log_gesture_bug(tp, event); 622 break; 623 } 624} 625 626static void 627tp_gesture_handle_event_on_state_hold(struct tp_dispatch *tp, 628 enum gesture_event event, 629 uint64_t time) 630{ 631 switch(event) { 632 case GESTURE_EVENT_RESET: 633 libinput_timer_cancel(&tp->gesture.hold_timer); 634 tp->gesture.state = GESTURE_STATE_NONE; 635 break; 636 case GESTURE_EVENT_HOLD_AND_MOTION: 637 tp->gesture.state = GESTURE_STATE_HOLD_AND_MOTION; 638 break; 639 case GESTURE_EVENT_POINTER_MOTION: 640 tp_gesture_cancel(tp, time); 641 tp->gesture.state = GESTURE_STATE_POINTER_MOTION; 642 break; 643 case GESTURE_EVENT_SCROLL: 644 tp_gesture_set_scroll_buildup(tp); 645 tp_gesture_cancel(tp, time); 646 tp->gesture.state = GESTURE_STATE_SCROLL; 647 break; 648 case GESTURE_EVENT_SWIPE: 649 tp_gesture_cancel(tp, time); 650 tp->gesture.state = GESTURE_STATE_SWIPE; 651 break; 652 case GESTURE_EVENT_PINCH: 653 tp_gesture_init_pinch(tp); 654 tp_gesture_cancel(tp, time); 655 tp->gesture.state = GESTURE_STATE_PINCH; 656 break; 657 case GESTURE_EVENT_HOLD_TIMEOUT: 658 case GESTURE_EVENT_FINGER_DETECTED: 659 log_gesture_bug(tp, event); 660 break; 661 } 662} 663 664static void 665tp_gesture_handle_event_on_state_hold_and_motion(struct tp_dispatch *tp, 666 enum gesture_event event, 667 uint64_t time) 668{ 669 switch(event) { 670 case GESTURE_EVENT_RESET: 671 libinput_timer_cancel(&tp->gesture.hold_timer); 672 tp->gesture.state = GESTURE_STATE_NONE; 673 break; 674 case GESTURE_EVENT_POINTER_MOTION: 675 tp_gesture_cancel(tp, time); 676 tp->gesture.state = GESTURE_STATE_POINTER_MOTION; 677 break; 678 case GESTURE_EVENT_HOLD_AND_MOTION: 679 case GESTURE_EVENT_FINGER_DETECTED: 680 case GESTURE_EVENT_HOLD_TIMEOUT: 681 case GESTURE_EVENT_SCROLL: 682 case GESTURE_EVENT_SWIPE: 683 case GESTURE_EVENT_PINCH: 684 log_gesture_bug(tp, event); 685 break; 686 } 687} 688 689static void 690tp_gesture_handle_event_on_state_pointer_motion(struct tp_dispatch *tp, 691 enum gesture_event event, 692 uint64_t time) 693{ 694 struct tp_touch *first; 695 struct phys_coords first_moved; 696 double first_mm; 697 698 switch(event) { 699 case GESTURE_EVENT_RESET: 700 libinput_timer_cancel(&tp->gesture.hold_timer); 701 tp->gesture.state = GESTURE_STATE_NONE; 702 break; 703 case GESTURE_EVENT_HOLD_TIMEOUT: 704 if (tp->gesture.finger_count != 1) 705 break; 706 707 first = tp->gesture.touches[0]; 708 first_moved = tp_gesture_mm_moved(tp, first); 709 first_mm = hypot(first_moved.x, first_moved.y); 710 711 if (first_mm < HOLD_AND_MOTION_THRESHOLD) { 712 tp->gesture.state = GESTURE_STATE_HOLD_AND_MOTION; 713 tp_gesture_start(tp, time); 714 } 715 break; 716 case GESTURE_EVENT_HOLD_AND_MOTION: 717 case GESTURE_EVENT_FINGER_DETECTED: 718 case GESTURE_EVENT_POINTER_MOTION: 719 case GESTURE_EVENT_SCROLL: 720 case GESTURE_EVENT_SWIPE: 721 case GESTURE_EVENT_PINCH: 722 log_gesture_bug(tp, event); 723 break; 724 } 725} 726 727static void 728tp_gesture_handle_event_on_state_scroll(struct tp_dispatch *tp, 729 enum gesture_event event, 730 uint64_t time) 731{ 732 switch(event) { 733 case GESTURE_EVENT_RESET: 734 libinput_timer_cancel(&tp->gesture.hold_timer); 735 tp->gesture.state = GESTURE_STATE_NONE; 736 break; 737 case GESTURE_EVENT_PINCH: 738 tp_gesture_init_pinch(tp); 739 tp_gesture_cancel(tp, time); 740 tp->gesture.state = GESTURE_STATE_PINCH; 741 break; 742 case GESTURE_EVENT_HOLD_AND_MOTION: 743 case GESTURE_EVENT_FINGER_DETECTED: 744 case GESTURE_EVENT_HOLD_TIMEOUT: 745 case GESTURE_EVENT_POINTER_MOTION: 746 case GESTURE_EVENT_SCROLL: 747 case GESTURE_EVENT_SWIPE: 748 log_gesture_bug(tp, event); 749 break; 750 } 751} 752 753static void 754tp_gesture_handle_event_on_state_pinch(struct tp_dispatch *tp, 755 enum gesture_event event, 756 uint64_t time) 757{ 758 switch(event) { 759 case GESTURE_EVENT_RESET: 760 libinput_timer_cancel(&tp->gesture.hold_timer); 761 tp->gesture.state = GESTURE_STATE_NONE; 762 break; 763 case GESTURE_EVENT_HOLD_AND_MOTION: 764 case GESTURE_EVENT_FINGER_DETECTED: 765 case GESTURE_EVENT_HOLD_TIMEOUT: 766 case GESTURE_EVENT_POINTER_MOTION: 767 case GESTURE_EVENT_SCROLL: 768 case GESTURE_EVENT_SWIPE: 769 case GESTURE_EVENT_PINCH: 770 log_gesture_bug(tp, event); 771 break; 772 } 773} 774 775static void 776tp_gesture_handle_event_on_state_swipe(struct tp_dispatch *tp, 777 enum gesture_event event, 778 uint64_t time) 779{ 780 switch(event) { 781 case GESTURE_EVENT_RESET: 782 libinput_timer_cancel(&tp->gesture.hold_timer); 783 tp->gesture.state = GESTURE_STATE_NONE; 784 break; 785 case GESTURE_EVENT_HOLD_AND_MOTION: 786 case GESTURE_EVENT_FINGER_DETECTED: 787 case GESTURE_EVENT_HOLD_TIMEOUT: 788 case GESTURE_EVENT_POINTER_MOTION: 789 case GESTURE_EVENT_SCROLL: 790 case GESTURE_EVENT_SWIPE: 791 case GESTURE_EVENT_PINCH: 792 log_gesture_bug(tp, event); 793 break; 794 } 795} 796 797static void 798tp_gesture_handle_event(struct tp_dispatch *tp, 799 enum gesture_event event, 800 uint64_t time) 801{ 802 enum tp_gesture_state oldstate; 803 804 oldstate = tp->gesture.state; 805 806 switch(tp->gesture.state) { 807 case GESTURE_STATE_NONE: 808 tp_gesture_handle_event_on_state_none(tp, event, time); 809 break; 810 case GESTURE_STATE_UNKNOWN: 811 tp_gesture_handle_event_on_state_unknown(tp, event, time); 812 break; 813 case GESTURE_STATE_HOLD: 814 tp_gesture_handle_event_on_state_hold(tp, event, time); 815 break; 816 case GESTURE_STATE_HOLD_AND_MOTION: 817 tp_gesture_handle_event_on_state_hold_and_motion(tp, event, time); 818 break; 819 case GESTURE_STATE_POINTER_MOTION: 820 tp_gesture_handle_event_on_state_pointer_motion(tp, event, time); 821 break; 822 case GESTURE_STATE_SCROLL: 823 tp_gesture_handle_event_on_state_scroll(tp, event, time); 824 break; 825 case GESTURE_STATE_PINCH: 826 tp_gesture_handle_event_on_state_pinch(tp, event, time); 827 break; 828 case GESTURE_STATE_SWIPE: 829 tp_gesture_handle_event_on_state_swipe(tp, event, time); 830 break; 831 } 832 833 if (oldstate != tp->gesture.state) { 834 evdev_log_debug(tp->device, 835 "gesture state %s → %s → %s\n", 836 gesture_state_to_str(oldstate), 837 gesture_event_to_str(event), 838 gesture_state_to_str(tp->gesture.state)); 839 } 840} 841 842static void 843tp_gesture_hold_timeout(uint64_t now, void *data) 844{ 845 struct tp_dispatch *tp = data; 846 847 if (tp_tap_dragging_or_double_tapping(tp) || tp_tap_dragging(tp)) 848 return; 849 850 tp_gesture_handle_event(tp, GESTURE_EVENT_HOLD_TIMEOUT, now); 851} 852 853void 854tp_gesture_tap_timeout(struct tp_dispatch *tp, uint64_t time) 855{ 856 if (!tp->gesture.hold_enabled) 857 return; 858 859 if (!tp_gesture_is_quick_hold(tp)) 860 tp_gesture_handle_event(tp, GESTURE_EVENT_HOLD_TIMEOUT, time); 861} 862 863static void 864tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, uint64_t time) 865{ 866 struct tp_touch *first = tp->gesture.touches[0], 867 *second = tp->gesture.touches[1], 868 *thumb; 869 uint32_t dir1, dir2; 870 struct device_coords delta; 871 struct phys_coords first_moved, second_moved, distance_mm; 872 double first_mm, second_mm; /* movement since gesture start in mm */ 873 double thumb_mm, finger_mm; 874 double min_move = 1.5; /* min movement threshold in mm - count this touch */ 875 double max_move = 4.0; /* max movement threshold in mm - ignore other touch */ 876 bool is_hold_and_motion; 877 878 first_moved = tp_gesture_mm_moved(tp, first); 879 first_mm = hypot(first_moved.x, first_moved.y); 880 881 if (tp->gesture.finger_count == 1) { 882 if (!tp_has_pending_pointer_motion(tp, time)) 883 return; 884 885 is_hold_and_motion = (first_mm < HOLD_AND_MOTION_THRESHOLD); 886 887 if (tp->gesture.state == GESTURE_STATE_HOLD && 888 is_hold_and_motion) { 889 tp_gesture_handle_event(tp, 890 GESTURE_EVENT_HOLD_AND_MOTION, 891 time); 892 return; 893 } 894 895 if (tp->gesture.state == GESTURE_STATE_HOLD_AND_MOTION && 896 is_hold_and_motion) 897 return; 898 899 tp_gesture_handle_event(tp, 900 GESTURE_EVENT_POINTER_MOTION, 901 time); 902 return; 903 } 904 905 /* If we have more fingers than slots, we don't know where the 906 * fingers are. Default to swipe */ 907 if (tp->gesture.enabled && tp->gesture.finger_count > 2 && 908 tp->gesture.finger_count > tp->num_slots) { 909 tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE, time); 910 return; 911 } 912 913 /* Need more margin for error when there are more fingers */ 914 max_move += 2.0 * (tp->gesture.finger_count - 2); 915 min_move += 0.5 * (tp->gesture.finger_count - 2); 916 917 second_moved = tp_gesture_mm_moved(tp, second); 918 second_mm = hypot(second_moved.x, second_moved.y); 919 920 delta.x = abs(first->point.x - second->point.x); 921 delta.y = abs(first->point.y - second->point.y); 922 distance_mm = evdev_device_unit_delta_to_mm(tp->device, &delta); 923 924 /* If both touches moved less than a mm, we cannot decide yet */ 925 if (first_mm < 1 && second_mm < 1) 926 return; 927 928 /* Pick the thumb as the lowest point on the touchpad */ 929 if (first->point.y > second->point.y) { 930 thumb = first; 931 thumb_mm = first_mm; 932 finger_mm = second_mm; 933 } else { 934 thumb = second; 935 thumb_mm = second_mm; 936 finger_mm = first_mm; 937 } 938 939 /* If both touches are within 7mm vertically and 40mm horizontally 940 * past the timeout, assume scroll/swipe */ 941 if ((!tp->gesture.enabled || 942 (distance_mm.x < 40.0 && distance_mm.y < 7.0)) && 943 time > (tp->gesture.initial_time + DEFAULT_GESTURE_SWIPE_TIMEOUT)) { 944 if (tp->gesture.finger_count == 2) 945 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time); 946 else 947 tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE, time); 948 949 return; 950 } 951 952 /* If one touch exceeds the max_move threshold while the other has not 953 * yet passed the min_move threshold, there is either a resting thumb, 954 * or the user is doing "one-finger-scroll," where one touch stays in 955 * place while the other moves. 956 */ 957 if (first_mm >= max_move || second_mm >= max_move) { 958 /* If thumb detection is enabled, and thumb is still while 959 * finger moves, cancel gestures and mark lower as thumb. 960 * This applies to all gestures (2, 3, 4+ fingers), but allows 961 * more thumb motion on >2 finger gestures during detection. 962 */ 963 if (tp->thumb.detect_thumbs && thumb_mm < min_move) { 964 tp_thumb_suppress(tp, thumb); 965 tp_gesture_cancel(tp, time); 966 return; 967 } 968 969 /* If gestures detection is disabled, or if finger is still 970 * while thumb moves, assume this is "one-finger scrolling." 971 * This applies only to 2-finger gestures. 972 */ 973 if ((!tp->gesture.enabled || finger_mm < min_move) && 974 tp->gesture.finger_count == 2) { 975 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time); 976 return; 977 } 978 979 /* If more than 2 fingers are involved, and the thumb moves 980 * while the fingers stay still, assume a pinch if eligible. 981 */ 982 if (finger_mm < min_move && 983 tp->gesture.finger_count > 2 && 984 tp->gesture.enabled && 985 tp->thumb.pinch_eligible) { 986 tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH, time); 987 return; 988 } 989 } 990 991 /* If either touch is still below the min_move threshold, we can't 992 * tell what kind of gesture this is. 993 */ 994 if ((first_mm < min_move) || (second_mm < min_move)) 995 return; 996 997 /* Both touches have exceeded the min_move threshold, so we have a 998 * valid gesture. Update gesture initial time and get directions so 999 * we know if it's a pinch or swipe/scroll. 1000 */ 1001 dir1 = tp_gesture_get_direction(tp, first); 1002 dir2 = tp_gesture_get_direction(tp, second); 1003 1004 /* If we can't accurately detect pinches, or if the touches are moving 1005 * the same way, this is a scroll or swipe. 1006 */ 1007 if (tp->gesture.finger_count > tp->num_slots || 1008 tp_gesture_same_directions(dir1, dir2)) { 1009 if (tp->gesture.finger_count == 2) { 1010 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time); 1011 return; 1012 } 1013 1014 if (tp->gesture.enabled) { 1015 tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE, time); 1016 return; 1017 } 1018 } 1019 1020 /* If the touches are moving away from each other, this is a pinch */ 1021 tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH, time); 1022} 1023 1024static bool 1025tp_gesture_is_pinch(struct tp_dispatch *tp) 1026{ 1027 struct tp_touch *first = tp->gesture.touches[0], 1028 *second = tp->gesture.touches[1]; 1029 uint32_t dir1, dir2; 1030 struct phys_coords first_moved, second_moved; 1031 double first_mm, second_mm; 1032 1033 dir1 = tp_gesture_get_direction(tp, first); 1034 dir2 = tp_gesture_get_direction(tp, second); 1035 if (tp_gesture_same_directions(dir1, dir2)) 1036 return false; 1037 1038 first_moved = tp_gesture_mm_moved(tp, first); 1039 first_mm = hypot(first_moved.x, first_moved.y); 1040 if (first_mm < PINCH_DISAMBIGUATION_MOVE_THRESHOLD) 1041 return false; 1042 1043 second_moved = tp_gesture_mm_moved(tp, second); 1044 second_mm = hypot(second_moved.x, second_moved.y); 1045 if (second_mm < PINCH_DISAMBIGUATION_MOVE_THRESHOLD) 1046 return false; 1047 1048 return true; 1049} 1050 1051static void 1052tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time) 1053{ 1054 struct tp_touch *first, *second; 1055 struct tp_touch *touches[4]; 1056 unsigned int ntouches; 1057 unsigned int i; 1058 1059 ntouches = tp_gesture_get_active_touches(tp, touches, 4); 1060 1061 first = touches[0]; 1062 second = touches[1]; 1063 1064 if (ntouches == 0) 1065 return; 1066 1067 if (ntouches == 1) { 1068 first->gesture.initial = first->point; 1069 tp->gesture.touches[0] = first; 1070 1071 tp_gesture_handle_event(tp, 1072 GESTURE_EVENT_FINGER_DETECTED, 1073 time); 1074 return; 1075 } 1076 1077 if (!tp->gesture.enabled) { 1078 if (ntouches == 2) 1079 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time); 1080 1081 return; 1082 } 1083 1084 /* For 3+ finger gestures, we only really need to track two touches. 1085 * The human hand's finger arrangement means that for a pinch, the 1086 * bottom-most touch will always be the thumb, and the top-most touch 1087 * will always be one of the fingers. 1088 * 1089 * For 3+ finger swipes, the fingers will likely (but not necessarily) 1090 * be in a horizontal line. They all move together, regardless, so it 1091 * doesn't really matter which two of those touches we track. 1092 * 1093 * Tracking top and bottom is a change from previous versions, where 1094 * we tracked leftmost and rightmost. This change enables: 1095 * 1096 * - More accurate pinch detection if thumb is near the center 1097 * - Better resting-thumb detection while two-finger scrolling 1098 * - On capable hardware, allow 3- or 4-finger swipes with resting 1099 * thumb or held-down clickpad 1100 */ 1101 if (ntouches > 2) { 1102 second = touches[0]; 1103 1104 for (i = 1; i < ntouches && i < tp->num_slots; i++) { 1105 if (touches[i]->point.y < first->point.y) 1106 first = touches[i]; 1107 else if (touches[i]->point.y >= second->point.y) 1108 second = touches[i]; 1109 } 1110 1111 if (first == second) 1112 return; 1113 1114 } 1115 1116 tp->gesture.initial_time = time; 1117 first->gesture.initial = first->point; 1118 second->gesture.initial = second->point; 1119 tp->gesture.touches[0] = first; 1120 tp->gesture.touches[1] = second; 1121 1122 tp_gesture_handle_event(tp, GESTURE_EVENT_FINGER_DETECTED, time); 1123} 1124 1125static void 1126tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time, 1127 bool ignore_motion) 1128{ 1129 if (!ignore_motion) 1130 tp_gesture_detect_motion_gestures(tp, time); 1131} 1132 1133static void 1134tp_gesture_handle_state_hold(struct tp_dispatch *tp, uint64_t time, 1135 bool ignore_motion) 1136{ 1137 tp_gesture_start(tp, time); 1138 1139 if (!ignore_motion) 1140 tp_gesture_detect_motion_gestures(tp, time); 1141} 1142 1143static void 1144tp_gesture_handle_state_hold_and_pointer_motion(struct tp_dispatch *tp, uint64_t time) 1145{ 1146 if (tp->queued & TOUCHPAD_EVENT_MOTION) 1147 tp_gesture_post_pointer_motion(tp, time); 1148 1149 tp_gesture_detect_motion_gestures(tp, time); 1150} 1151 1152static void 1153tp_gesture_handle_state_pointer_motion(struct tp_dispatch *tp, uint64_t time) 1154{ 1155 if (tp->queued & TOUCHPAD_EVENT_MOTION) 1156 tp_gesture_post_pointer_motion(tp, time); 1157} 1158 1159static void 1160tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time) 1161{ 1162 struct device_float_coords raw; 1163 struct normalized_coords delta; 1164 1165 if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG) 1166 return; 1167 1168 /* We may confuse a pinch for a scroll initially, 1169 * allow ourselves to correct our guess. 1170 */ 1171 if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) && 1172 tp_gesture_is_pinch(tp)) { 1173 tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH, time); 1174 return; 1175 } 1176 1177 raw = tp_get_average_touches_delta(tp); 1178 1179 /* scroll is not accelerated by default */ 1180 delta = tp_filter_scroll(tp, &raw, time); 1181 1182 if (normalized_is_zero(delta)) 1183 return; 1184 1185 tp_gesture_start(tp, time); 1186 tp_gesture_apply_scroll_constraints(tp, &raw, &delta, time); 1187 evdev_post_scroll(tp->device, 1188 time, 1189 LIBINPUT_POINTER_AXIS_SOURCE_FINGER, 1190 &delta); 1191} 1192 1193static void 1194tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time) 1195{ 1196 struct device_float_coords raw; 1197 struct normalized_coords delta, unaccel; 1198 1199 raw = tp_get_average_touches_delta(tp); 1200 delta = tp_filter_motion(tp, &raw, time); 1201 1202 if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) { 1203 unaccel = tp_filter_motion_unaccelerated(tp, &raw, time); 1204 tp_gesture_start(tp, time); 1205 gesture_notify_swipe(&tp->device->base, time, 1206 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 1207 tp->gesture.finger_count, 1208 &delta, &unaccel); 1209 } 1210} 1211 1212static void 1213tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time) 1214{ 1215 double angle, angle_delta, distance, scale; 1216 struct device_float_coords center, fdelta; 1217 struct normalized_coords delta, unaccel; 1218 1219 tp_gesture_get_pinch_info(tp, &distance, &angle, ¢er); 1220 1221 scale = distance / tp->gesture.initial_distance; 1222 1223 angle_delta = angle - tp->gesture.angle; 1224 tp->gesture.angle = angle; 1225 if (angle_delta > 180.0) 1226 angle_delta -= 360.0; 1227 else if (angle_delta < -180.0) 1228 angle_delta += 360.0; 1229 1230 fdelta = device_float_delta(center, tp->gesture.center); 1231 tp->gesture.center = center; 1232 1233 delta = tp_filter_motion(tp, &fdelta, time); 1234 1235 if (normalized_is_zero(delta) && device_float_is_zero(fdelta) && 1236 scale == tp->gesture.prev_scale && angle_delta == 0.0) 1237 return; 1238 1239 unaccel = tp_filter_motion_unaccelerated(tp, &fdelta, time); 1240 tp_gesture_start(tp, time); 1241 gesture_notify_pinch(&tp->device->base, time, 1242 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1243 tp->gesture.finger_count, 1244 &delta, &unaccel, scale, angle_delta); 1245 1246 tp->gesture.prev_scale = scale; 1247} 1248 1249static void 1250tp_gesture_post_gesture(struct tp_dispatch *tp, uint64_t time, 1251 bool ignore_motion) 1252{ 1253 if (tp->gesture.state == GESTURE_STATE_NONE) 1254 tp_gesture_handle_state_none(tp, time); 1255 1256 if (tp->gesture.state == GESTURE_STATE_UNKNOWN) 1257 tp_gesture_handle_state_unknown(tp, time, ignore_motion); 1258 1259 if (tp->gesture.state == GESTURE_STATE_HOLD) 1260 tp_gesture_handle_state_hold(tp, time, ignore_motion); 1261 1262 if (tp->gesture.state == GESTURE_STATE_POINTER_MOTION) 1263 tp_gesture_handle_state_pointer_motion(tp, time); 1264 1265 if (tp->gesture.state == GESTURE_STATE_HOLD_AND_MOTION) 1266 tp_gesture_handle_state_hold_and_pointer_motion(tp, time); 1267 1268 if (tp->gesture.state == GESTURE_STATE_SCROLL) 1269 tp_gesture_handle_state_scroll(tp, time); 1270 1271 if (tp->gesture.state == GESTURE_STATE_SWIPE) 1272 tp_gesture_handle_state_swipe(tp, time); 1273 1274 if (tp->gesture.state == GESTURE_STATE_PINCH) 1275 tp_gesture_handle_state_pinch(tp, time); 1276} 1277 1278static bool 1279tp_gesture_thumb_moved(struct tp_dispatch *tp) 1280{ 1281 struct tp_touch *thumb; 1282 struct phys_coords thumb_moved; 1283 double thumb_mm; 1284 1285 thumb = tp_thumb_get_touch(tp); 1286 if (!thumb) 1287 return false; 1288 1289 if (!tp_touch_active_for_gesture(tp, thumb)) 1290 return false; 1291 1292 thumb_moved = tp_gesture_mm_moved(tp, thumb); 1293 thumb_mm = hypot(thumb_moved.x, thumb_moved.y); 1294 return thumb_mm >= PINCH_DISAMBIGUATION_MOVE_THRESHOLD; 1295} 1296 1297void 1298tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time, 1299 bool ignore_motion) 1300{ 1301 if (tp->gesture.finger_count == 0) 1302 return; 1303 1304 /* When tap-and-dragging, force 1fg mode. On clickpads, if the 1305 * physical button is down, don't allow gestures unless the button 1306 * is held down by a *thumb*, specifically. 1307 */ 1308 if (tp_tap_dragging(tp) || 1309 (tp->buttons.is_clickpad && tp->buttons.state && 1310 tp->thumb.state == THUMB_STATE_FINGER)) { 1311 if (tp->gesture.state != GESTURE_STATE_POINTER_MOTION) { 1312 tp_gesture_cancel(tp, time); 1313 tp_gesture_handle_event(tp, 1314 GESTURE_EVENT_POINTER_MOTION, 1315 time); 1316 } 1317 tp->gesture.finger_count = 1; 1318 tp->gesture.finger_count_pending = 0; 1319 } 1320 1321 /* Don't send events when we're unsure in which mode we are */ 1322 if (tp->gesture.finger_count_pending) 1323 return; 1324 1325 /* When pinching, the thumb tends to move slower than the finger, 1326 * so we may suppress it too early. Give it some time to move. 1327 */ 1328 if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) && 1329 tp_gesture_thumb_moved(tp)) 1330 tp_thumb_reset(tp); 1331 1332 if (tp->gesture.finger_count <= 4) 1333 tp_gesture_post_gesture(tp, time, ignore_motion); 1334} 1335 1336void 1337tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) 1338{ 1339 if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG) 1340 return; 1341 1342 evdev_stop_scroll(tp->device, 1343 time, 1344 LIBINPUT_POINTER_AXIS_SOURCE_FINGER); 1345} 1346 1347static void 1348tp_gesture_end(struct tp_dispatch *tp, uint64_t time, bool cancelled) 1349{ 1350 enum tp_gesture_state state = tp->gesture.state; 1351 1352 if (!tp->gesture.started) { 1353 tp_gesture_handle_event(tp, GESTURE_EVENT_RESET, time); 1354 return; 1355 } 1356 1357 switch (state) { 1358 case GESTURE_STATE_NONE: 1359 case GESTURE_STATE_UNKNOWN: 1360 evdev_log_bug_libinput(tp->device, 1361 "%s in unknown gesture mode\n", 1362 __func__); 1363 break; 1364 case GESTURE_STATE_HOLD: 1365 case GESTURE_STATE_HOLD_AND_MOTION: 1366 gesture_notify_hold_end(&tp->device->base, time, 1367 tp->gesture.finger_count, cancelled); 1368 break; 1369 case GESTURE_STATE_SCROLL: 1370 tp_gesture_stop_twofinger_scroll(tp, time); 1371 break; 1372 case GESTURE_STATE_PINCH: 1373 gesture_notify_pinch_end(&tp->device->base, time, 1374 tp->gesture.finger_count, 1375 tp->gesture.prev_scale, 1376 cancelled); 1377 break; 1378 case GESTURE_STATE_SWIPE: 1379 gesture_notify_swipe_end(&tp->device->base, 1380 time, 1381 tp->gesture.finger_count, 1382 cancelled); 1383 break; 1384 case GESTURE_STATE_POINTER_MOTION: 1385 break; 1386 } 1387 1388 tp->gesture.started = false; 1389 tp_gesture_handle_event(tp, GESTURE_EVENT_RESET, time); 1390} 1391 1392void 1393tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time) 1394{ 1395 tp_gesture_end(tp, time, true); 1396} 1397 1398void 1399tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, uint64_t time) 1400{ 1401 if (tp->gesture.started && tp->gesture.state != GESTURE_STATE_HOLD) 1402 tp_gesture_end(tp, time, true); 1403} 1404 1405void 1406tp_gesture_stop(struct tp_dispatch *tp, uint64_t time) 1407{ 1408 tp_gesture_end(tp, time, false); 1409} 1410 1411static void 1412tp_gesture_finger_count_switch_timeout(uint64_t now, void *data) 1413{ 1414 struct tp_dispatch *tp = data; 1415 1416 if (!tp->gesture.finger_count_pending) 1417 return; 1418 1419 tp_gesture_cancel(tp, now); /* End current gesture */ 1420 tp->gesture.finger_count = tp->gesture.finger_count_pending; 1421 tp->gesture.finger_count_pending = 0; 1422} 1423 1424void 1425tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time) 1426{ 1427 unsigned int active_touches = 0; 1428 struct tp_touch *t; 1429 1430 tp_for_each_touch(tp, t) { 1431 if (tp_touch_active_for_gesture(tp, t)) 1432 active_touches++; 1433 } 1434 1435 if (active_touches != tp->gesture.finger_count) { 1436 /* If all fingers are lifted immediately end the gesture */ 1437 if (active_touches == 0) { 1438 tp_gesture_stop(tp, time); 1439 tp->gesture.finger_count = 0; 1440 tp->gesture.finger_count_pending = 0; 1441 /* Immediately switch to new mode to avoid initial latency */ 1442 } else if (!tp->gesture.started) { 1443 tp->gesture.finger_count = active_touches; 1444 tp->gesture.finger_count_pending = 0; 1445 /* If in UNKNOWN or POINTER_MOTION state, go back to 1446 * NONE to re-evaluate leftmost and rightmost touches 1447 */ 1448 if (tp->gesture.state == GESTURE_STATE_UNKNOWN || 1449 tp->gesture.state == GESTURE_STATE_POINTER_MOTION) { 1450 tp_gesture_handle_event(tp, 1451 GESTURE_EVENT_RESET, 1452 time); 1453 } 1454 /* Else debounce finger changes */ 1455 } else if (active_touches != tp->gesture.finger_count_pending) { 1456 tp->gesture.finger_count_pending = active_touches; 1457 libinput_timer_set(&tp->gesture.finger_count_switch_timer, 1458 time + DEFAULT_GESTURE_SWITCH_TIMEOUT); 1459 } 1460 } else { 1461 tp->gesture.finger_count_pending = 0; 1462 } 1463} 1464 1465static bool 1466tp_gesture_are_gestures_enabled(struct tp_dispatch *tp) 1467{ 1468 return (!tp->semi_mt && tp->num_slots > 1); 1469} 1470 1471static enum libinput_config_status 1472tp_gesture_set_hold_enabled(struct libinput_device *device, 1473 enum libinput_config_hold_state enabled) 1474{ 1475 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; 1476 struct tp_dispatch *tp = tp_dispatch(dispatch); 1477 1478 if (!tp_gesture_are_gestures_enabled(tp)) 1479 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 1480 1481 tp->gesture.hold_enabled = (enabled == LIBINPUT_CONFIG_HOLD_ENABLED); 1482 1483 return LIBINPUT_CONFIG_STATUS_SUCCESS; 1484} 1485 1486static enum libinput_config_hold_state 1487tp_gesture_is_hold_enabled(struct libinput_device *device) 1488{ 1489 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; 1490 struct tp_dispatch *tp = tp_dispatch(dispatch); 1491 1492 return tp->gesture.hold_enabled ? LIBINPUT_CONFIG_HOLD_ENABLED : 1493 LIBINPUT_CONFIG_HOLD_DISABLED; 1494} 1495 1496static enum libinput_config_hold_state 1497tp_gesture_get_hold_default(struct libinput_device *device) 1498{ 1499 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; 1500 struct tp_dispatch *tp = tp_dispatch(dispatch); 1501 1502 return tp_gesture_are_gestures_enabled(tp) ? 1503 LIBINPUT_CONFIG_HOLD_ENABLED : 1504 LIBINPUT_CONFIG_HOLD_DISABLED; 1505} 1506 1507void 1508tp_init_gesture(struct tp_dispatch *tp) 1509{ 1510 char timer_name[64]; 1511 1512 tp->gesture.config.set_hold_enabled = tp_gesture_set_hold_enabled; 1513 tp->gesture.config.get_hold_enabled = tp_gesture_is_hold_enabled; 1514 tp->gesture.config.get_hold_default = tp_gesture_get_hold_default; 1515 tp->device->base.config.gesture = &tp->gesture.config; 1516 1517 /* two-finger scrolling is always enabled, this flag just 1518 * decides whether we detect pinch. semi-mt devices are too 1519 * unreliable to do pinch gestures. */ 1520 tp->gesture.enabled = tp_gesture_are_gestures_enabled(tp); 1521 1522 tp->gesture.state = GESTURE_STATE_NONE; 1523 tp->gesture.hold_enabled = tp_gesture_are_gestures_enabled(tp); 1524 1525 snprintf(timer_name, 1526 sizeof(timer_name), 1527 "%s gestures", 1528 evdev_device_get_sysname(tp->device)); 1529 libinput_timer_init(&tp->gesture.finger_count_switch_timer, 1530 tp_libinput_context(tp), 1531 timer_name, 1532 tp_gesture_finger_count_switch_timeout, tp); 1533 1534 snprintf(timer_name, 1535 sizeof(timer_name), 1536 "%s hold", 1537 evdev_device_get_sysname(tp->device)); 1538 libinput_timer_init(&tp->gesture.hold_timer, 1539 tp_libinput_context(tp), 1540 timer_name, 1541 tp_gesture_hold_timeout, tp); 1542} 1543 1544void 1545tp_remove_gesture(struct tp_dispatch *tp) 1546{ 1547 libinput_timer_cancel(&tp->gesture.finger_count_switch_timer); 1548 libinput_timer_cancel(&tp->gesture.hold_timer); 1549} 1550