• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &center);
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