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 DEFAULT_GESTURE_SWITCH_TIMEOUT ms2us(100)
32 #define DEFAULT_GESTURE_SWIPE_TIMEOUT ms2us(150)
33 #define DEFAULT_GESTURE_PINCH_TIMEOUT ms2us(150)
34
35 static inline const char*
gesture_state_to_str(enum tp_gesture_state state)36 gesture_state_to_str(enum tp_gesture_state state)
37 {
38 switch (state) {
39 CASE_RETURN_STRING(GESTURE_STATE_NONE);
40 CASE_RETURN_STRING(GESTURE_STATE_UNKNOWN);
41 CASE_RETURN_STRING(GESTURE_STATE_SCROLL);
42 CASE_RETURN_STRING(GESTURE_STATE_PINCH);
43 CASE_RETURN_STRING(GESTURE_STATE_SWIPE);
44 }
45 return NULL;
46 }
47
48 static struct device_float_coords
tp_get_touches_delta(struct tp_dispatch * tp,bool average)49 tp_get_touches_delta(struct tp_dispatch *tp, bool average)
50 {
51 struct tp_touch *t;
52 unsigned int i, nactive = 0;
53 struct device_float_coords delta = {0.0, 0.0};
54
55 for (i = 0; i < tp->num_slots; i++) {
56 t = &tp->touches[i];
57
58 if (!tp_touch_active_for_gesture(tp, t))
59 continue;
60
61 nactive++;
62
63 if (t->dirty) {
64 struct device_coords d;
65
66 d = tp_get_delta(t);
67
68 delta.x += d.x;
69 delta.y += d.y;
70 }
71 }
72
73 if (!average || nactive == 0)
74 return delta;
75
76 delta.x /= nactive;
77 delta.y /= nactive;
78
79 return delta;
80 }
81
82 static void
tp_gesture_init_scroll(struct tp_dispatch * tp)83 tp_gesture_init_scroll(struct tp_dispatch *tp)
84 {
85 struct phys_coords zero = {0.0, 0.0};
86 tp->scroll.active.h = false;
87 tp->scroll.active.v = false;
88 tp->scroll.duration.h = 0;
89 tp->scroll.duration.v = 0;
90 tp->scroll.vector = zero;
91 tp->scroll.time_prev = 0;
92 }
93
94 static inline struct device_float_coords
tp_get_combined_touches_delta(struct tp_dispatch * tp)95 tp_get_combined_touches_delta(struct tp_dispatch *tp)
96 {
97 return tp_get_touches_delta(tp, false);
98 }
99
100 static inline struct device_float_coords
tp_get_average_touches_delta(struct tp_dispatch * tp)101 tp_get_average_touches_delta(struct tp_dispatch *tp)
102 {
103 return tp_get_touches_delta(tp, true);
104 }
105
106 static void
tp_gesture_start(struct tp_dispatch * tp,uint64_t time)107 tp_gesture_start(struct tp_dispatch *tp, uint64_t time)
108 {
109 const struct normalized_coords zero = { 0.0, 0.0 };
110
111 if (tp->gesture.started)
112 return;
113
114 switch (tp->gesture.state) {
115 case GESTURE_STATE_NONE:
116 case GESTURE_STATE_UNKNOWN:
117 evdev_log_bug_libinput(tp->device,
118 "%s in unknown gesture mode\n",
119 __func__);
120 break;
121 case GESTURE_STATE_SCROLL:
122 tp_gesture_init_scroll(tp);
123 break;
124 case GESTURE_STATE_PINCH:
125 gesture_notify_pinch(&tp->device->base, time,
126 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
127 tp->gesture.finger_count,
128 &zero, &zero, 1.0, 0.0);
129 break;
130 case GESTURE_STATE_SWIPE:
131 gesture_notify_swipe(&tp->device->base, time,
132 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
133 tp->gesture.finger_count,
134 &zero, &zero);
135 break;
136 }
137
138 tp->gesture.started = true;
139 }
140
141 static void
tp_gesture_post_pointer_motion(struct tp_dispatch * tp,uint64_t time)142 tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
143 {
144 struct device_float_coords raw;
145 struct normalized_coords delta;
146
147 /* When a clickpad is clicked, combine motion of all active touches */
148 if (tp->buttons.is_clickpad && tp->buttons.state)
149 raw = tp_get_combined_touches_delta(tp);
150 else
151 raw = tp_get_average_touches_delta(tp);
152
153 delta = tp_filter_motion(tp, &raw, time);
154
155 if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
156 struct device_float_coords unaccel;
157
158 unaccel = tp_scale_to_xaxis(tp, raw);
159 pointer_notify_motion(&tp->device->base,
160 time,
161 &delta,
162 &unaccel);
163 }
164 }
165
166 static unsigned int
tp_gesture_get_active_touches(const struct tp_dispatch * tp,struct tp_touch ** touches,unsigned int count)167 tp_gesture_get_active_touches(const struct tp_dispatch *tp,
168 struct tp_touch **touches,
169 unsigned int count)
170 {
171 unsigned int n = 0;
172 struct tp_touch *t;
173
174 memset(touches, 0, count * sizeof(struct tp_touch *));
175
176 tp_for_each_touch(tp, t) {
177 if (tp_touch_active_for_gesture(tp, t)) {
178 touches[n++] = t;
179 if (n == count)
180 return count;
181 }
182 }
183
184 /*
185 * This can happen when the user does .e.g:
186 * 1) Put down 1st finger in center (so active)
187 * 2) Put down 2nd finger in a button area (so inactive)
188 * 3) Put down 3th finger somewhere, gets reported as a fake finger,
189 * so gets same coordinates as 1st -> active
190 *
191 * We could avoid this by looking at all touches, be we really only
192 * want to look at real touches.
193 */
194 return n;
195 }
196
197 static uint32_t
tp_gesture_get_direction(struct tp_dispatch * tp,struct tp_touch * touch)198 tp_gesture_get_direction(struct tp_dispatch *tp, struct tp_touch *touch)
199 {
200 struct phys_coords mm;
201 struct device_float_coords delta;
202
203 delta = device_delta(touch->point, touch->gesture.initial);
204 mm = tp_phys_delta(tp, delta);
205
206 return phys_get_direction(mm);
207 }
208
209 static void
tp_gesture_get_pinch_info(struct tp_dispatch * tp,double * distance,double * angle,struct device_float_coords * center)210 tp_gesture_get_pinch_info(struct tp_dispatch *tp,
211 double *distance,
212 double *angle,
213 struct device_float_coords *center)
214 {
215 struct normalized_coords normalized;
216 struct device_float_coords delta;
217 struct tp_touch *first = tp->gesture.touches[0],
218 *second = tp->gesture.touches[1];
219
220 delta = device_delta(first->point, second->point);
221 normalized = tp_normalize_delta(tp, delta);
222 *distance = normalized_length(normalized);
223 *angle = atan2(normalized.y, normalized.x) * 180.0 / M_PI;
224
225 *center = device_average(first->point, second->point);
226 }
227
228 static void
tp_gesture_set_scroll_buildup(struct tp_dispatch * tp)229 tp_gesture_set_scroll_buildup(struct tp_dispatch *tp)
230 {
231 struct device_float_coords d0, d1;
232 struct device_float_coords average;
233 struct tp_touch *first = tp->gesture.touches[0],
234 *second = tp->gesture.touches[1];
235
236 d0 = device_delta(first->point, first->gesture.initial);
237 d1 = device_delta(second->point, second->gesture.initial);
238
239 average = device_float_average(d0, d1);
240 tp->device->scroll.buildup = tp_normalize_delta(tp, average);
241 }
242
243 static void
tp_gesture_apply_scroll_constraints(struct tp_dispatch * tp,struct device_float_coords * raw,struct normalized_coords * delta,uint64_t time)244 tp_gesture_apply_scroll_constraints(struct tp_dispatch *tp,
245 struct device_float_coords *raw,
246 struct normalized_coords *delta,
247 uint64_t time)
248 {
249 uint64_t tdelta = 0;
250 struct phys_coords delta_mm, vector;
251 double vector_decay, vector_length, slope;
252
253 const uint64_t ACTIVE_THRESHOLD = ms2us(100),
254 INACTIVE_THRESHOLD = ms2us(50),
255 EVENT_TIMEOUT = ms2us(100);
256
257 /* Both axes active == true means free scrolling is enabled */
258 if (tp->scroll.active.h && tp->scroll.active.v)
259 return;
260
261 /* Determine time delta since last movement event */
262 if (tp->scroll.time_prev != 0)
263 tdelta = time - tp->scroll.time_prev;
264 if (tdelta > EVENT_TIMEOUT)
265 tdelta = 0;
266 tp->scroll.time_prev = time;
267
268 /* Delta since last movement event in mm */
269 delta_mm = tp_phys_delta(tp, *raw);
270
271 /* Old vector data "fades" over time. This is a two-part linear
272 * approximation of an exponential function - for example, for
273 * EVENT_TIMEOUT of 100, vector_decay = (0.97)^tdelta. This linear
274 * approximation allows easier tweaking of EVENT_TIMEOUT and is faster.
275 */
276 if (tdelta > 0) {
277 double recent, later;
278 recent = ((EVENT_TIMEOUT / 2.0) - tdelta) /
279 (EVENT_TIMEOUT / 2.0);
280 later = (EVENT_TIMEOUT - tdelta) /
281 (EVENT_TIMEOUT * 2.0);
282 vector_decay = tdelta <= (0.33 * EVENT_TIMEOUT) ?
283 recent : later;
284 } else {
285 vector_decay = 0.0;
286 }
287
288 /* Calculate windowed vector from delta + weighted historic data */
289 vector.x = (tp->scroll.vector.x * vector_decay) + delta_mm.x;
290 vector.y = (tp->scroll.vector.y * vector_decay) + delta_mm.y;
291 vector_length = hypot(vector.x, vector.y);
292 tp->scroll.vector = vector;
293
294 /* We care somewhat about distance and speed, but more about
295 * consistency of direction over time. Keep track of the time spent
296 * primarily along each axis. If one axis is active, time spent NOT
297 * moving much in the other axis is subtracted, allowing a switch of
298 * axes in a single scroll + ability to "break out" and go diagonal.
299 *
300 * Slope to degree conversions (infinity = 90°, 0 = 0°):
301 */
302 const double DEGREE_75 = 3.73;
303 const double DEGREE_60 = 1.73;
304 const double DEGREE_30 = 0.57;
305 const double DEGREE_15 = 0.27;
306 slope = (vector.x != 0) ? fabs(vector.y / vector.x) : INFINITY;
307
308 /* Ensure vector is big enough (in mm per EVENT_TIMEOUT) to be confident
309 * of direction. Larger = harder to enable diagonal/free scrolling.
310 */
311 const double MIN_VECTOR = 0.15;
312
313 if (slope >= DEGREE_30 && vector_length > MIN_VECTOR) {
314 tp->scroll.duration.v += tdelta;
315 if (tp->scroll.duration.v > ACTIVE_THRESHOLD)
316 tp->scroll.duration.v = ACTIVE_THRESHOLD;
317 if (slope >= DEGREE_75) {
318 if (tp->scroll.duration.h > tdelta)
319 tp->scroll.duration.h -= tdelta;
320 else
321 tp->scroll.duration.h = 0;
322 }
323 }
324 if (slope < DEGREE_60 && vector_length > MIN_VECTOR) {
325 tp->scroll.duration.h += tdelta;
326 if (tp->scroll.duration.h > ACTIVE_THRESHOLD)
327 tp->scroll.duration.h = ACTIVE_THRESHOLD;
328 if (slope < DEGREE_15) {
329 if (tp->scroll.duration.v > tdelta)
330 tp->scroll.duration.v -= tdelta;
331 else
332 tp->scroll.duration.v = 0;
333 }
334 }
335
336 if (tp->scroll.duration.h == ACTIVE_THRESHOLD) {
337 tp->scroll.active.h = true;
338 if (tp->scroll.duration.v < INACTIVE_THRESHOLD)
339 tp->scroll.active.v = false;
340 }
341 if (tp->scroll.duration.v == ACTIVE_THRESHOLD) {
342 tp->scroll.active.v = true;
343 if (tp->scroll.duration.h < INACTIVE_THRESHOLD)
344 tp->scroll.active.h = false;
345 }
346
347 /* If vector is big enough in a diagonal direction, always unlock
348 * both axes regardless of thresholds
349 */
350 if (vector_length > 5.0 && slope < 1.73 && slope >= 0.57) {
351 tp->scroll.active.v = true;
352 tp->scroll.active.h = true;
353 }
354
355 /* If only one axis is active, constrain motion accordingly. If both
356 * are set, we've detected deliberate diagonal movement; enable free
357 * scrolling for the life of the gesture.
358 */
359 if (!tp->scroll.active.h && tp->scroll.active.v)
360 delta->x = 0.0;
361 if (tp->scroll.active.h && !tp->scroll.active.v)
362 delta->y = 0.0;
363
364 /* If we haven't determined an axis, use the slope in the meantime */
365 if (!tp->scroll.active.h && !tp->scroll.active.v) {
366 delta->x = (slope >= DEGREE_60) ? 0.0 : delta->x;
367 delta->y = (slope < DEGREE_30) ? 0.0 : delta->y;
368 }
369 }
370
371 static enum tp_gesture_state
tp_gesture_handle_state_none(struct tp_dispatch * tp,uint64_t time)372 tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time)
373 {
374 struct tp_touch *first, *second;
375 struct tp_touch *touches[4];
376 unsigned int ntouches;
377 unsigned int i;
378
379 ntouches = tp_gesture_get_active_touches(tp, touches, 4);
380 if (ntouches < 2)
381 return GESTURE_STATE_NONE;
382
383 if (!tp->gesture.enabled) {
384 if (ntouches == 2)
385 return GESTURE_STATE_SCROLL;
386 else
387 return GESTURE_STATE_NONE;
388 }
389
390 first = touches[0];
391 second = touches[1];
392
393 /* For 3+ finger gestures, we only really need to track two touches.
394 * The human hand's finger arrangement means that for a pinch, the
395 * bottom-most touch will always be the thumb, and the top-most touch
396 * will always be one of the fingers.
397 *
398 * For 3+ finger swipes, the fingers will likely (but not necessarily)
399 * be in a horizontal line. They all move together, regardless, so it
400 * doesn't really matter which two of those touches we track.
401 *
402 * Tracking top and bottom is a change from previous versions, where
403 * we tracked leftmost and rightmost. This change enables:
404 *
405 * - More accurate pinch detection if thumb is near the center
406 * - Better resting-thumb detection while two-finger scrolling
407 * - On capable hardware, allow 3- or 4-finger swipes with resting
408 * thumb or held-down clickpad
409 */
410 if (ntouches > 2) {
411 second = touches[0];
412
413 for (i = 1; i < ntouches && i < tp->num_slots; i++) {
414 if (touches[i]->point.y < first->point.y)
415 first = touches[i];
416 else if (touches[i]->point.y >= second->point.y)
417 second = touches[i];
418 }
419
420 if (first == second)
421 return GESTURE_STATE_NONE;
422
423 }
424
425 tp->gesture.initial_time = time;
426 first->gesture.initial = first->point;
427 second->gesture.initial = second->point;
428 tp->gesture.touches[0] = first;
429 tp->gesture.touches[1] = second;
430
431 return GESTURE_STATE_UNKNOWN;
432 }
433
434 static inline int
tp_gesture_same_directions(int dir1,int dir2)435 tp_gesture_same_directions(int dir1, int dir2)
436 {
437 /*
438 * In some cases (semi-mt touchpads) we may seen one finger move
439 * e.g. N/NE and the other W/NW so we not only check for overlapping
440 * directions, but also for neighboring bits being set.
441 * The ((dira & 0x80) && (dirb & 0x01)) checks are to check for bit 0
442 * and 7 being set as they also represent neighboring directions.
443 */
444 return ((dir1 | (dir1 >> 1)) & dir2) ||
445 ((dir2 | (dir2 >> 1)) & dir1) ||
446 ((dir1 & 0x80) && (dir2 & 0x01)) ||
447 ((dir2 & 0x80) && (dir1 & 0x01));
448 }
449
450 static inline void
tp_gesture_init_pinch(struct tp_dispatch * tp)451 tp_gesture_init_pinch(struct tp_dispatch *tp)
452 {
453 tp_gesture_get_pinch_info(tp,
454 &tp->gesture.initial_distance,
455 &tp->gesture.angle,
456 &tp->gesture.center);
457 tp->gesture.prev_scale = 1.0;
458 }
459
460 static struct phys_coords
tp_gesture_mm_moved(struct tp_dispatch * tp,struct tp_touch * t)461 tp_gesture_mm_moved(struct tp_dispatch *tp, struct tp_touch *t)
462 {
463 struct device_coords delta;
464
465 delta.x = abs(t->point.x - t->gesture.initial.x);
466 delta.y = abs(t->point.y - t->gesture.initial.y);
467
468 return evdev_device_unit_delta_to_mm(tp->device, &delta);
469 }
470
471 static enum tp_gesture_state
tp_gesture_handle_state_unknown(struct tp_dispatch * tp,uint64_t time)472 tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
473 {
474 struct tp_touch *first = tp->gesture.touches[0],
475 *second = tp->gesture.touches[1],
476 *thumb;
477 uint32_t dir1, dir2;
478 struct device_coords delta;
479 struct phys_coords first_moved, second_moved, distance_mm;
480 double first_mm, second_mm; /* movement since gesture start in mm */
481 double thumb_mm, finger_mm;
482 double min_move = 1.5; /* min movement threshold in mm - count this touch */
483 double max_move = 4.0; /* max movement threshold in mm - ignore other touch */
484
485 /* If we have more fingers than slots, we don't know where the
486 * fingers are. Default to swipe */
487 if (tp->gesture.enabled && tp->gesture.finger_count > 2 &&
488 tp->gesture.finger_count > tp->num_slots)
489 return GESTURE_STATE_SWIPE;
490
491 /* Need more margin for error when there are more fingers */
492 max_move += 2.0 * (tp->gesture.finger_count - 2);
493 min_move += 0.5 * (tp->gesture.finger_count - 2);
494
495 first_moved = tp_gesture_mm_moved(tp, first);
496 first_mm = hypot(first_moved.x, first_moved.y);
497
498 second_moved = tp_gesture_mm_moved(tp, second);
499 second_mm = hypot(second_moved.x, second_moved.y);
500
501 delta.x = abs(first->point.x - second->point.x);
502 delta.y = abs(first->point.y - second->point.y);
503 distance_mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
504
505 /* If both touches moved less than a mm, we cannot decide yet */
506 if (first_mm < 1 && second_mm < 1)
507 return GESTURE_STATE_UNKNOWN;
508
509 /* Pick the thumb as the lowest point on the touchpad */
510 if (first->point.y > second->point.y) {
511 thumb = first;
512 thumb_mm = first_mm;
513 finger_mm = second_mm;
514 } else {
515 thumb = second;
516 thumb_mm = second_mm;
517 finger_mm = first_mm;
518 }
519
520 /* If both touches are within 7mm vertically and 40mm horizontally
521 * past the timeout, assume scroll/swipe */
522 if ((!tp->gesture.enabled ||
523 (distance_mm.x < 40.0 && distance_mm.y < 7.0)) &&
524 time > (tp->gesture.initial_time + DEFAULT_GESTURE_SWIPE_TIMEOUT)) {
525 if (tp->gesture.finger_count == 2) {
526 tp_gesture_set_scroll_buildup(tp);
527 return GESTURE_STATE_SCROLL;
528 } else {
529 return GESTURE_STATE_SWIPE;
530 }
531 }
532
533 /* If one touch exceeds the max_move threshold while the other has not
534 * yet passed the min_move threshold, there is either a resting thumb,
535 * or the user is doing "one-finger-scroll," where one touch stays in
536 * place while the other moves.
537 */
538 if (first_mm >= max_move || second_mm >= max_move) {
539 /* If thumb detection is enabled, and thumb is still while
540 * finger moves, cancel gestures and mark lower as thumb.
541 * This applies to all gestures (2, 3, 4+ fingers), but allows
542 * more thumb motion on >2 finger gestures during detection.
543 */
544 if (tp->thumb.detect_thumbs && thumb_mm < min_move) {
545 tp_thumb_suppress(tp, thumb);
546 return GESTURE_STATE_NONE;
547 }
548
549 /* If gestures detection is disabled, or if finger is still
550 * while thumb moves, assume this is "one-finger scrolling."
551 * This applies only to 2-finger gestures.
552 */
553 if ((!tp->gesture.enabled || finger_mm < min_move) &&
554 tp->gesture.finger_count == 2) {
555 tp_gesture_set_scroll_buildup(tp);
556 return GESTURE_STATE_SCROLL;
557 }
558
559 /* If more than 2 fingers are involved, and the thumb moves
560 * while the fingers stay still, assume a pinch if eligible.
561 */
562 if (finger_mm < min_move &&
563 tp->gesture.finger_count > 2 &&
564 tp->gesture.enabled &&
565 tp->thumb.pinch_eligible) {
566 tp_gesture_init_pinch(tp);
567 return GESTURE_STATE_PINCH;
568 }
569 }
570
571 /* If either touch is still below the min_move threshold, we can't
572 * tell what kind of gesture this is.
573 */
574 if ((first_mm < min_move) || (second_mm < min_move))
575 return GESTURE_STATE_UNKNOWN;
576
577 /* Both touches have exceeded the min_move threshold, so we have a
578 * valid gesture. Update gesture initial time and get directions so
579 * we know if it's a pinch or swipe/scroll.
580 */
581 dir1 = tp_gesture_get_direction(tp, first);
582 dir2 = tp_gesture_get_direction(tp, second);
583
584 /* If we can't accurately detect pinches, or if the touches are moving
585 * the same way, this is a scroll or swipe.
586 */
587 if (tp->gesture.finger_count > tp->num_slots ||
588 tp_gesture_same_directions(dir1, dir2)) {
589 if (tp->gesture.finger_count == 2) {
590 tp_gesture_set_scroll_buildup(tp);
591 return GESTURE_STATE_SCROLL;
592 } else if (tp->gesture.enabled) {
593 return GESTURE_STATE_SWIPE;
594 }
595 }
596
597 /* If the touches are moving away from each other, this is a pinch */
598 tp_gesture_init_pinch(tp);
599 return GESTURE_STATE_PINCH;
600 }
601
602 static enum tp_gesture_state
tp_gesture_handle_state_scroll(struct tp_dispatch * tp,uint64_t time)603 tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
604 {
605 struct device_float_coords raw;
606 struct normalized_coords delta;
607
608 if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
609 return GESTURE_STATE_SCROLL;
610
611 raw = tp_get_average_touches_delta(tp);
612
613 /* scroll is not accelerated */
614 delta = tp_filter_motion_unaccelerated(tp, &raw, time);
615
616 if (normalized_is_zero(delta))
617 return GESTURE_STATE_SCROLL;
618
619 tp_gesture_start(tp, time);
620 tp_gesture_apply_scroll_constraints(tp, &raw, &delta, time);
621 evdev_post_scroll(tp->device,
622 time,
623 LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
624 &delta);
625
626 return GESTURE_STATE_SCROLL;
627 }
628
629 static enum tp_gesture_state
tp_gesture_handle_state_swipe(struct tp_dispatch * tp,uint64_t time)630 tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time)
631 {
632 struct device_float_coords raw;
633 struct normalized_coords delta, unaccel;
634
635 raw = tp_get_average_touches_delta(tp);
636 delta = tp_filter_motion(tp, &raw, time);
637
638 if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
639 unaccel = tp_normalize_delta(tp, raw);
640 tp_gesture_start(tp, time);
641 gesture_notify_swipe(&tp->device->base, time,
642 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
643 tp->gesture.finger_count,
644 &delta, &unaccel);
645 }
646
647 return GESTURE_STATE_SWIPE;
648 }
649
650 static enum tp_gesture_state
tp_gesture_handle_state_pinch(struct tp_dispatch * tp,uint64_t time)651 tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
652 {
653 double angle, angle_delta, distance, scale;
654 struct device_float_coords center, fdelta;
655 struct normalized_coords delta, unaccel;
656
657 tp_gesture_get_pinch_info(tp, &distance, &angle, ¢er);
658
659 scale = distance / tp->gesture.initial_distance;
660
661 angle_delta = angle - tp->gesture.angle;
662 tp->gesture.angle = angle;
663 if (angle_delta > 180.0)
664 angle_delta -= 360.0;
665 else if (angle_delta < -180.0)
666 angle_delta += 360.0;
667
668 fdelta = device_float_delta(center, tp->gesture.center);
669 tp->gesture.center = center;
670
671 delta = tp_filter_motion(tp, &fdelta, time);
672
673 if (normalized_is_zero(delta) && device_float_is_zero(fdelta) &&
674 scale == tp->gesture.prev_scale && angle_delta == 0.0)
675 return GESTURE_STATE_PINCH;
676
677 unaccel = tp_normalize_delta(tp, fdelta);
678 tp_gesture_start(tp, time);
679 gesture_notify_pinch(&tp->device->base, time,
680 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
681 tp->gesture.finger_count,
682 &delta, &unaccel, scale, angle_delta);
683
684 tp->gesture.prev_scale = scale;
685
686 return GESTURE_STATE_PINCH;
687 }
688
689 static void
tp_gesture_post_gesture(struct tp_dispatch * tp,uint64_t time)690 tp_gesture_post_gesture(struct tp_dispatch *tp, uint64_t time)
691 {
692 enum tp_gesture_state oldstate = tp->gesture.state;
693
694 if (tp->gesture.state == GESTURE_STATE_NONE)
695 tp->gesture.state =
696 tp_gesture_handle_state_none(tp, time);
697
698 if (tp->gesture.state == GESTURE_STATE_UNKNOWN)
699 tp->gesture.state =
700 tp_gesture_handle_state_unknown(tp, time);
701
702 if (tp->gesture.state == GESTURE_STATE_SCROLL)
703 tp->gesture.state =
704 tp_gesture_handle_state_scroll(tp, time);
705
706 if (tp->gesture.state == GESTURE_STATE_SWIPE)
707 tp->gesture.state =
708 tp_gesture_handle_state_swipe(tp, time);
709
710 if (tp->gesture.state == GESTURE_STATE_PINCH)
711 tp->gesture.state =
712 tp_gesture_handle_state_pinch(tp, time);
713
714 if (oldstate != tp->gesture.state)
715 evdev_log_debug(tp->device,
716 "gesture state: %s → %s\n",
717 gesture_state_to_str(oldstate),
718 gesture_state_to_str(tp->gesture.state));
719 }
720
721 void
tp_gesture_post_events(struct tp_dispatch * tp,uint64_t time)722 tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time)
723 {
724 if (tp->gesture.finger_count == 0)
725 return;
726
727 /* When tap-and-dragging, force 1fg mode. On clickpads, if the
728 * physical button is down, don't allow gestures unless the button
729 * is held down by a *thumb*, specifically.
730 */
731 if (tp_tap_dragging(tp) ||
732 (tp->buttons.is_clickpad && tp->buttons.state &&
733 tp->thumb.state == THUMB_STATE_FINGER)) {
734 tp_gesture_cancel(tp, time);
735 tp->gesture.finger_count = 1;
736 tp->gesture.finger_count_pending = 0;
737 }
738
739 /* Don't send events when we're unsure in which mode we are */
740 if (tp->gesture.finger_count_pending)
741 return;
742
743 switch (tp->gesture.finger_count) {
744 case 1:
745 if (tp->queued & TOUCHPAD_EVENT_MOTION)
746 tp_gesture_post_pointer_motion(tp, time);
747 break;
748 case 2:
749 case 3:
750 case 4:
751 tp_gesture_post_gesture(tp, time);
752 break;
753 }
754 }
755
756 void
tp_gesture_stop_twofinger_scroll(struct tp_dispatch * tp,uint64_t time)757 tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
758 {
759 if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
760 return;
761
762 evdev_stop_scroll(tp->device,
763 time,
764 LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
765 }
766
767 static void
tp_gesture_end(struct tp_dispatch * tp,uint64_t time,bool cancelled)768 tp_gesture_end(struct tp_dispatch *tp, uint64_t time, bool cancelled)
769 {
770 enum tp_gesture_state state = tp->gesture.state;
771
772 tp->gesture.state = GESTURE_STATE_NONE;
773
774 if (!tp->gesture.started)
775 return;
776
777 switch (state) {
778 case GESTURE_STATE_NONE:
779 case GESTURE_STATE_UNKNOWN:
780 evdev_log_bug_libinput(tp->device,
781 "%s in unknown gesture mode\n",
782 __func__);
783 break;
784 case GESTURE_STATE_SCROLL:
785 tp_gesture_stop_twofinger_scroll(tp, time);
786 break;
787 case GESTURE_STATE_PINCH:
788 gesture_notify_pinch_end(&tp->device->base, time,
789 tp->gesture.finger_count,
790 tp->gesture.prev_scale,
791 cancelled);
792 break;
793 case GESTURE_STATE_SWIPE:
794 gesture_notify_swipe_end(&tp->device->base,
795 time,
796 tp->gesture.finger_count,
797 cancelled);
798 break;
799 }
800
801 tp->gesture.started = false;
802 }
803
804 void
tp_gesture_cancel(struct tp_dispatch * tp,uint64_t time)805 tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time)
806 {
807 tp_gesture_end(tp, time, true);
808 }
809
810 void
tp_gesture_stop(struct tp_dispatch * tp,uint64_t time)811 tp_gesture_stop(struct tp_dispatch *tp, uint64_t time)
812 {
813 tp_gesture_end(tp, time, false);
814 }
815
816 static void
tp_gesture_finger_count_switch_timeout(uint64_t now,void * data)817 tp_gesture_finger_count_switch_timeout(uint64_t now, void *data)
818 {
819 struct tp_dispatch *tp = data;
820
821 if (!tp->gesture.finger_count_pending)
822 return;
823
824 tp_gesture_cancel(tp, now); /* End current gesture */
825 tp->gesture.finger_count = tp->gesture.finger_count_pending;
826 tp->gesture.finger_count_pending = 0;
827 }
828
829 void
tp_gesture_handle_state(struct tp_dispatch * tp,uint64_t time)830 tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time)
831 {
832 unsigned int active_touches = 0;
833 struct tp_touch *t;
834
835 tp_for_each_touch(tp, t) {
836 if (tp_touch_active_for_gesture(tp, t))
837 active_touches++;
838 }
839
840 if (active_touches != tp->gesture.finger_count) {
841 /* If all fingers are lifted immediately end the gesture */
842 if (active_touches == 0) {
843 tp_gesture_stop(tp, time);
844 tp->gesture.finger_count = 0;
845 tp->gesture.finger_count_pending = 0;
846 /* Immediately switch to new mode to avoid initial latency */
847 } else if (!tp->gesture.started) {
848 tp->gesture.finger_count = active_touches;
849 tp->gesture.finger_count_pending = 0;
850 /* If in UNKNOWN state, go back to NONE to
851 * re-evaluate leftmost and rightmost touches
852 */
853 tp->gesture.state = GESTURE_STATE_NONE;
854 /* Else debounce finger changes */
855 } else if (active_touches != tp->gesture.finger_count_pending) {
856 tp->gesture.finger_count_pending = active_touches;
857 libinput_timer_set(&tp->gesture.finger_count_switch_timer,
858 time + DEFAULT_GESTURE_SWITCH_TIMEOUT);
859 }
860 } else {
861 tp->gesture.finger_count_pending = 0;
862 }
863 }
864
865 void
tp_init_gesture(struct tp_dispatch * tp)866 tp_init_gesture(struct tp_dispatch *tp)
867 {
868 char timer_name[64];
869
870 /* two-finger scrolling is always enabled, this flag just
871 * decides whether we detect pinch. semi-mt devices are too
872 * unreliable to do pinch gestures. */
873 tp->gesture.enabled = !tp->semi_mt && tp->num_slots > 1;
874
875 tp->gesture.state = GESTURE_STATE_NONE;
876
877 snprintf(timer_name,
878 sizeof(timer_name),
879 "%s gestures",
880 evdev_device_get_sysname(tp->device));
881 libinput_timer_init(&tp->gesture.finger_count_switch_timer,
882 tp_libinput_context(tp),
883 timer_name,
884 tp_gesture_finger_count_switch_timeout, tp);
885 }
886
887 void
tp_remove_gesture(struct tp_dispatch * tp)888 tp_remove_gesture(struct tp_dispatch *tp)
889 {
890 libinput_timer_cancel(&tp->gesture.finger_count_switch_timer);
891 }
892