evdev-mt-touchpad-gestures.c 25.1 KB
Newer Older
1 2 3
/*
 * Copyright © 2015 Red Hat, Inc.
 *
4 5 6 7 8 9
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
10
 *
11 12 13 14 15 16 17 18 19 20 21
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
22 23 24 25 26 27 28 29 30
 */

#include "config.h"

#include <math.h>
#include <stdbool.h>

#include "evdev-mt-touchpad.h"

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*
36
gesture_state_to_str(enum tp_gesture_state state)
37 38
{
	switch (state) {
39 40 41 42
	CASE_RETURN_STRING(GESTURE_STATE_NONE);
	CASE_RETURN_STRING(GESTURE_STATE_UNKNOWN);
	CASE_RETURN_STRING(GESTURE_STATE_SCROLL);
	CASE_RETURN_STRING(GESTURE_STATE_PINCH);
43
	CASE_RETURN_STRING(GESTURE_STATE_SWIPE);
44 45 46 47
	}
	return NULL;
}

48
static struct device_float_coords
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 57
		t = &tp->touches[i];

58
		if (!tp_touch_active_for_gesture(tp, t))
59 60 61 62 63
			continue;

		nactive++;

		if (t->dirty) {
64 65 66
			struct device_coords d;

			d = tp_get_delta(t);
67

68 69
			delta.x += d.x;
			delta.y += d.y;
70 71 72
		}
	}

73
	if (!average || nactive == 0)
74 75
		return delta;

76 77
	delta.x /= nactive;
	delta.y /= nactive;
78

79
	return delta;
80 81
}

82 83 84 85 86 87 88 89 90 91 92 93
static void
tp_gesture_init_scroll(struct tp_dispatch *tp)
{
	struct phys_coords zero = {0.0, 0.0};
	tp->scroll.active.h = false;
	tp->scroll.active.v = false;
	tp->scroll.duration.h = 0;
	tp->scroll.duration.v = 0;
	tp->scroll.vector = zero;
	tp->scroll.time_prev = 0;
}

94
static inline struct device_float_coords
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
101
tp_get_average_touches_delta(struct tp_dispatch *tp)
102
{
103
	return tp_get_touches_delta(tp, true);
104 105 106
}

static void
107 108
tp_gesture_start(struct tp_dispatch *tp, uint64_t time)
{
109 110
	const struct normalized_coords zero = { 0.0, 0.0 };

111 112 113
	if (tp->gesture.started)
		return;

114 115 116
	switch (tp->gesture.state) {
	case GESTURE_STATE_NONE:
	case GESTURE_STATE_UNKNOWN:
117 118 119
		evdev_log_bug_libinput(tp->device,
				       "%s in unknown gesture mode\n",
				       __func__);
120
		break;
121
	case GESTURE_STATE_SCROLL:
122
		tp_gesture_init_scroll(tp);
123 124 125 126 127 128 129 130
		break;
	case GESTURE_STATE_PINCH:
		gesture_notify_pinch(&tp->device->base, time,
				    LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
				    tp->gesture.finger_count,
				    &zero, &zero, 1.0, 0.0);
		break;
	case GESTURE_STATE_SWIPE:
131 132 133 134 135
		gesture_notify_swipe(&tp->device->base, time,
				     LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
				     tp->gesture.finger_count,
				     &zero, &zero);
		break;
136
	}
137

138 139 140
	tp->gesture.started = true;
}

141 142 143
static void
tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
{
144
	struct device_float_coords raw;
145
	struct normalized_coords delta;
146 147 148

	/* When a clickpad is clicked, combine motion of all active touches */
	if (tp->buttons.is_clickpad && tp->buttons.state)
149
		raw = tp_get_combined_touches_delta(tp);
150
	else
151 152 153
		raw = tp_get_average_touches_delta(tp);

	delta = tp_filter_motion(tp, &raw, time);
154

155 156
	if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
		struct device_float_coords unaccel;
157

158
		unaccel = tp_scale_to_xaxis(tp, raw);
159 160 161
		pointer_notify_motion(&tp->device->base,
				      time,
				      &delta,
162
				      &unaccel);
163 164 165
	}
}

166
static unsigned int
167
tp_gesture_get_active_touches(const struct tp_dispatch *tp,
168 169 170
			      struct tp_touch **touches,
			      unsigned int count)
{
171
	unsigned int n = 0;
172 173 174 175
	struct tp_touch *t;

	memset(touches, 0, count * sizeof(struct tp_touch *));

176
	tp_for_each_touch(tp, t) {
177
		if (tp_touch_active_for_gesture(tp, t)) {
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
			touches[n++] = t;
			if (n == count)
				return count;
		}
	}

	/*
	 * This can happen when the user does .e.g:
	 * 1) Put down 1st finger in center (so active)
	 * 2) Put down 2nd finger in a button area (so inactive)
	 * 3) Put down 3th finger somewhere, gets reported as a fake finger,
	 *    so gets same coordinates as 1st -> active
	 *
	 * We could avoid this by looking at all touches, be we really only
	 * want to look at real touches.
	 */
	return n;
}

197
static uint32_t
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
210 211 212 213 214 215 216 217 218 219 220 221 222
tp_gesture_get_pinch_info(struct tp_dispatch *tp,
			  double *distance,
			  double *angle,
			  struct device_float_coords *center)
{
	struct normalized_coords normalized;
	struct device_float_coords delta;
	struct tp_touch *first = tp->gesture.touches[0],
			*second = tp->gesture.touches[1];

	delta = device_delta(first->point, second->point);
	normalized = tp_normalize_delta(tp, delta);
	*distance = normalized_length(normalized);
223
	*angle = atan2(normalized.y, normalized.x) * 180.0 / M_PI;
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

	*center = device_average(first->point, second->point);
}

static void
tp_gesture_set_scroll_buildup(struct tp_dispatch *tp)
{
	struct device_float_coords d0, d1;
	struct device_float_coords average;
	struct tp_touch *first = tp->gesture.touches[0],
			*second = tp->gesture.touches[1];

	d0 = device_delta(first->point, first->gesture.initial);
	d1 = device_delta(second->point, second->gesture.initial);

	average = device_float_average(d0, d1);
	tp->device->scroll.buildup = tp_normalize_delta(tp, average);
}

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
static void
tp_gesture_apply_scroll_constraints(struct tp_dispatch *tp,
				  struct device_float_coords *raw,
				  struct normalized_coords *delta,
				  uint64_t time)
{
	uint64_t tdelta = 0;
	struct phys_coords delta_mm, vector;
	double vector_decay, vector_length, slope;

	const uint64_t ACTIVE_THRESHOLD = ms2us(100),
		       INACTIVE_THRESHOLD = ms2us(50),
		       EVENT_TIMEOUT = ms2us(100);

	/* Both axes active == true means free scrolling is enabled */
	if (tp->scroll.active.h && tp->scroll.active.v)
		return;

	/* Determine time delta since last movement event */
	if (tp->scroll.time_prev != 0)
		tdelta = time - tp->scroll.time_prev;
	if (tdelta > EVENT_TIMEOUT)
		tdelta = 0;
	tp->scroll.time_prev = time;

	/* Delta since last movement event in mm */
	delta_mm = tp_phys_delta(tp, *raw);

	/* Old vector data "fades" over time. This is a two-part linear
	 * approximation of an exponential function - for example, for
	 * EVENT_TIMEOUT of 100, vector_decay = (0.97)^tdelta. This linear
	 * approximation allows easier tweaking of EVENT_TIMEOUT and is faster.
	 */
	if (tdelta > 0) {
		double recent, later;
		recent = ((EVENT_TIMEOUT / 2.0) - tdelta) /
			 (EVENT_TIMEOUT / 2.0);
		later = (EVENT_TIMEOUT - tdelta) /
			(EVENT_TIMEOUT * 2.0);
		vector_decay = tdelta <= (0.33 * EVENT_TIMEOUT) ?
			       recent : later;
	} else {
		vector_decay = 0.0;
	}

	/* Calculate windowed vector from delta + weighted historic data */
	vector.x = (tp->scroll.vector.x * vector_decay) + delta_mm.x;
	vector.y = (tp->scroll.vector.y * vector_decay) + delta_mm.y;
	vector_length = hypot(vector.x, vector.y);
	tp->scroll.vector = vector;

	/* We care somewhat about distance and speed, but more about
	 * consistency of direction over time. Keep track of the time spent
	 * primarily along each axis. If one axis is active, time spent NOT
	 * moving much in the other axis is subtracted, allowing a switch of
	 * axes in a single scroll + ability to "break out" and go diagonal.
	 *
	 * Slope to degree conversions (infinity = 90°, 0 = 0°):
	 */
	const double DEGREE_75 = 3.73;
	const double DEGREE_60 = 1.73;
	const double DEGREE_30 = 0.57;
	const double DEGREE_15 = 0.27;
	slope = (vector.x != 0) ? fabs(vector.y / vector.x) : INFINITY;

	/* Ensure vector is big enough (in mm per EVENT_TIMEOUT) to be confident
	 * of direction. Larger = harder to enable diagonal/free scrolling.
	 */
311
	const double MIN_VECTOR = 0.15;
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370

	if (slope >= DEGREE_30 && vector_length > MIN_VECTOR) {
		tp->scroll.duration.v += tdelta;
		if (tp->scroll.duration.v > ACTIVE_THRESHOLD)
			tp->scroll.duration.v = ACTIVE_THRESHOLD;
		if (slope >= DEGREE_75) {
			if (tp->scroll.duration.h > tdelta)
				tp->scroll.duration.h -= tdelta;
			else
				tp->scroll.duration.h = 0;
		}
	}
	if (slope < DEGREE_60  && vector_length > MIN_VECTOR) {
		tp->scroll.duration.h += tdelta;
		if (tp->scroll.duration.h > ACTIVE_THRESHOLD)
			tp->scroll.duration.h = ACTIVE_THRESHOLD;
		if (slope < DEGREE_15) {
			if (tp->scroll.duration.v > tdelta)
				tp->scroll.duration.v -= tdelta;
			else
				tp->scroll.duration.v = 0;
		}
	}

	if (tp->scroll.duration.h == ACTIVE_THRESHOLD) {
		tp->scroll.active.h = true;
		if (tp->scroll.duration.v < INACTIVE_THRESHOLD)
			tp->scroll.active.v = false;
	}
	if (tp->scroll.duration.v == ACTIVE_THRESHOLD) {
		tp->scroll.active.v = true;
		if (tp->scroll.duration.h < INACTIVE_THRESHOLD)
			tp->scroll.active.h = false;
	}

	/* If vector is big enough in a diagonal direction, always unlock
	 * both axes regardless of thresholds
	 */
	if (vector_length > 5.0 && slope < 1.73 && slope >= 0.57) {
		tp->scroll.active.v = true;
		tp->scroll.active.h = true;
	}

	/* If only one axis is active, constrain motion accordingly. If both
	 * are set, we've detected deliberate diagonal movement; enable free
	 * scrolling for the life of the gesture.
	 */
	if (!tp->scroll.active.h && tp->scroll.active.v)
		delta->x = 0.0;
	if (tp->scroll.active.h && !tp->scroll.active.v)
		delta->y = 0.0;

	/* If we haven't determined an axis, use the slope in the meantime */
	if (!tp->scroll.active.h && !tp->scroll.active.v) {
		delta->x = (slope >= DEGREE_60) ? 0.0 : delta->x;
		delta->y = (slope < DEGREE_30) ? 0.0 : delta->y;
	}
}

371
static enum tp_gesture_state
372
tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time)
373 374
{
	struct tp_touch *first, *second;
375 376 377
	struct tp_touch *touches[4];
	unsigned int ntouches;
	unsigned int i;
378

379 380
	ntouches = tp_gesture_get_active_touches(tp, touches, 4);
	if (ntouches < 2)
381
		return GESTURE_STATE_NONE;
382

383 384 385 386
	if (!tp->gesture.enabled) {
		if (ntouches == 2)
			return GESTURE_STATE_SCROLL;
		else
387
			return GESTURE_STATE_NONE;
388 389
	}

390 391 392
	first = touches[0];
	second = touches[1];

393 394 395 396
	/* For 3+ finger gestures, we only really need to track two touches.
	 * The human hand's finger arrangement means that for a pinch, the
	 * bottom-most touch will always be the thumb, and the top-most touch
	 * will always be one of the fingers.
397
	 *
398 399 400 401 402 403 404 405 406 407 408
	 * For 3+ finger swipes, the fingers will likely (but not necessarily)
	 * be in a horizontal line. They all move together, regardless, so it
	 * doesn't really matter which two of those touches we track.
	 *
	 * Tracking top and bottom is a change from previous versions, where
	 * we tracked leftmost and rightmost. This change enables:
	 *
	 * - More accurate pinch detection if thumb is near the center
	 * - Better resting-thumb detection while two-finger scrolling
	 * - On capable hardware, allow 3- or 4-finger swipes with resting
	 *   thumb or held-down clickpad
409 410 411 412 413
	 */
	if (ntouches > 2) {
		second = touches[0];

		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 418 419 420 421
				second = touches[i];
		}

		if (first == second)
			return GESTURE_STATE_NONE;
422

423
	}
424 425 426 427

	tp->gesture.initial_time = time;
	first->gesture.initial = first->point;
	second->gesture.initial = second->point;
428 429
	tp->gesture.touches[0] = first;
	tp->gesture.touches[1] = second;
430

431
	return GESTURE_STATE_UNKNOWN;
432 433
}

434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
static inline int
tp_gesture_same_directions(int dir1, int dir2)
{
	/*
	 * In some cases (semi-mt touchpads) we may seen one finger move
	 * e.g. N/NE and the other W/NW so we not only check for overlapping
	 * directions, but also for neighboring bits being set.
	 * The ((dira & 0x80) && (dirb & 0x01)) checks are to check for bit 0
	 * and 7 being set as they also represent neighboring directions.
	 */
	return ((dir1 | (dir1 >> 1)) & dir2) ||
		((dir2 | (dir2 >> 1)) & dir1) ||
		((dir1 & 0x80) && (dir2 & 0x01)) ||
		((dir2 & 0x80) && (dir1 & 0x01));
}

450
static inline void
Peter Hutterer's avatar
Peter Hutterer committed
451
tp_gesture_init_pinch(struct tp_dispatch *tp)
452 453 454 455 456 457 458 459
{
	tp_gesture_get_pinch_info(tp,
				  &tp->gesture.initial_distance,
				  &tp->gesture.angle,
				  &tp->gesture.center);
	tp->gesture.prev_scale = 1.0;
}

460 461 462 463 464 465 466 467 468 469 470
static struct phys_coords
tp_gesture_mm_moved(struct tp_dispatch *tp, struct tp_touch *t)
{
	struct device_coords delta;

	delta.x = abs(t->point.x - t->gesture.initial.x);
	delta.y = abs(t->point.y - t->gesture.initial.y);

	return evdev_device_unit_delta_to_mm(tp->device, &delta);
}

471
static enum tp_gesture_state
472
tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
473 474
{
	struct tp_touch *first = tp->gesture.touches[0],
475 476
			*second = tp->gesture.touches[1],
			*thumb;
477
	uint32_t dir1, dir2;
478 479 480
	struct device_coords delta;
	struct phys_coords first_moved, second_moved, distance_mm;
	double first_mm, second_mm; /* movement since gesture start in mm */
481
	double thumb_mm, finger_mm;
482 483
	double min_move = 1.5; /* min movement threshold in mm - count this touch */
	double max_move = 4.0; /* max movement threshold in mm - ignore other touch */
484

485 486 487 488 489 490
	/* If we have more fingers than slots, we don't know where the
	 * fingers are. Default to swipe */
	if (tp->gesture.enabled && tp->gesture.finger_count > 2 &&
	    tp->gesture.finger_count > tp->num_slots)
		return GESTURE_STATE_SWIPE;

491
	/* Need more margin for error when there are more fingers */
492 493
	max_move += 2.0 * (tp->gesture.finger_count - 2);
	min_move += 0.5 * (tp->gesture.finger_count - 2);
494

495 496
	first_moved = tp_gesture_mm_moved(tp, first);
	first_mm = hypot(first_moved.x, first_moved.y);
497

498 499 500 501 502 503
	second_moved = tp_gesture_mm_moved(tp, second);
	second_mm = hypot(second_moved.x, second_moved.y);

	delta.x = abs(first->point.x - second->point.x);
	delta.y = abs(first->point.y - second->point.y);
	distance_mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
504

505 506 507 508
	/* If both touches moved less than a mm, we cannot decide yet */
	if (first_mm < 1 && second_mm < 1)
		return GESTURE_STATE_UNKNOWN;

509 510 511 512 513 514 515 516 517 518 519
	/* Pick the thumb as the lowest point on the touchpad */
	if (first->point.y > second->point.y) {
		thumb = first;
		thumb_mm = first_mm;
		finger_mm = second_mm;
	} else {
		thumb = second;
		thumb_mm = second_mm;
		finger_mm = first_mm;
	}

520 521
	/* If both touches are within 7mm vertically and 40mm horizontally
	 * past the timeout, assume scroll/swipe */
522 523
	if ((!tp->gesture.enabled ||
	     (distance_mm.x < 40.0 && distance_mm.y < 7.0)) &&
524
	    time > (tp->gesture.initial_time + DEFAULT_GESTURE_SWIPE_TIMEOUT)) {
525 526 527
		if (tp->gesture.finger_count == 2) {
			tp_gesture_set_scroll_buildup(tp);
			return GESTURE_STATE_SCROLL;
528
		} else {
529 530 531 532
			return GESTURE_STATE_SWIPE;
		}
	}

533 534
	/* If one touch exceeds the max_move threshold while the other has not
	 * yet passed the min_move threshold, there is either a resting thumb,
535 536
	 * or the user is doing "one-finger-scroll," where one touch stays in
	 * place while the other moves.
537
	 */
538
	if (first_mm >= max_move || second_mm >= max_move) {
539 540 541 542 543
		/* If thumb detection is enabled, and thumb is still while
		 * finger moves, cancel gestures and mark lower as thumb.
		 * This applies to all gestures (2, 3, 4+ fingers), but allows
		 * more thumb motion on >2 finger gestures during detection.
		 */
544
		if (tp->thumb.detect_thumbs && thumb_mm < min_move) {
545
			tp_thumb_suppress(tp, thumb);
546 547
			return GESTURE_STATE_NONE;
		}
548 549 550 551 552

		/* If gestures detection is disabled, or if finger is still
		 * while thumb moves, assume this is "one-finger scrolling."
		 * This applies only to 2-finger gestures.
		 */
553
		if ((!tp->gesture.enabled || finger_mm < min_move) &&
554 555 556
		    tp->gesture.finger_count == 2) {
			tp_gesture_set_scroll_buildup(tp);
			return GESTURE_STATE_SCROLL;
557
		}
558

559 560
		/* If more than 2 fingers are involved, and the thumb moves
		 * while the fingers stay still, assume a pinch if eligible.
561
		 */
562
		if (finger_mm < min_move &&
563 564 565 566 567 568
		    tp->gesture.finger_count > 2 &&
		    tp->gesture.enabled &&
		    tp->thumb.pinch_eligible) {
			tp_gesture_init_pinch(tp);
			return GESTURE_STATE_PINCH;
		}
569 570
	}

571
	/* If either touch is still below the min_move threshold, we can't
572 573
	 * tell what kind of gesture this is.
	 */
574
	if ((first_mm < min_move) || (second_mm < min_move))
575
		return GESTURE_STATE_UNKNOWN;
576

577 578 579
	/* Both touches have exceeded the min_move threshold, so we have a
	 * valid gesture. Update gesture initial time and get directions so
	 * we know if it's a pinch or swipe/scroll.
580 581 582 583 584 585 586
	 */
	dir1 = tp_gesture_get_direction(tp, first);
	dir2 = tp_gesture_get_direction(tp, second);

	/* If we can't accurately detect pinches, or if the touches are moving
	 * the same way, this is a scroll or swipe.
	 */
587 588
	if (tp->gesture.finger_count > tp->num_slots ||
	    tp_gesture_same_directions(dir1, dir2)) {
589 590 591 592 593 594
		if (tp->gesture.finger_count == 2) {
			tp_gesture_set_scroll_buildup(tp);
			return GESTURE_STATE_SCROLL;
		} else if (tp->gesture.enabled) {
			return GESTURE_STATE_SWIPE;
		}
595
	}
596

597 598 599
	/* If the touches are moving away from each other, this is a pinch */
	tp_gesture_init_pinch(tp);
	return GESTURE_STATE_PINCH;
600 601
}

602
static enum tp_gesture_state
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 622 623
	evdev_post_scroll(tp->device,
			  time,
			  LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
624
			  &delta);
625

626
	return GESTURE_STATE_SCROLL;
627 628
}

629
static enum tp_gesture_state
630 631
tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time)
{
632
	struct device_float_coords raw;
633 634
	struct normalized_coords delta, unaccel;

635 636
	raw = tp_get_average_touches_delta(tp);
	delta = tp_filter_motion(tp, &raw, time);
637

638 639
	if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
		unaccel = tp_normalize_delta(tp, raw);
640 641 642 643 644 645 646 647 648 649 650 651
		tp_gesture_start(tp, time);
		gesture_notify_swipe(&tp->device->base, time,
				     LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
				     tp->gesture.finger_count,
				     &delta, &unaccel);
	}

	return GESTURE_STATE_SWIPE;
}

static enum tp_gesture_state
tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
{
	double angle, angle_delta, distance, scale;
	struct device_float_coords center, fdelta;
	struct normalized_coords delta, unaccel;

	tp_gesture_get_pinch_info(tp, &distance, &angle, &center);

	scale = distance / tp->gesture.initial_distance;

	angle_delta = angle - tp->gesture.angle;
	tp->gesture.angle = angle;
	if (angle_delta > 180.0)
		angle_delta -= 360.0;
	else if (angle_delta < -180.0)
		angle_delta += 360.0;

	fdelta = device_float_delta(center, tp->gesture.center);
	tp->gesture.center = center;

671 672 673
	delta = tp_filter_motion(tp, &fdelta, time);

	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 679 680
	tp_gesture_start(tp, time);
	gesture_notify_pinch(&tp->device->base, time,
			     LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
681
			     tp->gesture.finger_count,
682 683 684 685
			     &delta, &unaccel, scale, angle_delta);

	tp->gesture.prev_scale = scale;

686
	return GESTURE_STATE_PINCH;
687 688 689
}

static void
690
tp_gesture_post_gesture(struct tp_dispatch *tp, uint64_t time)
691
{
692
	enum tp_gesture_state oldstate = tp->gesture.state;
693

694 695
	if (tp->gesture.state == GESTURE_STATE_NONE)
		tp->gesture.state =
696
			tp_gesture_handle_state_none(tp, time);
697

698 699
	if (tp->gesture.state == GESTURE_STATE_UNKNOWN)
		tp->gesture.state =
700
			tp_gesture_handle_state_unknown(tp, time);
701

702 703
	if (tp->gesture.state == GESTURE_STATE_SCROLL)
		tp->gesture.state =
704 705 706 707 708
			tp_gesture_handle_state_scroll(tp, time);

	if (tp->gesture.state == GESTURE_STATE_SWIPE)
		tp->gesture.state =
			tp_gesture_handle_state_swipe(tp, time);
709

710 711
	if (tp->gesture.state == GESTURE_STATE_PINCH)
		tp->gesture.state =
712
			tp_gesture_handle_state_pinch(tp, time);
713

714 715 716 717 718
	if (oldstate != tp->gesture.state)
		evdev_log_debug(tp->device,
				"gesture state: %s → %s\n",
				gesture_state_to_str(oldstate),
				gesture_state_to_str(tp->gesture.state));
719 720
}

721 722 723 724 725 726
void
tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time)
{
	if (tp->gesture.finger_count == 0)
		return;

727 728 729 730 731 732 733
	/* When tap-and-dragging, force 1fg mode. On clickpads, if the
	 * physical button is down, don't allow gestures unless the button
	 * is held down by a *thumb*, specifically.
	 */
	if (tp_tap_dragging(tp) ||
	    (tp->buttons.is_clickpad && tp->buttons.state &&
	     tp->thumb.state == THUMB_STATE_FINGER)) {
734
		tp_gesture_cancel(tp, time);
735 736 737 738 739 740 741 742 743 744
		tp->gesture.finger_count = 1;
		tp->gesture.finger_count_pending = 0;
	}

	/* Don't send events when we're unsure in which mode we are */
	if (tp->gesture.finger_count_pending)
		return;

	switch (tp->gesture.finger_count) {
	case 1:
745 746
		if (tp->queued & TOUCHPAD_EVENT_MOTION)
			tp_gesture_post_pointer_motion(tp, time);
747 748
		break;
	case 2:
749 750
	case 3:
	case 4:
751
		tp_gesture_post_gesture(tp, time);
752
		break;
753 754 755
	}
}

756 757 758
void
tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
{
759 760 761
	if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
		return;

762 763 764 765 766
	evdev_stop_scroll(tp->device,
			  time,
			  LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
}

767 768
static void
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 775 776
	if (!tp->gesture.started)
		return;

777 778 779
	switch (state) {
	case GESTURE_STATE_NONE:
	case GESTURE_STATE_UNKNOWN:
780 781 782
		evdev_log_bug_libinput(tp->device,
				       "%s in unknown gesture mode\n",
				       __func__);
783
		break;
784 785 786 787 788 789 790 791 792 793 794 795 796 797
	case GESTURE_STATE_SCROLL:
		tp_gesture_stop_twofinger_scroll(tp, time);
		break;
	case GESTURE_STATE_PINCH:
		gesture_notify_pinch_end(&tp->device->base, time,
					 tp->gesture.finger_count,
					 tp->gesture.prev_scale,
					 cancelled);
		break;
	case GESTURE_STATE_SWIPE:
		gesture_notify_swipe_end(&tp->device->base,
					 time,
					 tp->gesture.finger_count,
					 cancelled);
798
		break;
799
	}
800

801 802 803
	tp->gesture.started = false;
}

804 805 806 807 808 809 810 811 812 813 814 815
void
tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time)
{
	tp_gesture_end(tp, time, true);
}

void
tp_gesture_stop(struct tp_dispatch *tp, uint64_t time)
{
	tp_gesture_end(tp, time, false);
}

816 817 818 819 820 821 822 823
static void
tp_gesture_finger_count_switch_timeout(uint64_t now, void *data)
{
	struct tp_dispatch *tp = data;

	if (!tp->gesture.finger_count_pending)
		return;

824
	tp_gesture_cancel(tp, now); /* End current gesture */
825 826 827 828 829 830 831 832 833 834
	tp->gesture.finger_count = tp->gesture.finger_count_pending;
	tp->gesture.finger_count_pending = 0;
}

void
tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time)
{
	unsigned int active_touches = 0;
	struct tp_touch *t;

835
	tp_for_each_touch(tp, t) {
836
		if (tp_touch_active_for_gesture(tp, t))
837
			active_touches++;
838 839
	}

840 841 842
	if (active_touches != tp->gesture.finger_count) {
		/* If all fingers are lifted immediately end the gesture */
		if (active_touches == 0) {
843
			tp_gesture_stop(tp, time);
844 845 846 847 848 849
			tp->gesture.finger_count = 0;
			tp->gesture.finger_count_pending = 0;
		/* Immediately switch to new mode to avoid initial latency */
		} else if (!tp->gesture.started) {
			tp->gesture.finger_count = active_touches;
			tp->gesture.finger_count_pending = 0;
850 851 852 853
			/* If in UNKNOWN state, go back to NONE to
			 * re-evaluate leftmost and rightmost touches
			 */
			tp->gesture.state = GESTURE_STATE_NONE;
854 855 856 857 858 859 860 861 862 863 864
		/* Else debounce finger changes */
		} else if (active_touches != tp->gesture.finger_count_pending) {
			tp->gesture.finger_count_pending = active_touches;
			libinput_timer_set(&tp->gesture.finger_count_switch_timer,
				time + DEFAULT_GESTURE_SWITCH_TIMEOUT);
		}
	} else {
		 tp->gesture.finger_count_pending = 0;
	}
}

865
void
866 867
tp_init_gesture(struct tp_dispatch *tp)
{
868 869
	char timer_name[64];

870 871 872
	/* two-finger scrolling is always enabled, this flag just
	 * decides whether we detect pinch. semi-mt devices are too
	 * 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 878 879 880
	snprintf(timer_name,
		 sizeof(timer_name),
		 "%s gestures",
		 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 885 886 887 888 889 890 891
			    tp_gesture_finger_count_switch_timeout, tp);
}

void
tp_remove_gesture(struct tp_dispatch *tp)
{
	libinput_timer_cancel(&tp->gesture.finger_count_switch_timer);
}