1 /*
2 * Copyright © 2013-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 <assert.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29
30 #include "evdev-mt-touchpad.h"
31
32 #define DEFAULT_TAP_TIMEOUT_PERIOD ms2us(180)
33 #define DEFAULT_DRAG_TIMEOUT_PERIOD_BASE ms2us(160)
34 #define DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER ms2us(20)
35 #define DEFAULT_DRAGLOCK_TIMEOUT_PERIOD ms2us(300)
36 #define DEFAULT_TAP_MOVE_THRESHOLD 1.3 /* mm */
37
38 enum tap_event {
39 TAP_EVENT_TOUCH = 12,
40 TAP_EVENT_MOTION,
41 TAP_EVENT_RELEASE,
42 TAP_EVENT_BUTTON,
43 TAP_EVENT_TIMEOUT,
44 TAP_EVENT_THUMB,
45 TAP_EVENT_PALM,
46 TAP_EVENT_PALM_UP,
47 };
48
49 /*****************************************
50 * DO NOT EDIT THIS FILE!
51 *
52 * Look at the state diagram in doc/touchpad-tap-state-machine.svg
53 * (generated with https://www.diagrams.net)
54 *
55 * Any changes in this file must be represented in the diagram.
56 */
57
58 static inline const char*
tap_state_to_str(enum tp_tap_state state)59 tap_state_to_str(enum tp_tap_state state)
60 {
61 switch(state) {
62 CASE_RETURN_STRING(TAP_STATE_IDLE);
63 CASE_RETURN_STRING(TAP_STATE_HOLD);
64 CASE_RETURN_STRING(TAP_STATE_TOUCH);
65 CASE_RETURN_STRING(TAP_STATE_1FGTAP_TAPPED);
66 CASE_RETURN_STRING(TAP_STATE_2FGTAP_TAPPED);
67 CASE_RETURN_STRING(TAP_STATE_3FGTAP_TAPPED);
68 CASE_RETURN_STRING(TAP_STATE_TOUCH_2);
69 CASE_RETURN_STRING(TAP_STATE_TOUCH_2_HOLD);
70 CASE_RETURN_STRING(TAP_STATE_TOUCH_2_RELEASE);
71 CASE_RETURN_STRING(TAP_STATE_TOUCH_3);
72 CASE_RETURN_STRING(TAP_STATE_TOUCH_3_HOLD);
73 CASE_RETURN_STRING(TAP_STATE_TOUCH_3_RELEASE);
74 CASE_RETURN_STRING(TAP_STATE_TOUCH_3_RELEASE_2);
75 CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING);
76 CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING);
77 CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING);
78 CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_WAIT);
79 CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_WAIT);
80 CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_WAIT);
81 CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP);
82 CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP);
83 CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP);
84 CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_OR_TAP);
85 CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_OR_TAP);
86 CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_OR_TAP);
87 CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_2);
88 CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_2);
89 CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_2);
90 CASE_RETURN_STRING(TAP_STATE_DEAD);
91 }
92 return NULL;
93 }
94
95 static inline const char*
tap_event_to_str(enum tap_event event)96 tap_event_to_str(enum tap_event event)
97 {
98 switch(event) {
99 CASE_RETURN_STRING(TAP_EVENT_TOUCH);
100 CASE_RETURN_STRING(TAP_EVENT_MOTION);
101 CASE_RETURN_STRING(TAP_EVENT_RELEASE);
102 CASE_RETURN_STRING(TAP_EVENT_TIMEOUT);
103 CASE_RETURN_STRING(TAP_EVENT_BUTTON);
104 CASE_RETURN_STRING(TAP_EVENT_THUMB);
105 CASE_RETURN_STRING(TAP_EVENT_PALM);
106 CASE_RETURN_STRING(TAP_EVENT_PALM_UP);
107 }
108 return NULL;
109 }
110
111 static inline void
log_tap_bug(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event)112 log_tap_bug(struct tp_dispatch *tp, struct tp_touch *t, enum tap_event event)
113 {
114 evdev_log_bug_libinput(tp->device,
115 "%d: invalid tap event %s in state %s\n",
116 t->index,
117 tap_event_to_str(event),
118 tap_state_to_str(tp->tap.state));
119
120 }
121
122 static void
tp_tap_notify(struct tp_dispatch * tp,uint64_t time,int nfingers,enum libinput_button_state state)123 tp_tap_notify(struct tp_dispatch *tp,
124 uint64_t time,
125 int nfingers,
126 enum libinput_button_state state)
127 {
128 int32_t button;
129 int32_t button_map[2][3] = {
130 { BTN_LEFT, BTN_RIGHT, BTN_MIDDLE },
131 { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT },
132 };
133
134 assert(tp->tap.map < ARRAY_LENGTH(button_map));
135
136 if (nfingers < 1 || nfingers > 3)
137 return;
138
139 button = button_map[tp->tap.map][nfingers - 1];
140
141 if (state == LIBINPUT_BUTTON_STATE_PRESSED)
142 tp->tap.buttons_pressed |= (1 << nfingers);
143 else
144 tp->tap.buttons_pressed &= ~(1 << nfingers);
145
146 evdev_pointer_notify_button(tp->device,
147 time,
148 button,
149 state);
150 }
151
152 static void
tp_tap_set_timer(struct tp_dispatch * tp,uint64_t time)153 tp_tap_set_timer(struct tp_dispatch *tp, uint64_t time)
154 {
155 libinput_timer_set(&tp->tap.timer, time + DEFAULT_TAP_TIMEOUT_PERIOD);
156 }
157
158 static void
tp_tap_set_drag_timer(struct tp_dispatch * tp,uint64_t time,int nfingers_tapped)159 tp_tap_set_drag_timer(struct tp_dispatch *tp, uint64_t time,
160 int nfingers_tapped)
161 {
162 libinput_timer_set(&tp->tap.timer,
163 time + DEFAULT_DRAG_TIMEOUT_PERIOD_BASE +
164 (nfingers_tapped *
165 DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER));
166 }
167
168 static void
tp_tap_set_draglock_timer(struct tp_dispatch * tp,uint64_t time)169 tp_tap_set_draglock_timer(struct tp_dispatch *tp, uint64_t time)
170 {
171 libinput_timer_set(&tp->tap.timer,
172 time + DEFAULT_DRAGLOCK_TIMEOUT_PERIOD);
173 }
174
175 static void
tp_tap_clear_timer(struct tp_dispatch * tp)176 tp_tap_clear_timer(struct tp_dispatch *tp)
177 {
178 libinput_timer_cancel(&tp->tap.timer);
179 }
180
181 static void
tp_tap_move_to_dead(struct tp_dispatch * tp,struct tp_touch * t)182 tp_tap_move_to_dead(struct tp_dispatch *tp, struct tp_touch *t)
183 {
184 tp->tap.state = TAP_STATE_DEAD;
185 t->tap.state = TAP_TOUCH_STATE_DEAD;
186 tp_tap_clear_timer(tp);
187 }
188
189 static void
tp_tap_idle_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)190 tp_tap_idle_handle_event(struct tp_dispatch *tp,
191 struct tp_touch *t,
192 enum tap_event event, uint64_t time)
193 {
194 switch (event) {
195 case TAP_EVENT_TOUCH:
196 tp->tap.state = TAP_STATE_TOUCH;
197 tp->tap.saved_press_time = time;
198 tp_tap_set_timer(tp, time);
199 break;
200 case TAP_EVENT_RELEASE:
201 break;
202 case TAP_EVENT_MOTION:
203 log_tap_bug(tp, t, event);
204 break;
205 case TAP_EVENT_TIMEOUT:
206 break;
207 case TAP_EVENT_BUTTON:
208 tp->tap.state = TAP_STATE_DEAD;
209 break;
210 case TAP_EVENT_THUMB:
211 log_tap_bug(tp, t, event);
212 break;
213 case TAP_EVENT_PALM:
214 tp->tap.state = TAP_STATE_IDLE;
215 break;
216 case TAP_EVENT_PALM_UP:
217 break;
218 }
219 }
220
221 static void
tp_tap_touch_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)222 tp_tap_touch_handle_event(struct tp_dispatch *tp,
223 struct tp_touch *t,
224 enum tap_event event, uint64_t time)
225 {
226
227 switch (event) {
228 case TAP_EVENT_TOUCH:
229 tp->tap.state = TAP_STATE_TOUCH_2;
230 tp->tap.saved_press_time = time;
231 tp_tap_set_timer(tp, time);
232 break;
233 case TAP_EVENT_RELEASE:
234 tp_tap_notify(tp,
235 tp->tap.saved_press_time,
236 1,
237 LIBINPUT_BUTTON_STATE_PRESSED);
238 if (tp->tap.drag_enabled) {
239 tp->tap.state = TAP_STATE_1FGTAP_TAPPED;
240 tp->tap.saved_release_time = time;
241 tp_tap_set_drag_timer(tp, time, 1);
242 } else {
243 tp_tap_notify(tp,
244 time,
245 1,
246 LIBINPUT_BUTTON_STATE_RELEASED);
247 tp->tap.state = TAP_STATE_IDLE;
248 }
249 break;
250 case TAP_EVENT_MOTION:
251 tp_tap_move_to_dead(tp, t);
252 break;
253 case TAP_EVENT_TIMEOUT:
254 tp->tap.state = TAP_STATE_HOLD;
255 tp_tap_clear_timer(tp);
256 tp_gesture_tap_timeout(tp, time);
257 break;
258 case TAP_EVENT_BUTTON:
259 tp->tap.state = TAP_STATE_DEAD;
260 break;
261 case TAP_EVENT_THUMB:
262 tp->tap.state = TAP_STATE_IDLE;
263 t->tap.is_thumb = true;
264 tp->tap.nfingers_down--;
265 t->tap.state = TAP_TOUCH_STATE_DEAD;
266 tp_tap_clear_timer(tp);
267 break;
268 case TAP_EVENT_PALM:
269 tp->tap.state = TAP_STATE_IDLE;
270 tp_tap_clear_timer(tp);
271 break;
272 case TAP_EVENT_PALM_UP:
273 break;
274 }
275 }
276
277 static void
tp_tap_hold_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)278 tp_tap_hold_handle_event(struct tp_dispatch *tp,
279 struct tp_touch *t,
280 enum tap_event event, uint64_t time)
281 {
282
283 switch (event) {
284 case TAP_EVENT_TOUCH:
285 tp->tap.state = TAP_STATE_TOUCH_2;
286 tp->tap.saved_press_time = time;
287 tp_tap_set_timer(tp, time);
288 break;
289 case TAP_EVENT_RELEASE:
290 tp->tap.state = TAP_STATE_IDLE;
291 break;
292 case TAP_EVENT_MOTION:
293 tp_tap_move_to_dead(tp, t);
294 break;
295 case TAP_EVENT_TIMEOUT:
296 break;
297 case TAP_EVENT_BUTTON:
298 tp->tap.state = TAP_STATE_DEAD;
299 break;
300 case TAP_EVENT_THUMB:
301 tp->tap.state = TAP_STATE_IDLE;
302 t->tap.is_thumb = true;
303 tp->tap.nfingers_down--;
304 t->tap.state = TAP_TOUCH_STATE_DEAD;
305 break;
306 case TAP_EVENT_PALM:
307 tp->tap.state = TAP_STATE_IDLE;
308 break;
309 case TAP_EVENT_PALM_UP:
310 break;
311 }
312 }
313
314 static void
tp_tap_tapped_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time,int nfingers_tapped)315 tp_tap_tapped_handle_event(struct tp_dispatch *tp,
316 struct tp_touch *t,
317 enum tap_event event, uint64_t time,
318 int nfingers_tapped)
319 {
320 switch (event) {
321 case TAP_EVENT_MOTION:
322 case TAP_EVENT_RELEASE:
323 log_tap_bug(tp, t, event);
324 break;
325 case TAP_EVENT_TOUCH: {
326 enum tp_tap_state dest[3] = {
327 TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP,
328 TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP,
329 TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP,
330 };
331 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
332 tp->tap.state = dest[nfingers_tapped - 1];
333 tp->tap.saved_press_time = time;
334 tp_tap_set_timer(tp, time);
335 break;
336 }
337 case TAP_EVENT_TIMEOUT:
338 tp->tap.state = TAP_STATE_IDLE;
339 tp_tap_notify(tp,
340 tp->tap.saved_release_time,
341 nfingers_tapped,
342 LIBINPUT_BUTTON_STATE_RELEASED);
343 break;
344 case TAP_EVENT_BUTTON:
345 tp->tap.state = TAP_STATE_DEAD;
346 tp_tap_notify(tp,
347 tp->tap.saved_release_time,
348 nfingers_tapped,
349 LIBINPUT_BUTTON_STATE_RELEASED);
350 break;
351 case TAP_EVENT_THUMB:
352 log_tap_bug(tp, t, event);
353 break;
354 case TAP_EVENT_PALM:
355 log_tap_bug(tp, t, event);
356 break;
357 case TAP_EVENT_PALM_UP:
358 break;
359 }
360 }
361
362 static void
tp_tap_touch2_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)363 tp_tap_touch2_handle_event(struct tp_dispatch *tp,
364 struct tp_touch *t,
365 enum tap_event event, uint64_t time)
366 {
367
368 switch (event) {
369 case TAP_EVENT_TOUCH:
370 tp->tap.state = TAP_STATE_TOUCH_3;
371 tp->tap.saved_press_time = time;
372 tp_tap_set_timer(tp, time);
373 break;
374 case TAP_EVENT_RELEASE:
375 tp->tap.state = TAP_STATE_TOUCH_2_RELEASE;
376 tp->tap.saved_release_time = time;
377 tp_tap_set_timer(tp, time);
378 break;
379 case TAP_EVENT_MOTION:
380 tp_tap_move_to_dead(tp, t);
381 break;
382 case TAP_EVENT_TIMEOUT:
383 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
384 tp_gesture_tap_timeout(tp, time);
385 break;
386 case TAP_EVENT_BUTTON:
387 tp->tap.state = TAP_STATE_DEAD;
388 break;
389 case TAP_EVENT_THUMB:
390 break;
391 case TAP_EVENT_PALM:
392 tp->tap.state = TAP_STATE_TOUCH;
393 break;
394 case TAP_EVENT_PALM_UP:
395 break;
396 }
397 }
398
399 static void
tp_tap_touch2_hold_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)400 tp_tap_touch2_hold_handle_event(struct tp_dispatch *tp,
401 struct tp_touch *t,
402 enum tap_event event, uint64_t time)
403 {
404
405 switch (event) {
406 case TAP_EVENT_TOUCH:
407 tp->tap.state = TAP_STATE_TOUCH_3;
408 tp->tap.saved_press_time = time;
409 tp_tap_set_timer(tp, time);
410 break;
411 case TAP_EVENT_RELEASE:
412 tp->tap.state = TAP_STATE_HOLD;
413 break;
414 case TAP_EVENT_MOTION:
415 tp_tap_move_to_dead(tp, t);
416 break;
417 case TAP_EVENT_TIMEOUT:
418 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
419 break;
420 case TAP_EVENT_BUTTON:
421 tp->tap.state = TAP_STATE_DEAD;
422 break;
423 case TAP_EVENT_THUMB:
424 break;
425 case TAP_EVENT_PALM:
426 tp->tap.state = TAP_STATE_HOLD;
427 break;
428 case TAP_EVENT_PALM_UP:
429 break;
430 }
431 }
432
433 static void
tp_tap_touch2_release_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)434 tp_tap_touch2_release_handle_event(struct tp_dispatch *tp,
435 struct tp_touch *t,
436 enum tap_event event, uint64_t time)
437 {
438
439 switch (event) {
440 case TAP_EVENT_TOUCH:
441 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
442 t->tap.state = TAP_TOUCH_STATE_DEAD;
443 tp_tap_clear_timer(tp);
444 break;
445 case TAP_EVENT_RELEASE:
446 tp_tap_notify(tp,
447 tp->tap.saved_press_time,
448 2,
449 LIBINPUT_BUTTON_STATE_PRESSED);
450 if (tp->tap.drag_enabled) {
451 tp->tap.state = TAP_STATE_2FGTAP_TAPPED;
452 tp_tap_set_drag_timer(tp, time, 2);
453 } else {
454 tp_tap_notify(tp,
455 tp->tap.saved_release_time,
456 2,
457 LIBINPUT_BUTTON_STATE_RELEASED);
458 tp->tap.state = TAP_STATE_IDLE;
459 }
460 break;
461 case TAP_EVENT_MOTION:
462 tp_tap_move_to_dead(tp, t);
463 break;
464 case TAP_EVENT_TIMEOUT:
465 tp->tap.state = TAP_STATE_HOLD;
466 break;
467 case TAP_EVENT_BUTTON:
468 tp->tap.state = TAP_STATE_DEAD;
469 break;
470 case TAP_EVENT_THUMB:
471 break;
472 case TAP_EVENT_PALM:
473 /* There's only one saved press time and it's overwritten by
474 * the last touch down. So in the case of finger down, palm
475 * down, finger up, palm detected, we use the
476 * palm touch's press time here instead of the finger's press
477 * time. Let's wait and see if that's an issue.
478 */
479 tp_tap_notify(tp,
480 tp->tap.saved_press_time,
481 1,
482 LIBINPUT_BUTTON_STATE_PRESSED);
483 if (tp->tap.drag_enabled) {
484 /* For a single-finger tap the timer delay is the same
485 * as for the release of the finger that became a palm,
486 * no reset necessary */
487 tp->tap.state = TAP_STATE_1FGTAP_TAPPED;
488 } else {
489 tp_tap_notify(tp,
490 tp->tap.saved_release_time,
491 1,
492 LIBINPUT_BUTTON_STATE_RELEASED);
493 tp->tap.state = TAP_STATE_IDLE;
494 }
495 break;
496 case TAP_EVENT_PALM_UP:
497 break;
498 }
499 }
500
501 static void
tp_tap_touch3_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)502 tp_tap_touch3_handle_event(struct tp_dispatch *tp,
503 struct tp_touch *t,
504 enum tap_event event, uint64_t time)
505 {
506
507 switch (event) {
508 case TAP_EVENT_TOUCH:
509 tp->tap.state = TAP_STATE_DEAD;
510 tp_tap_clear_timer(tp);
511 break;
512 case TAP_EVENT_MOTION:
513 tp_tap_move_to_dead(tp, t);
514 break;
515 case TAP_EVENT_TIMEOUT:
516 tp->tap.state = TAP_STATE_TOUCH_3_HOLD;
517 tp_tap_clear_timer(tp);
518 tp_gesture_tap_timeout(tp, time);
519 break;
520 case TAP_EVENT_RELEASE:
521 tp->tap.state = TAP_STATE_TOUCH_3_RELEASE;
522 tp->tap.saved_release_time = time;
523 tp_tap_set_timer(tp, time);
524 break;
525 case TAP_EVENT_BUTTON:
526 tp->tap.state = TAP_STATE_DEAD;
527 break;
528 case TAP_EVENT_THUMB:
529 break;
530 case TAP_EVENT_PALM:
531 tp->tap.state = TAP_STATE_TOUCH_2;
532 break;
533 case TAP_EVENT_PALM_UP:
534 break;
535 }
536 }
537
538 static void
tp_tap_touch3_hold_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)539 tp_tap_touch3_hold_handle_event(struct tp_dispatch *tp,
540 struct tp_touch *t,
541 enum tap_event event, uint64_t time)
542 {
543
544 switch (event) {
545 case TAP_EVENT_TOUCH:
546 tp->tap.state = TAP_STATE_DEAD;
547 tp_tap_set_timer(tp, time);
548 break;
549 case TAP_EVENT_RELEASE:
550 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
551 break;
552 case TAP_EVENT_MOTION:
553 tp_tap_move_to_dead(tp, t);
554 break;
555 case TAP_EVENT_TIMEOUT:
556 break;
557 case TAP_EVENT_BUTTON:
558 tp->tap.state = TAP_STATE_DEAD;
559 break;
560 case TAP_EVENT_THUMB:
561 break;
562 case TAP_EVENT_PALM:
563 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
564 break;
565 case TAP_EVENT_PALM_UP:
566 break;
567 }
568 }
569
570 static void
tp_tap_touch3_release_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)571 tp_tap_touch3_release_handle_event(struct tp_dispatch *tp,
572 struct tp_touch *t,
573 enum tap_event event, uint64_t time)
574 {
575
576 switch (event) {
577 case TAP_EVENT_TOUCH:
578 tp_tap_notify(tp,
579 tp->tap.saved_press_time,
580 3,
581 LIBINPUT_BUTTON_STATE_PRESSED);
582 tp_tap_notify(tp,
583 tp->tap.saved_release_time,
584 3,
585 LIBINPUT_BUTTON_STATE_RELEASED);
586 tp->tap.state = TAP_STATE_TOUCH_3;
587 tp->tap.saved_press_time = time;
588 tp_tap_set_timer(tp, time);
589 break;
590 case TAP_EVENT_RELEASE:
591 tp->tap.state = TAP_STATE_TOUCH_3_RELEASE_2;
592 tp_tap_set_timer(tp, time);
593 break;
594 case TAP_EVENT_MOTION:
595 tp_tap_notify(tp,
596 tp->tap.saved_press_time,
597 3,
598 LIBINPUT_BUTTON_STATE_PRESSED);
599 tp_tap_notify(tp,
600 tp->tap.saved_release_time,
601 3,
602 LIBINPUT_BUTTON_STATE_RELEASED);
603 tp_tap_move_to_dead(tp, t);
604 break;
605 case TAP_EVENT_TIMEOUT:
606 tp_tap_notify(tp,
607 tp->tap.saved_press_time,
608 3,
609 LIBINPUT_BUTTON_STATE_PRESSED);
610 tp_tap_notify(tp,
611 tp->tap.saved_release_time,
612 3,
613 LIBINPUT_BUTTON_STATE_RELEASED);
614 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
615 break;
616 case TAP_EVENT_BUTTON:
617 tp_tap_notify(tp,
618 tp->tap.saved_press_time,
619 3,
620 LIBINPUT_BUTTON_STATE_PRESSED);
621 tp_tap_notify(tp,
622 tp->tap.saved_release_time,
623 3,
624 LIBINPUT_BUTTON_STATE_RELEASED);
625 tp->tap.state = TAP_STATE_DEAD;
626 break;
627 case TAP_EVENT_THUMB:
628 break;
629 case TAP_EVENT_PALM:
630 tp->tap.state = TAP_STATE_TOUCH_2_RELEASE;
631 break;
632 case TAP_EVENT_PALM_UP:
633 break;
634 }
635 }
636
637 static void
tp_tap_touch3_release2_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)638 tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp,
639 struct tp_touch *t,
640 enum tap_event event, uint64_t time)
641 {
642
643 switch (event) {
644 case TAP_EVENT_TOUCH:
645 tp_tap_notify(tp,
646 tp->tap.saved_press_time,
647 3,
648 LIBINPUT_BUTTON_STATE_PRESSED);
649 tp_tap_notify(tp,
650 tp->tap.saved_release_time,
651 3,
652 LIBINPUT_BUTTON_STATE_RELEASED);
653 tp->tap.state = TAP_STATE_TOUCH_2;
654 tp->tap.saved_press_time = time;
655 tp_tap_set_timer(tp, time);
656 break;
657 case TAP_EVENT_RELEASE:
658 tp_tap_notify(tp,
659 tp->tap.saved_press_time,
660 3,
661 LIBINPUT_BUTTON_STATE_PRESSED);
662 if (tp->tap.drag_enabled) {
663 tp->tap.state = TAP_STATE_3FGTAP_TAPPED;
664 tp_tap_set_drag_timer(tp, time, 3);
665 } else {
666 tp_tap_notify(tp,
667 tp->tap.saved_release_time,
668 3,
669 LIBINPUT_BUTTON_STATE_RELEASED);
670 tp->tap.state = TAP_STATE_IDLE;
671 }
672 break;
673 case TAP_EVENT_MOTION:
674 tp_tap_notify(tp,
675 tp->tap.saved_press_time,
676 3,
677 LIBINPUT_BUTTON_STATE_PRESSED);
678 tp_tap_notify(tp,
679 tp->tap.saved_release_time,
680 3,
681 LIBINPUT_BUTTON_STATE_RELEASED);
682 tp_tap_move_to_dead(tp, t);
683 break;
684 case TAP_EVENT_TIMEOUT:
685 tp_tap_notify(tp,
686 tp->tap.saved_press_time,
687 3,
688 LIBINPUT_BUTTON_STATE_PRESSED);
689 tp_tap_notify(tp,
690 tp->tap.saved_release_time,
691 3,
692 LIBINPUT_BUTTON_STATE_RELEASED);
693 tp->tap.state = TAP_STATE_HOLD;
694 break;
695 case TAP_EVENT_BUTTON:
696 tp_tap_notify(tp,
697 tp->tap.saved_press_time,
698 3,
699 LIBINPUT_BUTTON_STATE_PRESSED);
700 tp_tap_notify(tp,
701 tp->tap.saved_release_time,
702 3,
703 LIBINPUT_BUTTON_STATE_RELEASED);
704 tp->tap.state = TAP_STATE_DEAD;
705 break;
706 case TAP_EVENT_THUMB:
707 break;
708 case TAP_EVENT_PALM:
709 tp_tap_notify(tp,
710 tp->tap.saved_press_time,
711 2,
712 LIBINPUT_BUTTON_STATE_PRESSED);
713 if (tp->tap.drag_enabled) {
714 /* Resetting the timer to the appropriate delay
715 * for a two-finger tap would be ideal, but the
716 * timestamp of the last real finger release is lost,
717 * so the in-progress similar delay for release
718 * of the finger which became a palm instead
719 * will have to do */
720 tp->tap.state = TAP_STATE_2FGTAP_TAPPED;
721 } else {
722 tp_tap_notify(tp,
723 tp->tap.saved_release_time,
724 2,
725 LIBINPUT_BUTTON_STATE_RELEASED);
726 tp->tap.state = TAP_STATE_IDLE;
727 }
728 break;
729 case TAP_EVENT_PALM_UP:
730 break;
731 }
732 }
733
734 static void
tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time,int nfingers_tapped)735 tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
736 struct tp_touch *t,
737 enum tap_event event, uint64_t time,
738 int nfingers_tapped)
739 {
740 switch (event) {
741 case TAP_EVENT_TOUCH: {
742 tp_tap_notify(tp,
743 tp->tap.saved_release_time,
744 nfingers_tapped,
745 LIBINPUT_BUTTON_STATE_RELEASED);
746 tp->tap.state = TAP_STATE_TOUCH_2;
747 tp->tap.saved_press_time = time;
748 tp_tap_set_timer(tp, time);
749 break;
750 }
751 case TAP_EVENT_RELEASE:
752 tp->tap.state = TAP_STATE_1FGTAP_TAPPED;
753 tp_tap_notify(tp,
754 tp->tap.saved_release_time,
755 nfingers_tapped,
756 LIBINPUT_BUTTON_STATE_RELEASED);
757 tp_tap_notify(tp,
758 tp->tap.saved_press_time,
759 1,
760 LIBINPUT_BUTTON_STATE_PRESSED);
761 tp->tap.saved_release_time = time;
762 tp_tap_set_timer(tp, time);
763 break;
764 case TAP_EVENT_MOTION:
765 case TAP_EVENT_TIMEOUT: {
766 enum tp_tap_state dest[3] = {
767 TAP_STATE_1FGTAP_DRAGGING,
768 TAP_STATE_2FGTAP_DRAGGING,
769 TAP_STATE_3FGTAP_DRAGGING,
770 };
771 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
772 tp->tap.state = dest[nfingers_tapped - 1];
773 break;
774 }
775 case TAP_EVENT_BUTTON:
776 tp->tap.state = TAP_STATE_DEAD;
777 tp_tap_notify(tp,
778 tp->tap.saved_release_time,
779 nfingers_tapped,
780 LIBINPUT_BUTTON_STATE_RELEASED);
781 break;
782 case TAP_EVENT_THUMB:
783 break;
784 case TAP_EVENT_PALM: {
785 enum tp_tap_state dest[3] = {
786 TAP_STATE_1FGTAP_TAPPED,
787 TAP_STATE_2FGTAP_TAPPED,
788 TAP_STATE_3FGTAP_TAPPED,
789 };
790 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
791 tp->tap.state = dest[nfingers_tapped - 1];
792 break;
793 }
794 case TAP_EVENT_PALM_UP:
795 break;
796 }
797 }
798
799 static void
tp_tap_dragging_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time,int nfingers_tapped)800 tp_tap_dragging_handle_event(struct tp_dispatch *tp,
801 struct tp_touch *t,
802 enum tap_event event, uint64_t time,
803 int nfingers_tapped)
804 {
805
806 switch (event) {
807 case TAP_EVENT_TOUCH: {
808 enum tp_tap_state dest[3] = {
809 TAP_STATE_1FGTAP_DRAGGING_2,
810 TAP_STATE_2FGTAP_DRAGGING_2,
811 TAP_STATE_3FGTAP_DRAGGING_2,
812 };
813 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
814 tp->tap.state = dest[nfingers_tapped - 1];
815 break;
816 }
817 case TAP_EVENT_RELEASE:
818 if (tp->tap.drag_lock_enabled) {
819 enum tp_tap_state dest[3] = {
820 TAP_STATE_1FGTAP_DRAGGING_WAIT,
821 TAP_STATE_2FGTAP_DRAGGING_WAIT,
822 TAP_STATE_3FGTAP_DRAGGING_WAIT,
823 };
824 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
825 tp->tap.state = dest[nfingers_tapped - 1];
826 tp_tap_set_draglock_timer(tp, time);
827 } else {
828 tp_tap_notify(tp,
829 time,
830 nfingers_tapped,
831 LIBINPUT_BUTTON_STATE_RELEASED);
832 tp->tap.state = TAP_STATE_IDLE;
833 }
834 break;
835 case TAP_EVENT_MOTION:
836 case TAP_EVENT_TIMEOUT:
837 /* noop */
838 break;
839 case TAP_EVENT_BUTTON:
840 tp->tap.state = TAP_STATE_DEAD;
841 tp_tap_notify(tp,
842 time,
843 nfingers_tapped,
844 LIBINPUT_BUTTON_STATE_RELEASED);
845 break;
846 case TAP_EVENT_THUMB:
847 break;
848 case TAP_EVENT_PALM:
849 tp_tap_notify(tp,
850 tp->tap.saved_release_time,
851 nfingers_tapped,
852 LIBINPUT_BUTTON_STATE_RELEASED);
853 tp->tap.state = TAP_STATE_IDLE;
854 break;
855 case TAP_EVENT_PALM_UP:
856 break;
857 }
858 }
859
860 static void
tp_tap_dragging_wait_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time,int nfingers_tapped)861 tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp,
862 struct tp_touch *t,
863 enum tap_event event, uint64_t time,
864 int nfingers_tapped)
865 {
866
867 switch (event) {
868 case TAP_EVENT_TOUCH: {
869 enum tp_tap_state dest[3] = {
870 TAP_STATE_1FGTAP_DRAGGING_OR_TAP,
871 TAP_STATE_2FGTAP_DRAGGING_OR_TAP,
872 TAP_STATE_3FGTAP_DRAGGING_OR_TAP,
873 };
874 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
875 tp->tap.state = dest[nfingers_tapped - 1];
876 tp_tap_set_timer(tp, time);
877 break;
878 }
879 case TAP_EVENT_RELEASE:
880 case TAP_EVENT_MOTION:
881 log_tap_bug(tp, t, event);
882 break;
883 case TAP_EVENT_TIMEOUT:
884 tp->tap.state = TAP_STATE_IDLE;
885 tp_tap_notify(tp,
886 time,
887 nfingers_tapped,
888 LIBINPUT_BUTTON_STATE_RELEASED);
889 break;
890 case TAP_EVENT_BUTTON:
891 tp->tap.state = TAP_STATE_DEAD;
892 tp_tap_notify(tp,
893 time,
894 nfingers_tapped,
895 LIBINPUT_BUTTON_STATE_RELEASED);
896 break;
897 case TAP_EVENT_THUMB:
898 case TAP_EVENT_PALM:
899 log_tap_bug(tp, t, event);
900 break;
901 case TAP_EVENT_PALM_UP:
902 break;
903 }
904 }
905
906 static void
tp_tap_dragging_tap_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time,int nfingers_tapped)907 tp_tap_dragging_tap_handle_event(struct tp_dispatch *tp,
908 struct tp_touch *t,
909 enum tap_event event, uint64_t time,
910 int nfingers_tapped)
911 {
912
913 switch (event) {
914 case TAP_EVENT_TOUCH: {
915 tp_tap_notify(tp,
916 time,
917 nfingers_tapped,
918 LIBINPUT_BUTTON_STATE_RELEASED);
919 tp_tap_clear_timer(tp);
920 tp_tap_move_to_dead(tp, t);
921 break;
922 }
923 case TAP_EVENT_RELEASE:
924 tp->tap.state = TAP_STATE_IDLE;
925 tp_tap_notify(tp,
926 time,
927 nfingers_tapped,
928 LIBINPUT_BUTTON_STATE_RELEASED);
929 break;
930 case TAP_EVENT_MOTION:
931 case TAP_EVENT_TIMEOUT: {
932 enum tp_tap_state dest[3] = {
933 TAP_STATE_1FGTAP_DRAGGING,
934 TAP_STATE_2FGTAP_DRAGGING,
935 TAP_STATE_3FGTAP_DRAGGING,
936 };
937 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
938 tp->tap.state = dest[nfingers_tapped - 1];
939 break;
940 }
941 case TAP_EVENT_BUTTON:
942 tp->tap.state = TAP_STATE_DEAD;
943 tp_tap_notify(tp,
944 time,
945 nfingers_tapped,
946 LIBINPUT_BUTTON_STATE_RELEASED);
947 break;
948 case TAP_EVENT_THUMB:
949 break;
950 case TAP_EVENT_PALM: {
951 enum tp_tap_state dest[3] = {
952 TAP_STATE_1FGTAP_DRAGGING_WAIT,
953 TAP_STATE_2FGTAP_DRAGGING_WAIT,
954 TAP_STATE_3FGTAP_DRAGGING_WAIT,
955 };
956 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
957 tp->tap.state = dest[nfingers_tapped - 1];
958 break;
959 }
960 case TAP_EVENT_PALM_UP:
961 break;
962 }
963 }
964
965 static void
tp_tap_dragging2_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time,int nfingers_tapped)966 tp_tap_dragging2_handle_event(struct tp_dispatch *tp,
967 struct tp_touch *t,
968 enum tap_event event, uint64_t time,
969 int nfingers_tapped)
970 {
971
972 switch (event) {
973 case TAP_EVENT_RELEASE: {
974 enum tp_tap_state dest[3] = {
975 TAP_STATE_1FGTAP_DRAGGING,
976 TAP_STATE_2FGTAP_DRAGGING,
977 TAP_STATE_3FGTAP_DRAGGING,
978 };
979 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
980 tp->tap.state = dest[nfingers_tapped - 1];
981 break;
982 }
983 case TAP_EVENT_TOUCH:
984 tp->tap.state = TAP_STATE_DEAD;
985 tp_tap_notify(tp,
986 time,
987 nfingers_tapped,
988 LIBINPUT_BUTTON_STATE_RELEASED);
989 break;
990 case TAP_EVENT_MOTION:
991 case TAP_EVENT_TIMEOUT:
992 /* noop */
993 break;
994 case TAP_EVENT_BUTTON:
995 tp->tap.state = TAP_STATE_DEAD;
996 tp_tap_notify(tp,
997 time,
998 nfingers_tapped,
999 LIBINPUT_BUTTON_STATE_RELEASED);
1000 break;
1001 case TAP_EVENT_THUMB:
1002 break;
1003 case TAP_EVENT_PALM: {
1004 enum tp_tap_state dest[3] = {
1005 TAP_STATE_1FGTAP_DRAGGING,
1006 TAP_STATE_2FGTAP_DRAGGING,
1007 TAP_STATE_3FGTAP_DRAGGING,
1008 };
1009 assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
1010 tp->tap.state = dest[nfingers_tapped - 1];
1011 break;
1012 }
1013 case TAP_EVENT_PALM_UP:
1014 break;
1015 }
1016 }
1017
1018 static void
tp_tap_dead_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)1019 tp_tap_dead_handle_event(struct tp_dispatch *tp,
1020 struct tp_touch *t,
1021 enum tap_event event,
1022 uint64_t time)
1023 {
1024
1025 switch (event) {
1026 case TAP_EVENT_RELEASE:
1027 if (tp->tap.nfingers_down == 0)
1028 tp->tap.state = TAP_STATE_IDLE;
1029 break;
1030 case TAP_EVENT_TOUCH:
1031 case TAP_EVENT_MOTION:
1032 case TAP_EVENT_TIMEOUT:
1033 case TAP_EVENT_BUTTON:
1034 break;
1035 case TAP_EVENT_THUMB:
1036 break;
1037 case TAP_EVENT_PALM:
1038 case TAP_EVENT_PALM_UP:
1039 if (tp->tap.nfingers_down == 0)
1040 tp->tap.state = TAP_STATE_IDLE;
1041 break;
1042 }
1043 }
1044
1045 static void
tp_tap_handle_event(struct tp_dispatch * tp,struct tp_touch * t,enum tap_event event,uint64_t time)1046 tp_tap_handle_event(struct tp_dispatch *tp,
1047 struct tp_touch *t,
1048 enum tap_event event,
1049 uint64_t time)
1050 {
1051 enum tp_tap_state current;
1052
1053 current = tp->tap.state;
1054
1055 switch(tp->tap.state) {
1056 case TAP_STATE_IDLE:
1057 tp_tap_idle_handle_event(tp, t, event, time);
1058 break;
1059 case TAP_STATE_TOUCH:
1060 tp_tap_touch_handle_event(tp, t, event, time);
1061 break;
1062 case TAP_STATE_HOLD:
1063 tp_tap_hold_handle_event(tp, t, event, time);
1064 break;
1065 case TAP_STATE_1FGTAP_TAPPED:
1066 tp_tap_tapped_handle_event(tp, t, event, time, 1);
1067 break;
1068 case TAP_STATE_2FGTAP_TAPPED:
1069 tp_tap_tapped_handle_event(tp, t, event, time, 2);
1070 break;
1071 case TAP_STATE_3FGTAP_TAPPED:
1072 tp_tap_tapped_handle_event(tp, t, event, time, 3);
1073 break;
1074 case TAP_STATE_TOUCH_2:
1075 tp_tap_touch2_handle_event(tp, t, event, time);
1076 break;
1077 case TAP_STATE_TOUCH_2_HOLD:
1078 tp_tap_touch2_hold_handle_event(tp, t, event, time);
1079 break;
1080 case TAP_STATE_TOUCH_2_RELEASE:
1081 tp_tap_touch2_release_handle_event(tp, t, event, time);
1082 break;
1083 case TAP_STATE_TOUCH_3:
1084 tp_tap_touch3_handle_event(tp, t, event, time);
1085 break;
1086 case TAP_STATE_TOUCH_3_HOLD:
1087 tp_tap_touch3_hold_handle_event(tp, t, event, time);
1088 break;
1089 case TAP_STATE_TOUCH_3_RELEASE:
1090 tp_tap_touch3_release_handle_event(tp, t, event, time);
1091 break;
1092 case TAP_STATE_TOUCH_3_RELEASE_2:
1093 tp_tap_touch3_release2_handle_event(tp, t, event, time);
1094 break;
1095 case TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP:
1096 tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time,
1097 1);
1098 break;
1099 case TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP:
1100 tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time,
1101 2);
1102 break;
1103 case TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP:
1104 tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time,
1105 3);
1106 break;
1107 case TAP_STATE_1FGTAP_DRAGGING:
1108 tp_tap_dragging_handle_event(tp, t, event, time, 1);
1109 break;
1110 case TAP_STATE_2FGTAP_DRAGGING:
1111 tp_tap_dragging_handle_event(tp, t, event, time, 2);
1112 break;
1113 case TAP_STATE_3FGTAP_DRAGGING:
1114 tp_tap_dragging_handle_event(tp, t, event, time, 3);
1115 break;
1116 case TAP_STATE_1FGTAP_DRAGGING_WAIT:
1117 tp_tap_dragging_wait_handle_event(tp, t, event, time, 1);
1118 break;
1119 case TAP_STATE_2FGTAP_DRAGGING_WAIT:
1120 tp_tap_dragging_wait_handle_event(tp, t, event, time, 2);
1121 break;
1122 case TAP_STATE_3FGTAP_DRAGGING_WAIT:
1123 tp_tap_dragging_wait_handle_event(tp, t, event, time, 3);
1124 break;
1125 case TAP_STATE_1FGTAP_DRAGGING_OR_TAP:
1126 tp_tap_dragging_tap_handle_event(tp, t, event, time, 1);
1127 break;
1128 case TAP_STATE_2FGTAP_DRAGGING_OR_TAP:
1129 tp_tap_dragging_tap_handle_event(tp, t, event, time, 2);
1130 break;
1131 case TAP_STATE_3FGTAP_DRAGGING_OR_TAP:
1132 tp_tap_dragging_tap_handle_event(tp, t, event, time, 3);
1133 break;
1134 case TAP_STATE_1FGTAP_DRAGGING_2:
1135 tp_tap_dragging2_handle_event(tp, t, event, time, 1);
1136 break;
1137 case TAP_STATE_2FGTAP_DRAGGING_2:
1138 tp_tap_dragging2_handle_event(tp, t, event, time, 2);
1139 break;
1140 case TAP_STATE_3FGTAP_DRAGGING_2:
1141 tp_tap_dragging2_handle_event(tp, t, event, time, 3);
1142 break;
1143 case TAP_STATE_DEAD:
1144 tp_tap_dead_handle_event(tp, t, event, time);
1145 break;
1146 }
1147
1148 if (tp->tap.state == TAP_STATE_IDLE || tp->tap.state == TAP_STATE_DEAD)
1149 tp_tap_clear_timer(tp);
1150
1151 if (current != tp->tap.state)
1152 evdev_log_debug(tp->device,
1153 "tap: touch %d (%s), tap state %s → %s → %s\n",
1154 t ? (int)t->index : -1,
1155 t ? touch_state_to_str(t->state) : "",
1156 tap_state_to_str(current),
1157 tap_event_to_str(event),
1158 tap_state_to_str(tp->tap.state));
1159 }
1160
1161 static bool
tp_tap_exceeds_motion_threshold(struct tp_dispatch * tp,struct tp_touch * t)1162 tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp,
1163 struct tp_touch *t)
1164 {
1165 struct phys_coords mm =
1166 tp_phys_delta(tp, device_delta(t->point, t->tap.initial));
1167
1168 /* if we have more fingers down than slots, we know that synaptics
1169 * touchpads are likely to give us pointer jumps.
1170 * This triggers the movement threshold, making three-finger taps
1171 * less reliable (#101435)
1172 *
1173 * This uses the real nfingers_down, not the one for taps.
1174 */
1175 if (tp->device->model_flags & EVDEV_MODEL_SYNAPTICS_SERIAL_TOUCHPAD &&
1176 (tp->nfingers_down > 2 || tp->old_nfingers_down > 2) &&
1177 (tp->nfingers_down > tp->num_slots ||
1178 tp->old_nfingers_down > tp->num_slots)) {
1179 return false;
1180 }
1181
1182 /* Semi-mt devices will give us large movements on finger release,
1183 * depending which touch is released. Make sure we ignore any
1184 * movement in the same frame as a finger change.
1185 */
1186 if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
1187 return false;
1188
1189 return length_in_mm(mm) > DEFAULT_TAP_MOVE_THRESHOLD;
1190 }
1191
1192 static bool
tp_tap_enabled(struct tp_dispatch * tp)1193 tp_tap_enabled(struct tp_dispatch *tp)
1194 {
1195 return tp->tap.enabled && !tp->tap.suspended;
1196 }
1197
1198 int
tp_tap_handle_state(struct tp_dispatch * tp,uint64_t time)1199 tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
1200 {
1201 struct tp_touch *t;
1202 int filter_motion = 0;
1203
1204 if (!tp_tap_enabled(tp))
1205 return 0;
1206
1207 /* Handle queued button pressed events from clickpads. For touchpads
1208 * with separate physical buttons, ignore button pressed events so they
1209 * don't interfere with tapping. */
1210 if (tp->buttons.is_clickpad && tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
1211 tp_tap_handle_event(tp, NULL, TAP_EVENT_BUTTON, time);
1212
1213 tp_for_each_touch(tp, t) {
1214 if (!t->dirty || t->state == TOUCH_NONE)
1215 continue;
1216
1217 if (tp->buttons.is_clickpad &&
1218 tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
1219 t->tap.state = TAP_TOUCH_STATE_DEAD;
1220
1221 /* If a touch was considered thumb for tapping once, we
1222 * ignore it for the rest of lifetime */
1223 if (t->tap.is_thumb)
1224 continue;
1225
1226 /* A palm tap needs to be properly released because we might
1227 * be who-knows-where in the state machine. Otherwise, we
1228 * ignore any event from it.
1229 */
1230 if (t->tap.is_palm) {
1231 if (t->state == TOUCH_END)
1232 tp_tap_handle_event(tp,
1233 t,
1234 TAP_EVENT_PALM_UP,
1235 time);
1236 continue;
1237 }
1238
1239 if (t->state == TOUCH_HOVERING)
1240 continue;
1241
1242 if (t->palm.state != PALM_NONE) {
1243 assert(!t->tap.is_palm);
1244 t->tap.is_palm = true;
1245 t->tap.state = TAP_TOUCH_STATE_DEAD;
1246 if (t->state != TOUCH_BEGIN) {
1247 tp_tap_handle_event(tp, t, TAP_EVENT_PALM, time);
1248 assert(tp->tap.nfingers_down > 0);
1249 tp->tap.nfingers_down--;
1250 }
1251 } else if (t->state == TOUCH_BEGIN) {
1252 /* The simple version: if a touch is a thumb on
1253 * begin we ignore it. All other thumb touches
1254 * follow the normal tap state for now */
1255 if (tp_thumb_ignored_for_tap(tp, t)) {
1256 t->tap.is_thumb = true;
1257 continue;
1258 }
1259
1260 t->tap.state = TAP_TOUCH_STATE_TOUCH;
1261 t->tap.initial = t->point;
1262 tp->tap.nfingers_down++;
1263 tp_tap_handle_event(tp, t, TAP_EVENT_TOUCH, time);
1264
1265 /* If we think this is a palm, pretend there's a
1266 * motion event which will prevent tap clicks
1267 * without requiring extra states in the FSM.
1268 */
1269 if (tp_palm_tap_is_palm(tp, t))
1270 tp_tap_handle_event(tp, t, TAP_EVENT_MOTION, time);
1271
1272 } else if (t->state == TOUCH_END) {
1273 if (t->was_down) {
1274 assert(tp->tap.nfingers_down >= 1);
1275 tp->tap.nfingers_down--;
1276 tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);
1277 }
1278 t->tap.state = TAP_TOUCH_STATE_IDLE;
1279 } else if (tp->tap.state != TAP_STATE_IDLE &&
1280 tp_thumb_ignored(tp, t)) {
1281 tp_tap_handle_event(tp, t, TAP_EVENT_THUMB, time);
1282 } else if (tp->tap.state != TAP_STATE_IDLE &&
1283 tp_tap_exceeds_motion_threshold(tp, t)) {
1284 struct tp_touch *tmp;
1285
1286 /* Any touch exceeding the threshold turns all
1287 * touches into DEAD */
1288 tp_for_each_touch(tp, tmp) {
1289 if (tmp->tap.state == TAP_TOUCH_STATE_TOUCH)
1290 tmp->tap.state = TAP_TOUCH_STATE_DEAD;
1291 }
1292
1293 tp_tap_handle_event(tp, t, TAP_EVENT_MOTION, time);
1294 }
1295 }
1296
1297 /**
1298 * In any state where motion exceeding the move threshold would
1299 * move to the next state, filter that motion until we actually
1300 * exceed it. This prevents small motion events while we're waiting
1301 * on a decision if a tap is a tap.
1302 */
1303 switch (tp->tap.state) {
1304 case TAP_STATE_TOUCH:
1305 case TAP_STATE_1FGTAP_TAPPED:
1306 case TAP_STATE_2FGTAP_TAPPED:
1307 case TAP_STATE_3FGTAP_TAPPED:
1308 case TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP:
1309 case TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP:
1310 case TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP:
1311 case TAP_STATE_1FGTAP_DRAGGING_OR_TAP:
1312 case TAP_STATE_2FGTAP_DRAGGING_OR_TAP:
1313 case TAP_STATE_3FGTAP_DRAGGING_OR_TAP:
1314 case TAP_STATE_TOUCH_2:
1315 case TAP_STATE_TOUCH_3:
1316 filter_motion = 1;
1317 break;
1318
1319 default:
1320 break;
1321
1322 }
1323
1324 assert(tp->tap.nfingers_down <= tp->nfingers_down);
1325 if (tp->nfingers_down == 0)
1326 assert(tp->tap.nfingers_down == 0);
1327
1328 return filter_motion;
1329 }
1330
1331 static inline void
tp_tap_update_map(struct tp_dispatch * tp)1332 tp_tap_update_map(struct tp_dispatch *tp)
1333 {
1334 if (tp->tap.state != TAP_STATE_IDLE)
1335 return;
1336
1337 if (tp->tap.map != tp->tap.want_map)
1338 tp->tap.map = tp->tap.want_map;
1339 }
1340
1341 void
tp_tap_post_process_state(struct tp_dispatch * tp)1342 tp_tap_post_process_state(struct tp_dispatch *tp)
1343 {
1344 tp_tap_update_map(tp);
1345 }
1346
1347 static void
tp_tap_handle_timeout(uint64_t time,void * data)1348 tp_tap_handle_timeout(uint64_t time, void *data)
1349 {
1350 struct tp_dispatch *tp = data;
1351 struct tp_touch *t;
1352
1353 tp_tap_handle_event(tp, NULL, TAP_EVENT_TIMEOUT, time);
1354
1355 tp_for_each_touch(tp, t) {
1356 if (t->state == TOUCH_NONE ||
1357 t->tap.state == TAP_TOUCH_STATE_IDLE)
1358 continue;
1359
1360 t->tap.state = TAP_TOUCH_STATE_DEAD;
1361 }
1362 }
1363
1364 static void
tp_tap_enabled_update(struct tp_dispatch * tp,bool suspended,bool enabled,uint64_t time)1365 tp_tap_enabled_update(struct tp_dispatch *tp, bool suspended, bool enabled, uint64_t time)
1366 {
1367 bool was_enabled = tp_tap_enabled(tp);
1368
1369 tp->tap.suspended = suspended;
1370 tp->tap.enabled = enabled;
1371
1372 if (tp_tap_enabled(tp) == was_enabled)
1373 return;
1374
1375 if (tp_tap_enabled(tp)) {
1376 struct tp_touch *t;
1377
1378 /* On resume, all touches are considered palms */
1379 tp_for_each_touch(tp, t) {
1380 if (t->state == TOUCH_NONE)
1381 continue;
1382
1383 t->tap.is_palm = true;
1384 t->tap.state = TAP_TOUCH_STATE_DEAD;
1385 }
1386
1387 tp->tap.state = TAP_STATE_IDLE;
1388 tp->tap.nfingers_down = 0;
1389 } else {
1390 tp_release_all_taps(tp, time);
1391 }
1392 }
1393
1394 static int
tp_tap_config_count(struct libinput_device * device)1395 tp_tap_config_count(struct libinput_device *device)
1396 {
1397 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1398 struct tp_dispatch *tp = tp_dispatch(dispatch);
1399
1400 return min(tp->ntouches, 3U); /* we only do up to 3 finger tap */
1401 }
1402
1403 static enum libinput_config_status
tp_tap_config_set_enabled(struct libinput_device * device,enum libinput_config_tap_state enabled)1404 tp_tap_config_set_enabled(struct libinput_device *device,
1405 enum libinput_config_tap_state enabled)
1406 {
1407 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1408 struct tp_dispatch *tp = tp_dispatch(dispatch);
1409
1410 tp_tap_enabled_update(tp, tp->tap.suspended,
1411 (enabled == LIBINPUT_CONFIG_TAP_ENABLED),
1412 libinput_now(device->seat->libinput));
1413
1414 return LIBINPUT_CONFIG_STATUS_SUCCESS;
1415 }
1416
1417 static enum libinput_config_tap_state
tp_tap_config_is_enabled(struct libinput_device * device)1418 tp_tap_config_is_enabled(struct libinput_device *device)
1419 {
1420 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1421 struct tp_dispatch *tp = tp_dispatch(dispatch);
1422
1423 return tp->tap.enabled ? LIBINPUT_CONFIG_TAP_ENABLED :
1424 LIBINPUT_CONFIG_TAP_DISABLED;
1425 }
1426
1427 static enum libinput_config_tap_state
tp_tap_default(struct evdev_device * evdev)1428 tp_tap_default(struct evdev_device *evdev)
1429 {
1430 /**
1431 * If we don't have a left button we must have tapping enabled by
1432 * default.
1433 */
1434 if (!libevdev_has_event_code(evdev->evdev, EV_KEY, BTN_LEFT))
1435 return LIBINPUT_CONFIG_TAP_ENABLED;
1436
1437 /**
1438 * Tapping is disabled by default for two reasons:
1439 * * if you don't know that tapping is a thing (or enabled by
1440 * default), you get spurious mouse events that make the desktop
1441 * feel buggy.
1442 * * if you do know what tapping is and you want it, you
1443 * usually know where to enable it, or at least you can search for
1444 * it.
1445 */
1446 return LIBINPUT_CONFIG_TAP_DISABLED;
1447 }
1448
1449 static enum libinput_config_tap_state
tp_tap_config_get_default(struct libinput_device * device)1450 tp_tap_config_get_default(struct libinput_device *device)
1451 {
1452 struct evdev_device *evdev = evdev_device(device);
1453
1454 return tp_tap_default(evdev);
1455 }
1456
1457 static enum libinput_config_status
tp_tap_config_set_map(struct libinput_device * device,enum libinput_config_tap_button_map map)1458 tp_tap_config_set_map(struct libinput_device *device,
1459 enum libinput_config_tap_button_map map)
1460 {
1461 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1462 struct tp_dispatch *tp = tp_dispatch(dispatch);
1463
1464 tp->tap.want_map = map;
1465
1466 tp_tap_update_map(tp);
1467
1468 return LIBINPUT_CONFIG_STATUS_SUCCESS;
1469 }
1470
1471 static enum libinput_config_tap_button_map
tp_tap_config_get_map(struct libinput_device * device)1472 tp_tap_config_get_map(struct libinput_device *device)
1473 {
1474 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1475 struct tp_dispatch *tp = tp_dispatch(dispatch);
1476
1477 return tp->tap.want_map;
1478 }
1479
1480 static enum libinput_config_tap_button_map
tp_tap_config_get_default_map(struct libinput_device * device)1481 tp_tap_config_get_default_map(struct libinput_device *device)
1482 {
1483 return LIBINPUT_CONFIG_TAP_MAP_LRM;
1484 }
1485
1486 static enum libinput_config_status
tp_tap_config_set_drag_enabled(struct libinput_device * device,enum libinput_config_drag_state enabled)1487 tp_tap_config_set_drag_enabled(struct libinput_device *device,
1488 enum libinput_config_drag_state enabled)
1489 {
1490 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1491 struct tp_dispatch *tp = tp_dispatch(dispatch);
1492
1493 tp->tap.drag_enabled = enabled;
1494
1495 return LIBINPUT_CONFIG_STATUS_SUCCESS;
1496 }
1497
1498 static enum libinput_config_drag_state
tp_tap_config_get_drag_enabled(struct libinput_device * device)1499 tp_tap_config_get_drag_enabled(struct libinput_device *device)
1500 {
1501 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1502 struct tp_dispatch *tp = tp_dispatch(dispatch);
1503
1504 return tp->tap.drag_enabled;
1505 }
1506
1507 static inline enum libinput_config_drag_state
tp_drag_default(struct evdev_device * device)1508 tp_drag_default(struct evdev_device *device)
1509 {
1510 return LIBINPUT_CONFIG_DRAG_ENABLED;
1511 }
1512
1513 static enum libinput_config_drag_state
tp_tap_config_get_default_drag_enabled(struct libinput_device * device)1514 tp_tap_config_get_default_drag_enabled(struct libinput_device *device)
1515 {
1516 struct evdev_device *evdev = evdev_device(device);
1517
1518 return tp_drag_default(evdev);
1519 }
1520
1521 static enum libinput_config_status
tp_tap_config_set_draglock_enabled(struct libinput_device * device,enum libinput_config_drag_lock_state enabled)1522 tp_tap_config_set_draglock_enabled(struct libinput_device *device,
1523 enum libinput_config_drag_lock_state enabled)
1524 {
1525 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1526 struct tp_dispatch *tp = tp_dispatch(dispatch);
1527
1528 tp->tap.drag_lock_enabled = enabled;
1529
1530 return LIBINPUT_CONFIG_STATUS_SUCCESS;
1531 }
1532
1533 static enum libinput_config_drag_lock_state
tp_tap_config_get_draglock_enabled(struct libinput_device * device)1534 tp_tap_config_get_draglock_enabled(struct libinput_device *device)
1535 {
1536 struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
1537 struct tp_dispatch *tp = tp_dispatch(dispatch);
1538
1539 return tp->tap.drag_lock_enabled;
1540 }
1541
1542 static inline enum libinput_config_drag_lock_state
tp_drag_lock_default(struct evdev_device * device)1543 tp_drag_lock_default(struct evdev_device *device)
1544 {
1545 return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
1546 }
1547
1548 static enum libinput_config_drag_lock_state
tp_tap_config_get_default_draglock_enabled(struct libinput_device * device)1549 tp_tap_config_get_default_draglock_enabled(struct libinput_device *device)
1550 {
1551 struct evdev_device *evdev = evdev_device(device);
1552
1553 return tp_drag_lock_default(evdev);
1554 }
1555
1556 void
tp_init_tap(struct tp_dispatch * tp)1557 tp_init_tap(struct tp_dispatch *tp)
1558 {
1559 char timer_name[64];
1560
1561 tp->tap.config.count = tp_tap_config_count;
1562 tp->tap.config.set_enabled = tp_tap_config_set_enabled;
1563 tp->tap.config.get_enabled = tp_tap_config_is_enabled;
1564 tp->tap.config.get_default = tp_tap_config_get_default;
1565 tp->tap.config.set_map = tp_tap_config_set_map;
1566 tp->tap.config.get_map = tp_tap_config_get_map;
1567 tp->tap.config.get_default_map = tp_tap_config_get_default_map;
1568 tp->tap.config.set_drag_enabled = tp_tap_config_set_drag_enabled;
1569 tp->tap.config.get_drag_enabled = tp_tap_config_get_drag_enabled;
1570 tp->tap.config.get_default_drag_enabled = tp_tap_config_get_default_drag_enabled;
1571 tp->tap.config.set_draglock_enabled = tp_tap_config_set_draglock_enabled;
1572 tp->tap.config.get_draglock_enabled = tp_tap_config_get_draglock_enabled;
1573 tp->tap.config.get_default_draglock_enabled = tp_tap_config_get_default_draglock_enabled;
1574 tp->device->base.config.tap = &tp->tap.config;
1575
1576 tp->tap.state = TAP_STATE_IDLE;
1577 tp->tap.enabled = tp_tap_default(tp->device);
1578 tp->tap.map = LIBINPUT_CONFIG_TAP_MAP_LRM;
1579 tp->tap.want_map = tp->tap.map;
1580 tp->tap.drag_enabled = tp_drag_default(tp->device);
1581 tp->tap.drag_lock_enabled = tp_drag_lock_default(tp->device);
1582
1583 snprintf(timer_name,
1584 sizeof(timer_name),
1585 "%s tap",
1586 evdev_device_get_sysname(tp->device));
1587 libinput_timer_init(&tp->tap.timer,
1588 tp_libinput_context(tp),
1589 timer_name,
1590 tp_tap_handle_timeout, tp);
1591 }
1592
1593 void
tp_remove_tap(struct tp_dispatch * tp)1594 tp_remove_tap(struct tp_dispatch *tp)
1595 {
1596 libinput_timer_cancel(&tp->tap.timer);
1597 }
1598
1599 void
tp_release_all_taps(struct tp_dispatch * tp,uint64_t now)1600 tp_release_all_taps(struct tp_dispatch *tp, uint64_t now)
1601 {
1602 struct tp_touch *t;
1603 int i;
1604
1605 for (i = 1; i <= 3; i++) {
1606 if (tp->tap.buttons_pressed & (1 << i))
1607 tp_tap_notify(tp, now, i, LIBINPUT_BUTTON_STATE_RELEASED);
1608 }
1609
1610 /* To neutralize all current touches, we make them all palms */
1611 tp_for_each_touch(tp, t) {
1612 if (t->state == TOUCH_NONE)
1613 continue;
1614
1615 if (t->tap.is_palm)
1616 continue;
1617
1618 t->tap.is_palm = true;
1619 t->tap.state = TAP_TOUCH_STATE_DEAD;
1620 }
1621
1622 tp->tap.state = TAP_STATE_IDLE;
1623 tp->tap.nfingers_down = 0;
1624 }
1625
1626 void
tp_tap_suspend(struct tp_dispatch * tp,uint64_t time)1627 tp_tap_suspend(struct tp_dispatch *tp, uint64_t time)
1628 {
1629 tp_tap_enabled_update(tp, true, tp->tap.enabled, time);
1630 }
1631
1632 void
tp_tap_resume(struct tp_dispatch * tp,uint64_t time)1633 tp_tap_resume(struct tp_dispatch *tp, uint64_t time)
1634 {
1635 tp_tap_enabled_update(tp, false, tp->tap.enabled, time);
1636 }
1637
1638 bool
tp_tap_dragging(const struct tp_dispatch * tp)1639 tp_tap_dragging(const struct tp_dispatch *tp)
1640 {
1641 switch (tp->tap.state) {
1642 case TAP_STATE_1FGTAP_DRAGGING:
1643 case TAP_STATE_2FGTAP_DRAGGING:
1644 case TAP_STATE_3FGTAP_DRAGGING:
1645 case TAP_STATE_1FGTAP_DRAGGING_2:
1646 case TAP_STATE_2FGTAP_DRAGGING_2:
1647 case TAP_STATE_3FGTAP_DRAGGING_2:
1648 case TAP_STATE_1FGTAP_DRAGGING_WAIT:
1649 case TAP_STATE_2FGTAP_DRAGGING_WAIT:
1650 case TAP_STATE_3FGTAP_DRAGGING_WAIT:
1651 case TAP_STATE_1FGTAP_DRAGGING_OR_TAP:
1652 case TAP_STATE_2FGTAP_DRAGGING_OR_TAP:
1653 case TAP_STATE_3FGTAP_DRAGGING_OR_TAP:
1654 return true;
1655 default:
1656 return false;
1657 }
1658 }
1659
1660 bool
tp_tap_dragging_or_double_tapping(const struct tp_dispatch * tp)1661 tp_tap_dragging_or_double_tapping(const struct tp_dispatch *tp)
1662 {
1663 switch (tp->tap.state) {
1664 case TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP:
1665 case TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP:
1666 case TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP:
1667 return true;
1668 default:
1669 return false;
1670 }
1671 }
1672