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
40 enum 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
60 static inline const char*
gesture_state_to_str(enum tp_gesture_state state)61 gesture_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
76 static inline const char*
gesture_event_to_str(enum gesture_event event)77 gesture_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
92 static struct device_float_coords
tp_get_touches_delta(struct tp_dispatch * tp,bool average)93 tp_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
126 static void
tp_gesture_init_scroll(struct tp_dispatch * tp)127 tp_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
138 static inline struct device_float_coords
tp_get_combined_touches_delta(struct tp_dispatch * tp)139 tp_get_combined_touches_delta(struct tp_dispatch *tp)
140 {
141 return tp_get_touches_delta(tp, false);
142 }
143
144 static inline struct device_float_coords
tp_get_average_touches_delta(struct tp_dispatch * tp)145 tp_get_average_touches_delta(struct tp_dispatch *tp)
146 {
147 return tp_get_touches_delta(tp, true);
148 }
149
150 static void
tp_gesture_start(struct tp_dispatch * tp,uint64_t time)151 tp_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
192 static struct device_float_coords
tp_get_raw_pointer_motion(struct tp_dispatch * tp)193 tp_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
206 static bool
tp_has_pending_pointer_motion(struct tp_dispatch * tp,uint64_t time)207 tp_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
223 static void
tp_gesture_post_pointer_motion(struct tp_dispatch * tp,uint64_t time)224 tp_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
243 static unsigned int
tp_gesture_get_active_touches(const struct tp_dispatch * tp,struct tp_touch ** touches,unsigned int count)244 tp_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
274 static inline int
tp_gesture_same_directions(int dir1,int dir2)275 tp_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
290 static struct phys_coords
tp_gesture_mm_moved(struct tp_dispatch * tp,struct tp_touch * t)291 tp_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
301 static uint32_t
tp_gesture_get_direction(struct tp_dispatch * tp,struct tp_touch * touch)302 tp_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
313 static void
tp_gesture_get_pinch_info(struct tp_dispatch * tp,double * distance,double * angle,struct device_float_coords * center)314 tp_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
332 static inline void
tp_gesture_init_pinch(struct tp_dispatch * tp)333 tp_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
342 static void
tp_gesture_set_scroll_buildup(struct tp_dispatch * tp)343 tp_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
357 static void
tp_gesture_apply_scroll_constraints(struct tp_dispatch * tp,struct device_float_coords * raw,struct normalized_coords * delta,uint64_t time)358 tp_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
485 static inline void
log_gesture_bug(struct tp_dispatch * tp,enum gesture_event event)486 log_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
494 static bool
tp_gesture_is_quick_hold(struct tp_dispatch * tp)495 tp_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
505 static bool
tp_gesture_use_hold_timer(struct tp_dispatch * tp)506 tp_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
540 static void
tp_gesture_set_hold_timer(struct tp_dispatch * tp,uint64_t time)541 tp_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
557 static void
tp_gesture_none_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)558 tp_gesture_none_handle_event(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
586 static void
tp_gesture_unknown_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)587 tp_gesture_unknown_handle_event(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
626 static void
tp_gesture_hold_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)627 tp_gesture_hold_handle_event(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
664 static void
tp_gesture_hold_and_motion_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)665 tp_gesture_hold_and_motion_handle_event(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
689 static void
tp_gesture_pointer_motion_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)690 tp_gesture_pointer_motion_handle_event(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
727 static void
tp_gesture_scroll_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)728 tp_gesture_scroll_handle_event(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_HOLD_AND_MOTION:
738 case GESTURE_EVENT_FINGER_DETECTED:
739 case GESTURE_EVENT_HOLD_TIMEOUT:
740 case GESTURE_EVENT_POINTER_MOTION:
741 case GESTURE_EVENT_SCROLL:
742 case GESTURE_EVENT_SWIPE:
743 case GESTURE_EVENT_PINCH:
744 log_gesture_bug(tp, event);
745 break;
746 }
747 }
748
749 static void
tp_gesture_pinch_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)750 tp_gesture_pinch_handle_event(struct tp_dispatch *tp,
751 enum gesture_event event,
752 uint64_t time)
753 {
754 switch(event) {
755 case GESTURE_EVENT_RESET:
756 libinput_timer_cancel(&tp->gesture.hold_timer);
757 tp->gesture.state = GESTURE_STATE_NONE;
758 break;
759 case GESTURE_EVENT_HOLD_AND_MOTION:
760 case GESTURE_EVENT_FINGER_DETECTED:
761 case GESTURE_EVENT_HOLD_TIMEOUT:
762 case GESTURE_EVENT_POINTER_MOTION:
763 case GESTURE_EVENT_SCROLL:
764 case GESTURE_EVENT_SWIPE:
765 case GESTURE_EVENT_PINCH:
766 log_gesture_bug(tp, event);
767 break;
768 }
769 }
770
771 static void
tp_gesture_swipe_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)772 tp_gesture_swipe_handle_event(struct tp_dispatch *tp,
773 enum gesture_event event,
774 uint64_t time)
775 {
776 switch(event) {
777 case GESTURE_EVENT_RESET:
778 libinput_timer_cancel(&tp->gesture.hold_timer);
779 tp->gesture.state = GESTURE_STATE_NONE;
780 break;
781 case GESTURE_EVENT_HOLD_AND_MOTION:
782 case GESTURE_EVENT_FINGER_DETECTED:
783 case GESTURE_EVENT_HOLD_TIMEOUT:
784 case GESTURE_EVENT_POINTER_MOTION:
785 case GESTURE_EVENT_SCROLL:
786 case GESTURE_EVENT_SWIPE:
787 case GESTURE_EVENT_PINCH:
788 log_gesture_bug(tp, event);
789 break;
790 }
791 }
792
793 static void
tp_gesture_handle_event(struct tp_dispatch * tp,enum gesture_event event,uint64_t time)794 tp_gesture_handle_event(struct tp_dispatch *tp,
795 enum gesture_event event,
796 uint64_t time)
797 {
798 enum tp_gesture_state oldstate;
799
800 oldstate = tp->gesture.state;
801
802 switch(tp->gesture.state) {
803 case GESTURE_STATE_NONE:
804 tp_gesture_none_handle_event(tp, event, time);
805 break;
806 case GESTURE_STATE_UNKNOWN:
807 tp_gesture_unknown_handle_event(tp, event, time);
808 break;
809 case GESTURE_STATE_HOLD:
810 tp_gesture_hold_handle_event(tp, event, time);
811 break;
812 case GESTURE_STATE_HOLD_AND_MOTION:
813 tp_gesture_hold_and_motion_handle_event(tp, event, time);
814 break;
815 case GESTURE_STATE_POINTER_MOTION:
816 tp_gesture_pointer_motion_handle_event(tp, event, time);
817 break;
818 case GESTURE_STATE_SCROLL:
819 tp_gesture_scroll_handle_event(tp, event, time);
820 break;
821 case GESTURE_STATE_PINCH:
822 tp_gesture_pinch_handle_event(tp, event, time);
823 break;
824 case GESTURE_STATE_SWIPE:
825 tp_gesture_swipe_handle_event(tp, event, time);
826 break;
827 }
828
829 if (oldstate != tp->gesture.state) {
830 evdev_log_debug(tp->device,
831 "gesture state %s → %s → %s\n",
832 gesture_state_to_str(oldstate),
833 gesture_event_to_str(event),
834 gesture_state_to_str(tp->gesture.state));
835 }
836 }
837
838 static void
tp_gesture_hold_timeout(uint64_t now,void * data)839 tp_gesture_hold_timeout(uint64_t now, void *data)
840 {
841 struct tp_dispatch *tp = data;
842
843 if (tp_tap_dragging_or_double_tapping(tp) || tp_tap_dragging(tp))
844 return;
845
846 tp_gesture_handle_event(tp, GESTURE_EVENT_HOLD_TIMEOUT, now);
847 }
848
849 void
tp_gesture_tap_timeout(struct tp_dispatch * tp,uint64_t time)850 tp_gesture_tap_timeout(struct tp_dispatch *tp, uint64_t time)
851 {
852 if (!tp->gesture.hold_enabled)
853 return;
854
855 if (!tp_gesture_is_quick_hold(tp))
856 tp_gesture_handle_event(tp, GESTURE_EVENT_HOLD_TIMEOUT, time);
857 }
858
859 static void
tp_gesture_detect_motion_gestures(struct tp_dispatch * tp,uint64_t time)860 tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, uint64_t time)
861 {
862 struct tp_touch *first = tp->gesture.touches[0],
863 *second = tp->gesture.touches[1],
864 *thumb;
865 uint32_t dir1, dir2;
866 struct device_coords delta;
867 struct phys_coords first_moved, second_moved, distance_mm;
868 double first_mm, second_mm; /* movement since gesture start in mm */
869 double thumb_mm, finger_mm;
870 double min_move = 1.5; /* min movement threshold in mm - count this touch */
871 double max_move = 4.0; /* max movement threshold in mm - ignore other touch */
872 bool is_hold_and_motion;
873
874 first_moved = tp_gesture_mm_moved(tp, first);
875 first_mm = hypot(first_moved.x, first_moved.y);
876
877 if (tp->gesture.finger_count == 1) {
878 if (!tp_has_pending_pointer_motion(tp, time))
879 return;
880
881 is_hold_and_motion = (first_mm < HOLD_AND_MOTION_THRESHOLD);
882
883 if (tp->gesture.state == GESTURE_STATE_HOLD &&
884 is_hold_and_motion) {
885 tp_gesture_handle_event(tp,
886 GESTURE_EVENT_HOLD_AND_MOTION,
887 time);
888 return;
889 }
890
891 if (tp->gesture.state == GESTURE_STATE_HOLD_AND_MOTION &&
892 is_hold_and_motion)
893 return;
894
895 tp_gesture_handle_event(tp,
896 GESTURE_EVENT_POINTER_MOTION,
897 time);
898 return;
899 }
900
901 /* If we have more fingers than slots, we don't know where the
902 * fingers are. Default to swipe */
903 if (tp->gesture.enabled && tp->gesture.finger_count > 2 &&
904 tp->gesture.finger_count > tp->num_slots) {
905 tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE, time);
906 return;
907 }
908
909 /* Need more margin for error when there are more fingers */
910 max_move += 2.0 * (tp->gesture.finger_count - 2);
911 min_move += 0.5 * (tp->gesture.finger_count - 2);
912
913 second_moved = tp_gesture_mm_moved(tp, second);
914 second_mm = hypot(second_moved.x, second_moved.y);
915
916 delta.x = abs(first->point.x - second->point.x);
917 delta.y = abs(first->point.y - second->point.y);
918 distance_mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
919
920 /* If both touches moved less than a mm, we cannot decide yet */
921 if (first_mm < 1 && second_mm < 1)
922 return;
923
924 /* Pick the thumb as the lowest point on the touchpad */
925 if (first->point.y > second->point.y) {
926 thumb = first;
927 thumb_mm = first_mm;
928 finger_mm = second_mm;
929 } else {
930 thumb = second;
931 thumb_mm = second_mm;
932 finger_mm = first_mm;
933 }
934
935 /* If both touches are within 7mm vertically and 40mm horizontally
936 * past the timeout, assume scroll/swipe */
937 if ((!tp->gesture.enabled ||
938 (distance_mm.x < 40.0 && distance_mm.y < 7.0)) &&
939 time > (tp->gesture.initial_time + DEFAULT_GESTURE_SWIPE_TIMEOUT)) {
940 if (tp->gesture.finger_count == 2)
941 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time);
942 else
943 tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE, time);
944
945 return;
946 }
947
948 /* If one touch exceeds the max_move threshold while the other has not
949 * yet passed the min_move threshold, there is either a resting thumb,
950 * or the user is doing "one-finger-scroll," where one touch stays in
951 * place while the other moves.
952 */
953 if (first_mm >= max_move || second_mm >= max_move) {
954 /* If thumb detection is enabled, and thumb is still while
955 * finger moves, cancel gestures and mark lower as thumb.
956 * This applies to all gestures (2, 3, 4+ fingers), but allows
957 * more thumb motion on >2 finger gestures during detection.
958 */
959 if (tp->thumb.detect_thumbs && thumb_mm < min_move) {
960 tp_thumb_suppress(tp, thumb);
961 tp_gesture_cancel(tp, time);
962 return;
963 }
964
965 /* If gestures detection is disabled, or if finger is still
966 * while thumb moves, assume this is "one-finger scrolling."
967 * This applies only to 2-finger gestures.
968 */
969 if ((!tp->gesture.enabled || finger_mm < min_move) &&
970 tp->gesture.finger_count == 2) {
971 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time);
972 return;
973 }
974
975 /* If more than 2 fingers are involved, and the thumb moves
976 * while the fingers stay still, assume a pinch if eligible.
977 */
978 if (finger_mm < min_move &&
979 tp->gesture.finger_count > 2 &&
980 tp->gesture.enabled &&
981 tp->thumb.pinch_eligible) {
982 tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH, time);
983 return;
984 }
985 }
986
987 /* If either touch is still below the min_move threshold, we can't
988 * tell what kind of gesture this is.
989 */
990 if ((first_mm < min_move) || (second_mm < min_move))
991 return;
992
993 /* Both touches have exceeded the min_move threshold, so we have a
994 * valid gesture. Update gesture initial time and get directions so
995 * we know if it's a pinch or swipe/scroll.
996 */
997 dir1 = tp_gesture_get_direction(tp, first);
998 dir2 = tp_gesture_get_direction(tp, second);
999
1000 /* If we can't accurately detect pinches, or if the touches are moving
1001 * the same way, this is a scroll or swipe.
1002 */
1003 if (tp->gesture.finger_count > tp->num_slots ||
1004 tp_gesture_same_directions(dir1, dir2)) {
1005 if (tp->gesture.finger_count == 2) {
1006 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time);
1007 return;
1008 }
1009
1010 if (tp->gesture.enabled) {
1011 tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE, time);
1012 return;
1013 }
1014 }
1015
1016 /* If the touches are moving away from each other, this is a pinch */
1017 tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH, time);
1018 }
1019
1020 static bool
tp_gesture_is_pinch(struct tp_dispatch * tp)1021 tp_gesture_is_pinch(struct tp_dispatch *tp)
1022 {
1023 struct tp_touch *first = tp->gesture.touches[0],
1024 *second = tp->gesture.touches[1];
1025 uint32_t dir1, dir2;
1026 struct phys_coords first_moved, second_moved;
1027 double first_mm, second_mm;
1028
1029 dir1 = tp_gesture_get_direction(tp, first);
1030 dir2 = tp_gesture_get_direction(tp, second);
1031 if (tp_gesture_same_directions(dir1, dir2))
1032 return false;
1033
1034 first_moved = tp_gesture_mm_moved(tp, first);
1035 first_mm = hypot(first_moved.x, first_moved.y);
1036 if (first_mm < PINCH_DISAMBIGUATION_MOVE_THRESHOLD)
1037 return false;
1038
1039 second_moved = tp_gesture_mm_moved(tp, second);
1040 second_mm = hypot(second_moved.x, second_moved.y);
1041 if (second_mm < PINCH_DISAMBIGUATION_MOVE_THRESHOLD)
1042 return false;
1043
1044 return true;
1045 }
1046
1047 static void
tp_gesture_handle_state_none(struct tp_dispatch * tp,uint64_t time)1048 tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time)
1049 {
1050 struct tp_touch *first, *second;
1051 struct tp_touch *touches[4];
1052 unsigned int ntouches;
1053 unsigned int i;
1054
1055 ntouches = tp_gesture_get_active_touches(tp, touches, 4);
1056
1057 first = touches[0];
1058 second = touches[1];
1059
1060 if (ntouches == 0)
1061 return;
1062
1063 if (ntouches == 1) {
1064 first->gesture.initial = first->point;
1065 tp->gesture.touches[0] = first;
1066
1067 tp_gesture_handle_event(tp,
1068 GESTURE_EVENT_FINGER_DETECTED,
1069 time);
1070 return;
1071 }
1072
1073 if (!tp->gesture.enabled) {
1074 if (ntouches == 2)
1075 tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL, time);
1076
1077 return;
1078 }
1079
1080 /* For 3+ finger gestures, we only really need to track two touches.
1081 * The human hand's finger arrangement means that for a pinch, the
1082 * bottom-most touch will always be the thumb, and the top-most touch
1083 * will always be one of the fingers.
1084 *
1085 * For 3+ finger swipes, the fingers will likely (but not necessarily)
1086 * be in a horizontal line. They all move together, regardless, so it
1087 * doesn't really matter which two of those touches we track.
1088 *
1089 * Tracking top and bottom is a change from previous versions, where
1090 * we tracked leftmost and rightmost. This change enables:
1091 *
1092 * - More accurate pinch detection if thumb is near the center
1093 * - Better resting-thumb detection while two-finger scrolling
1094 * - On capable hardware, allow 3- or 4-finger swipes with resting
1095 * thumb or held-down clickpad
1096 */
1097 if (ntouches > 2) {
1098 second = touches[0];
1099
1100 for (i = 1; i < ntouches && i < tp->num_slots; i++) {
1101 if (touches[i]->point.y < first->point.y)
1102 first = touches[i];
1103 else if (touches[i]->point.y >= second->point.y)
1104 second = touches[i];
1105 }
1106
1107 if (first == second)
1108 return;
1109
1110 }
1111
1112 tp->gesture.initial_time = time;
1113 first->gesture.initial = first->point;
1114 second->gesture.initial = second->point;
1115 tp->gesture.touches[0] = first;
1116 tp->gesture.touches[1] = second;
1117
1118 tp_gesture_handle_event(tp, GESTURE_EVENT_FINGER_DETECTED, time);
1119 }
1120
1121 static void
tp_gesture_handle_state_unknown(struct tp_dispatch * tp,uint64_t time,bool ignore_motion)1122 tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time,
1123 bool ignore_motion)
1124 {
1125 if (!ignore_motion)
1126 tp_gesture_detect_motion_gestures(tp, time);
1127 }
1128
1129 static void
tp_gesture_handle_state_hold(struct tp_dispatch * tp,uint64_t time,bool ignore_motion)1130 tp_gesture_handle_state_hold(struct tp_dispatch *tp, uint64_t time,
1131 bool ignore_motion)
1132 {
1133 tp_gesture_start(tp, time);
1134
1135 if (!ignore_motion)
1136 tp_gesture_detect_motion_gestures(tp, time);
1137 }
1138
1139 static void
tp_gesture_handle_state_hold_and_pointer_motion(struct tp_dispatch * tp,uint64_t time)1140 tp_gesture_handle_state_hold_and_pointer_motion(struct tp_dispatch *tp, uint64_t time)
1141 {
1142 if (tp->queued & TOUCHPAD_EVENT_MOTION)
1143 tp_gesture_post_pointer_motion(tp, time);
1144
1145 tp_gesture_detect_motion_gestures(tp, time);
1146 }
1147
1148 static void
tp_gesture_handle_state_pointer_motion(struct tp_dispatch * tp,uint64_t time)1149 tp_gesture_handle_state_pointer_motion(struct tp_dispatch *tp, uint64_t time)
1150 {
1151 if (tp->queued & TOUCHPAD_EVENT_MOTION)
1152 tp_gesture_post_pointer_motion(tp, time);
1153 }
1154
1155 static void
tp_gesture_handle_state_scroll(struct tp_dispatch * tp,uint64_t time)1156 tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
1157 {
1158 struct device_float_coords raw;
1159 struct normalized_coords delta;
1160
1161 if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
1162 return;
1163
1164 /* We may confuse a pinch for a scroll initially,
1165 * allow ourselves to correct our guess.
1166 */
1167 if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) &&
1168 tp_gesture_is_pinch(tp)) {
1169 tp_gesture_cancel(tp, time);
1170 tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH, time);
1171 return;
1172 }
1173
1174 raw = tp_get_average_touches_delta(tp);
1175
1176 /* scroll is not accelerated */
1177 delta = tp_filter_motion_unaccelerated(tp, &raw, time);
1178
1179 if (normalized_is_zero(delta))
1180 return;
1181
1182 tp_gesture_start(tp, time);
1183 tp_gesture_apply_scroll_constraints(tp, &raw, &delta, time);
1184 evdev_post_scroll(tp->device,
1185 time,
1186 LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
1187 &delta);
1188 }
1189
1190 static void
tp_gesture_handle_state_swipe(struct tp_dispatch * tp,uint64_t time)1191 tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time)
1192 {
1193 struct device_float_coords raw;
1194 struct normalized_coords delta, unaccel;
1195
1196 raw = tp_get_average_touches_delta(tp);
1197 delta = tp_filter_motion(tp, &raw, time);
1198
1199 if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
1200 unaccel = tp_filter_motion_unaccelerated(tp, &raw, time);
1201 tp_gesture_start(tp, time);
1202 gesture_notify_swipe(&tp->device->base, time,
1203 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
1204 tp->gesture.finger_count,
1205 &delta, &unaccel);
1206 }
1207 }
1208
1209 static void
tp_gesture_handle_state_pinch(struct tp_dispatch * tp,uint64_t time)1210 tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
1211 {
1212 double angle, angle_delta, distance, scale;
1213 struct device_float_coords center, fdelta;
1214 struct normalized_coords delta, unaccel;
1215
1216 tp_gesture_get_pinch_info(tp, &distance, &angle, ¢er);
1217
1218 scale = distance / tp->gesture.initial_distance;
1219
1220 angle_delta = angle - tp->gesture.angle;
1221 tp->gesture.angle = angle;
1222 if (angle_delta > 180.0)
1223 angle_delta -= 360.0;
1224 else if (angle_delta < -180.0)
1225 angle_delta += 360.0;
1226
1227 fdelta = device_float_delta(center, tp->gesture.center);
1228 tp->gesture.center = center;
1229
1230 delta = tp_filter_motion(tp, &fdelta, time);
1231
1232 if (normalized_is_zero(delta) && device_float_is_zero(fdelta) &&
1233 scale == tp->gesture.prev_scale && angle_delta == 0.0)
1234 return;
1235
1236 unaccel = tp_filter_motion_unaccelerated(tp, &fdelta, time);
1237 tp_gesture_start(tp, time);
1238 gesture_notify_pinch(&tp->device->base, time,
1239 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1240 tp->gesture.finger_count,
1241 &delta, &unaccel, scale, angle_delta);
1242
1243 tp->gesture.prev_scale = scale;
1244 }
1245
1246 static void
tp_gesture_post_gesture(struct tp_dispatch * tp,uint64_t time,bool ignore_motion)1247 tp_gesture_post_gesture(struct tp_dispatch *tp, uint64_t time,
1248 bool ignore_motion)
1249 {
1250 if (tp->gesture.state == GESTURE_STATE_NONE)
1251 tp_gesture_handle_state_none(tp, time);
1252
1253 if (tp->gesture.state == GESTURE_STATE_UNKNOWN)
1254 tp_gesture_handle_state_unknown(tp, time, ignore_motion);
1255
1256 if (tp->gesture.state == GESTURE_STATE_HOLD)
1257 tp_gesture_handle_state_hold(tp, time, ignore_motion);
1258
1259 if (tp->gesture.state == GESTURE_STATE_POINTER_MOTION)
1260 tp_gesture_handle_state_pointer_motion(tp, time);
1261
1262 if (tp->gesture.state == GESTURE_STATE_HOLD_AND_MOTION)
1263 tp_gesture_handle_state_hold_and_pointer_motion(tp, time);
1264
1265 if (tp->gesture.state == GESTURE_STATE_SCROLL)
1266 tp_gesture_handle_state_scroll(tp, time);
1267
1268 if (tp->gesture.state == GESTURE_STATE_SWIPE)
1269 tp_gesture_handle_state_swipe(tp, time);
1270
1271 if (tp->gesture.state == GESTURE_STATE_PINCH)
1272 tp_gesture_handle_state_pinch(tp, time);
1273 }
1274
1275 static bool
tp_gesture_thumb_moved(struct tp_dispatch * tp)1276 tp_gesture_thumb_moved(struct tp_dispatch *tp)
1277 {
1278 struct tp_touch *thumb;
1279 struct phys_coords thumb_moved;
1280 double thumb_mm;
1281
1282 thumb = tp_thumb_get_touch(tp);
1283 if (!thumb)
1284 return false;
1285
1286 thumb_moved = tp_gesture_mm_moved(tp, thumb);
1287 thumb_mm = hypot(thumb_moved.x, thumb_moved.y);
1288 return thumb_mm >= PINCH_DISAMBIGUATION_MOVE_THRESHOLD;
1289 }
1290
1291 void
tp_gesture_post_events(struct tp_dispatch * tp,uint64_t time,bool ignore_motion)1292 tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time,
1293 bool ignore_motion)
1294 {
1295 if (tp->gesture.finger_count == 0)
1296 return;
1297
1298 /* When tap-and-dragging, force 1fg mode. On clickpads, if the
1299 * physical button is down, don't allow gestures unless the button
1300 * is held down by a *thumb*, specifically.
1301 */
1302 if (tp_tap_dragging(tp) ||
1303 (tp->buttons.is_clickpad && tp->buttons.state &&
1304 tp->thumb.state == THUMB_STATE_FINGER)) {
1305 if (tp->gesture.state != GESTURE_STATE_POINTER_MOTION) {
1306 tp_gesture_cancel(tp, time);
1307 tp_gesture_handle_event(tp,
1308 GESTURE_EVENT_POINTER_MOTION,
1309 time);
1310 }
1311 tp->gesture.finger_count = 1;
1312 tp->gesture.finger_count_pending = 0;
1313 }
1314
1315 /* Don't send events when we're unsure in which mode we are */
1316 if (tp->gesture.finger_count_pending)
1317 return;
1318
1319 /* When pinching, the thumb tends to move slower than the finger,
1320 * so we may suppress it too early. Give it some time to move.
1321 */
1322 if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) &&
1323 tp_gesture_thumb_moved(tp))
1324 tp_thumb_reset(tp);
1325
1326 if (tp->gesture.finger_count <= 4)
1327 tp_gesture_post_gesture(tp, time, ignore_motion);
1328 }
1329
1330 void
tp_gesture_stop_twofinger_scroll(struct tp_dispatch * tp,uint64_t time)1331 tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
1332 {
1333 if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
1334 return;
1335
1336 evdev_stop_scroll(tp->device,
1337 time,
1338 LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
1339 }
1340
1341 static void
tp_gesture_end(struct tp_dispatch * tp,uint64_t time,bool cancelled)1342 tp_gesture_end(struct tp_dispatch *tp, uint64_t time, bool cancelled)
1343 {
1344 enum tp_gesture_state state = tp->gesture.state;
1345
1346 if (!tp->gesture.started) {
1347 tp_gesture_handle_event(tp, GESTURE_EVENT_RESET, time);
1348 return;
1349 }
1350
1351 switch (state) {
1352 case GESTURE_STATE_NONE:
1353 case GESTURE_STATE_UNKNOWN:
1354 evdev_log_bug_libinput(tp->device,
1355 "%s in unknown gesture mode\n",
1356 __func__);
1357 break;
1358 case GESTURE_STATE_HOLD:
1359 case GESTURE_STATE_HOLD_AND_MOTION:
1360 gesture_notify_hold_end(&tp->device->base, time,
1361 tp->gesture.finger_count, cancelled);
1362 break;
1363 case GESTURE_STATE_SCROLL:
1364 tp_gesture_stop_twofinger_scroll(tp, time);
1365 break;
1366 case GESTURE_STATE_PINCH:
1367 gesture_notify_pinch_end(&tp->device->base, time,
1368 tp->gesture.finger_count,
1369 tp->gesture.prev_scale,
1370 cancelled);
1371 break;
1372 case GESTURE_STATE_SWIPE:
1373 gesture_notify_swipe_end(&tp->device->base,
1374 time,
1375 tp->gesture.finger_count,
1376 cancelled);
1377 break;
1378 case GESTURE_STATE_POINTER_MOTION:
1379 break;
1380 }
1381
1382 tp->gesture.started = false;
1383 tp_gesture_handle_event(tp, GESTURE_EVENT_RESET, time);
1384 }
1385
1386 void
tp_gesture_cancel(struct tp_dispatch * tp,uint64_t time)1387 tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time)
1388 {
1389 tp_gesture_end(tp, time, true);
1390 }
1391
1392 void
tp_gesture_cancel_motion_gestures(struct tp_dispatch * tp,uint64_t time)1393 tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, uint64_t time)
1394 {
1395 if (tp->gesture.started && tp->gesture.state != GESTURE_STATE_HOLD)
1396 tp_gesture_end(tp, time, true);
1397 }
1398
1399 void
tp_gesture_stop(struct tp_dispatch * tp,uint64_t time)1400 tp_gesture_stop(struct tp_dispatch *tp, uint64_t time)
1401 {
1402 tp_gesture_end(tp, time, false);
1403 }
1404
1405 static void
tp_gesture_finger_count_switch_timeout(uint64_t now,void * data)1406 tp_gesture_finger_count_switch_timeout(uint64_t now, void *data)
1407 {
1408 struct tp_dispatch *tp = data;
1409
1410 if (!tp->gesture.finger_count_pending)
1411 return;
1412
1413 tp_gesture_cancel(tp, now); /* End current gesture */
1414 tp->gesture.finger_count = tp->gesture.finger_count_pending;
1415 tp->gesture.finger_count_pending = 0;
1416 }
1417
1418 void
tp_gesture_handle_state(struct tp_dispatch * tp,uint64_t time)1419 tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time)
1420 {
1421 unsigned int active_touches = 0;
1422 struct tp_touch *t;
1423
1424 tp_for_each_touch(tp, t) {
1425 if (tp_touch_active_for_gesture(tp, t))
1426 active_touches++;
1427 }
1428
1429 if (active_touches != tp->gesture.finger_count) {
1430 /* If all fingers are lifted immediately end the gesture */
1431 if (active_touches == 0) {
1432 tp_gesture_stop(tp, time);
1433 tp->gesture.finger_count = 0;
1434 tp->gesture.finger_count_pending = 0;
1435 /* Immediately switch to new mode to avoid initial latency */
1436 } else if (!tp->gesture.started) {
1437 tp->gesture.finger_count = active_touches;
1438 tp->gesture.finger_count_pending = 0;
1439 /* If in UNKNOWN or POINTER_MOTION state, go back to
1440 * NONE to re-evaluate leftmost and rightmost touches
1441 */
1442 if (tp->gesture.state == GESTURE_STATE_UNKNOWN ||
1443 tp->gesture.state == GESTURE_STATE_POINTER_MOTION) {
1444 tp_gesture_handle_event(tp,
1445 GESTURE_EVENT_RESET,
1446 time);
1447 }
1448 /* Else debounce finger changes */
1449 } else if (active_touches != tp->gesture.finger_count_pending) {
1450 tp->gesture.finger_count_pending = active_touches;
1451 libinput_timer_set(&tp->gesture.finger_count_switch_timer,
1452 time + DEFAULT_GESTURE_SWITCH_TIMEOUT);
1453 }
1454 } else {
1455 tp->gesture.finger_count_pending = 0;
1456 }
1457 }
1458
1459 static bool
tp_gesture_are_gestures_enabled(struct tp_dispatch * tp)1460 tp_gesture_are_gestures_enabled(struct tp_dispatch *tp)
1461 {
1462 return (!tp->semi_mt && tp->num_slots > 1);
1463 }
1464
1465 static enum libinput_config_status
tp_gesture_set_hold_enabled(struct libinput_device * device,enum libinput_config_hold_state enabled)1466 tp_gesture_set_hold_enabled(struct libinput_device *device,
1467 enum libinput_config_hold_state enabled)
1468 {
1469 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1470 struct tp_dispatch *tp = tp_dispatch(dispatch);
1471
1472 if (!tp_gesture_are_gestures_enabled(tp))
1473 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
1474
1475 tp->gesture.hold_enabled = (enabled == LIBINPUT_CONFIG_HOLD_ENABLED);
1476
1477 return LIBINPUT_CONFIG_STATUS_SUCCESS;
1478 }
1479
1480 static enum libinput_config_hold_state
tp_gesture_is_hold_enabled(struct libinput_device * device)1481 tp_gesture_is_hold_enabled(struct libinput_device *device)
1482 {
1483 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1484 struct tp_dispatch *tp = tp_dispatch(dispatch);
1485
1486 return tp->gesture.hold_enabled ? LIBINPUT_CONFIG_HOLD_ENABLED :
1487 LIBINPUT_CONFIG_HOLD_DISABLED;
1488 }
1489
1490 static enum libinput_config_hold_state
tp_gesture_get_hold_default(struct libinput_device * device)1491 tp_gesture_get_hold_default(struct libinput_device *device)
1492 {
1493 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1494 struct tp_dispatch *tp = tp_dispatch(dispatch);
1495
1496 return tp_gesture_are_gestures_enabled(tp) ?
1497 LIBINPUT_CONFIG_HOLD_ENABLED :
1498 LIBINPUT_CONFIG_HOLD_DISABLED;
1499 }
1500
1501 void
tp_init_gesture(struct tp_dispatch * tp)1502 tp_init_gesture(struct tp_dispatch *tp)
1503 {
1504 char timer_name[64];
1505
1506 tp->gesture.config.set_hold_enabled = tp_gesture_set_hold_enabled;
1507 tp->gesture.config.get_hold_enabled = tp_gesture_is_hold_enabled;
1508 tp->gesture.config.get_hold_default = tp_gesture_get_hold_default;
1509 tp->device->base.config.gesture = &tp->gesture.config;
1510
1511 /* two-finger scrolling is always enabled, this flag just
1512 * decides whether we detect pinch. semi-mt devices are too
1513 * unreliable to do pinch gestures. */
1514 tp->gesture.enabled = tp_gesture_are_gestures_enabled(tp);
1515
1516 tp->gesture.state = GESTURE_STATE_NONE;
1517 tp->gesture.hold_enabled = tp_gesture_are_gestures_enabled(tp);
1518
1519 snprintf(timer_name,
1520 sizeof(timer_name),
1521 "%s gestures",
1522 evdev_device_get_sysname(tp->device));
1523 libinput_timer_init(&tp->gesture.finger_count_switch_timer,
1524 tp_libinput_context(tp),
1525 timer_name,
1526 tp_gesture_finger_count_switch_timeout, tp);
1527
1528 snprintf(timer_name,
1529 sizeof(timer_name),
1530 "%s hold",
1531 evdev_device_get_sysname(tp->device));
1532 libinput_timer_init(&tp->gesture.hold_timer,
1533 tp_libinput_context(tp),
1534 timer_name,
1535 tp_gesture_hold_timeout, tp);
1536 }
1537
1538 void
tp_remove_gesture(struct tp_dispatch * tp)1539 tp_remove_gesture(struct tp_dispatch *tp)
1540 {
1541 libinput_timer_cancel(&tp->gesture.finger_count_switch_timer);
1542 libinput_timer_cancel(&tp->gesture.hold_timer);
1543 }
1544