touchpad: add support for multi-finger tapping
[platform/upstream/libinput.git] / src / evdev-mt-touchpad-tap.c
1 /*
2  * Copyright © 2013 Red Hat, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without
6  * fee, provided that the above copyright notice appear in all copies
7  * and that both that copyright notice and this permission notice
8  * appear in supporting documentation, and that the name of Red Hat
9  * not be used in advertising or publicity pertaining to distribution
10  * of the software without specific, written prior permission.  Red
11  * Hat makes no representations about the suitability of this software
12  * for any purpose.  It is provided "as is" without express or implied
13  * warranty.
14  *
15  * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17  * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <assert.h>
29 #include <stdbool.h>
30 #include <stdio.h>
31 #include <time.h>
32 #include <unistd.h>
33 #include <sys/timerfd.h>
34
35 #include "evdev-mt-touchpad.h"
36
37 #define CASE_RETURN_STRING(a) case a: return #a;
38
39 #define DEFAULT_TAP_TIMEOUT_PERIOD 180
40 #define DEFAULT_TAP_MOVE_THRESHOLD 30
41
42 enum tap_event {
43         TAP_EVENT_TOUCH = 12,
44         TAP_EVENT_MOTION,
45         TAP_EVENT_RELEASE,
46         TAP_EVENT_BUTTON,
47         TAP_EVENT_TIMEOUT,
48 };
49
50 /*****************************************
51  * DO NOT EDIT THIS FILE!
52  *
53  * Look at the state diagram in doc/touchpad-tap-state-machine.svg, or
54  * online at
55  * https://drive.google.com/file/d/0B1NwWmji69noYTdMcU1kTUZuUVE/edit?usp=sharing
56  * (it's a http://draw.io diagram)
57  *
58  * Any changes in this file must be represented in the diagram.
59  */
60
61 static inline const char*
62 tap_state_to_str(enum tp_tap_state state) {
63
64         switch(state) {
65         CASE_RETURN_STRING(TAP_STATE_IDLE);
66         CASE_RETURN_STRING(TAP_STATE_HOLD);
67         CASE_RETURN_STRING(TAP_STATE_TOUCH);
68         CASE_RETURN_STRING(TAP_STATE_TAPPED);
69         CASE_RETURN_STRING(TAP_STATE_TOUCH_2);
70         CASE_RETURN_STRING(TAP_STATE_TOUCH_2_HOLD);
71         CASE_RETURN_STRING(TAP_STATE_TOUCH_3);
72         CASE_RETURN_STRING(TAP_STATE_TOUCH_3_HOLD);
73         CASE_RETURN_STRING(TAP_STATE_DRAGGING);
74         CASE_RETURN_STRING(TAP_STATE_DRAGGING_WAIT);
75         CASE_RETURN_STRING(TAP_STATE_DRAGGING_OR_DOUBLETAP);
76         CASE_RETURN_STRING(TAP_STATE_DRAGGING_2);
77         CASE_RETURN_STRING(TAP_STATE_DEAD);
78         }
79         return NULL;
80 }
81
82 static inline const char*
83 tap_event_to_str(enum tap_event event) {
84
85         switch(event) {
86         CASE_RETURN_STRING(TAP_EVENT_TOUCH);
87         CASE_RETURN_STRING(TAP_EVENT_MOTION);
88         CASE_RETURN_STRING(TAP_EVENT_RELEASE);
89         CASE_RETURN_STRING(TAP_EVENT_TIMEOUT);
90         CASE_RETURN_STRING(TAP_EVENT_BUTTON);
91         }
92         return NULL;
93 }
94 #undef CASE_RETURN_STRING
95
96 static void
97 tp_tap_notify(struct tp_dispatch *tp,
98               uint32_t time,
99               int nfingers,
100               enum libinput_pointer_button_state state)
101 {
102         int32_t button;
103
104         switch (nfingers) {
105         case 1: button = BTN_LEFT; break;
106         case 2: button = BTN_RIGHT; break;
107         case 3: button = BTN_MIDDLE; break;
108         default:
109                 return;
110         }
111
112         pointer_notify_button(&tp->device->base,
113                               time,
114                               button,
115                               state);
116 }
117
118 static void
119 tp_tap_set_timer(struct tp_dispatch *tp, uint32_t time)
120 {
121         uint32_t timeout = time + DEFAULT_TAP_TIMEOUT_PERIOD;
122         struct itimerspec its;
123
124         its.it_interval.tv_sec = 0;
125         its.it_interval.tv_nsec = 0;
126         its.it_value.tv_sec = timeout / 1000;
127         its.it_value.tv_nsec = (timeout % 1000) * 1000 * 1000;
128         timerfd_settime(tp->tap.timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
129
130         tp->tap.timeout = timeout;
131 }
132
133 static void
134 tp_tap_clear_timer(struct tp_dispatch *tp)
135 {
136         tp->tap.timeout = 0;
137 }
138
139 static void
140 tp_tap_idle_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
141 {
142
143         switch (event) {
144         case TAP_EVENT_TOUCH:
145                 tp->tap.state = TAP_STATE_TOUCH;
146                 tp_tap_set_timer(tp, time);
147                 break;
148         case TAP_EVENT_RELEASE:
149         case TAP_EVENT_MOTION:
150                 log_info("invalid event, no fingers are down\n");
151                 break;
152         case TAP_EVENT_TIMEOUT:
153                 break;
154         case TAP_EVENT_BUTTON:
155                 tp->tap.state = TAP_STATE_DEAD;
156                 break;
157         }
158 }
159
160 static void
161 tp_tap_touch_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
162 {
163
164         switch (event) {
165         case TAP_EVENT_TOUCH:
166                 tp->tap.state = TAP_STATE_TOUCH_2;
167                 tp_tap_set_timer(tp, time);
168                 break;
169         case TAP_EVENT_RELEASE:
170                 tp->tap.state = TAP_STATE_TAPPED;
171                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
172                 tp_tap_set_timer(tp, time);
173                 break;
174         case TAP_EVENT_TIMEOUT:
175         case TAP_EVENT_MOTION:
176                 tp->tap.state = TAP_STATE_HOLD;
177                 tp_tap_clear_timer(tp);
178                 break;
179         case TAP_EVENT_BUTTON:
180                 tp->tap.state = TAP_STATE_DEAD;
181                 break;
182         }
183 }
184
185 static void
186 tp_tap_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
187 {
188
189         switch (event) {
190         case TAP_EVENT_TOUCH:
191                 tp->tap.state = TAP_STATE_TOUCH_2;
192                 tp_tap_set_timer(tp, time);
193                 break;
194         case TAP_EVENT_RELEASE:
195                 tp->tap.state = TAP_STATE_IDLE;
196                 break;
197         case TAP_EVENT_MOTION:
198         case TAP_EVENT_TIMEOUT:
199                 break;
200         case TAP_EVENT_BUTTON:
201                 tp->tap.state = TAP_STATE_DEAD;
202                 break;
203         }
204 }
205
206 static void
207 tp_tap_tapped_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
208 {
209
210         switch (event) {
211         case TAP_EVENT_MOTION:
212         case TAP_EVENT_RELEASE:
213                 log_info("invalid event when fingers are up\n");
214                 break;
215         case TAP_EVENT_TOUCH:
216                 tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
217                 tp_tap_clear_timer(tp);
218                 break;
219         case TAP_EVENT_TIMEOUT:
220                 tp->tap.state = TAP_STATE_IDLE;
221                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
222                 break;
223         case TAP_EVENT_BUTTON:
224                 tp->tap.state = TAP_STATE_DEAD;
225                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
226                 break;
227         }
228 }
229
230 static void
231 tp_tap_touch2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
232 {
233
234         switch (event) {
235         case TAP_EVENT_TOUCH:
236                 tp->tap.state = TAP_STATE_TOUCH_3;
237                 tp_tap_set_timer(tp, time);
238                 break;
239         case TAP_EVENT_RELEASE:
240                 tp->tap.state = TAP_STATE_HOLD;
241                 tp_tap_notify(tp, time, 2, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
242                 tp_tap_notify(tp, time, 2, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
243                 tp_tap_clear_timer(tp);
244                 break;
245         case TAP_EVENT_MOTION:
246                 tp_tap_clear_timer(tp);
247         case TAP_EVENT_TIMEOUT:
248                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
249                 break;
250         case TAP_EVENT_BUTTON:
251                 tp->tap.state = TAP_STATE_DEAD;
252                 break;
253         }
254 }
255
256 static void
257 tp_tap_touch2_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
258 {
259
260         switch (event) {
261         case TAP_EVENT_TOUCH:
262                 tp->tap.state = TAP_STATE_TOUCH_3;
263                 tp_tap_set_timer(tp, time);
264                 break;
265         case TAP_EVENT_RELEASE:
266                 tp->tap.state = TAP_STATE_HOLD;
267                 break;
268         case TAP_EVENT_MOTION:
269         case TAP_EVENT_TIMEOUT:
270                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
271                 break;
272         case TAP_EVENT_BUTTON:
273                 tp->tap.state = TAP_STATE_DEAD;
274                 break;
275         }
276 }
277
278 static void
279 tp_tap_touch3_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
280 {
281
282         switch (event) {
283         case TAP_EVENT_TOUCH:
284                 tp->tap.state = TAP_STATE_DEAD;
285                 tp_tap_clear_timer(tp);
286                 break;
287         case TAP_EVENT_MOTION:
288         case TAP_EVENT_TIMEOUT:
289                 tp->tap.state = TAP_STATE_TOUCH_3_HOLD;
290                 tp_tap_clear_timer(tp);
291                 break;
292         case TAP_EVENT_RELEASE:
293                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
294                 tp_tap_notify(tp, time, 3, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
295                 tp_tap_notify(tp, time, 3, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
296                 break;
297         case TAP_EVENT_BUTTON:
298                 tp->tap.state = TAP_STATE_DEAD;
299                 break;
300         }
301 }
302
303 static void
304 tp_tap_touch3_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
305 {
306
307         switch (event) {
308         case TAP_EVENT_TOUCH:
309                 tp->tap.state = TAP_STATE_DEAD;
310                 tp_tap_set_timer(tp, time);
311                 break;
312         case TAP_EVENT_RELEASE:
313                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
314                 break;
315         case TAP_EVENT_MOTION:
316         case TAP_EVENT_TIMEOUT:
317                 break;
318         case TAP_EVENT_BUTTON:
319                 tp->tap.state = TAP_STATE_DEAD;
320                 break;
321         }
322 }
323
324 static void
325 tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
326 {
327         switch (event) {
328         case TAP_EVENT_TOUCH:
329                 tp->tap.state = TAP_STATE_DRAGGING_2;
330                 break;
331         case TAP_EVENT_RELEASE:
332                 tp->tap.state = TAP_STATE_IDLE;
333                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
334                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
335                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
336                 tp_tap_clear_timer(tp);
337                 break;
338         case TAP_EVENT_MOTION:
339         case TAP_EVENT_TIMEOUT:
340                 tp->tap.state = TAP_STATE_DRAGGING;
341                 break;
342         case TAP_EVENT_BUTTON:
343                 tp->tap.state = TAP_STATE_DEAD;
344                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
345                 break;
346         }
347 }
348
349 static void
350 tp_tap_dragging_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
351 {
352
353         switch (event) {
354         case TAP_EVENT_TOUCH:
355                 tp->tap.state = TAP_STATE_DRAGGING_2;
356                 break;
357         case TAP_EVENT_RELEASE:
358                 tp->tap.state = TAP_STATE_DRAGGING_WAIT;
359                 tp_tap_set_timer(tp, time);
360                 break;
361         case TAP_EVENT_MOTION:
362         case TAP_EVENT_TIMEOUT:
363                 /* noop */
364                 break;
365         case TAP_EVENT_BUTTON:
366                 tp->tap.state = TAP_STATE_DEAD;
367                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
368                 break;
369         }
370 }
371
372 static void
373 tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
374 {
375
376         switch (event) {
377         case TAP_EVENT_TOUCH:
378                 tp->tap.state = TAP_STATE_DRAGGING;
379                 tp_tap_clear_timer(tp);
380                 break;
381         case TAP_EVENT_RELEASE:
382         case TAP_EVENT_MOTION:
383                 break;
384         case TAP_EVENT_TIMEOUT:
385                 tp->tap.state = TAP_STATE_IDLE;
386                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
387                 break;
388         case TAP_EVENT_BUTTON:
389                 tp->tap.state = TAP_STATE_DEAD;
390                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
391                 break;
392         }
393 }
394
395 static void
396 tp_tap_dragging2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
397 {
398
399         switch (event) {
400         case TAP_EVENT_RELEASE:
401                 tp->tap.state = TAP_STATE_DRAGGING;
402                 break;
403         case TAP_EVENT_TOUCH:
404                 tp->tap.state = TAP_STATE_DEAD;
405                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
406                 break;
407         case TAP_EVENT_MOTION:
408         case TAP_EVENT_TIMEOUT:
409                 /* noop */
410                 break;
411         case TAP_EVENT_BUTTON:
412                 tp->tap.state = TAP_STATE_DEAD;
413                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
414                 break;
415         }
416 }
417
418 static void
419 tp_tap_dead_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
420 {
421
422         switch (event) {
423         case TAP_EVENT_RELEASE:
424                 if (tp->nfingers_down == 0)
425                         tp->tap.state = TAP_STATE_IDLE;
426                 break;
427         case TAP_EVENT_TOUCH:
428         case TAP_EVENT_MOTION:
429         case TAP_EVENT_TIMEOUT:
430         case TAP_EVENT_BUTTON:
431                 break;
432         }
433 }
434
435 static void
436 tp_tap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
437 {
438         enum tp_tap_state current;
439         if (!tp->tap.enabled)
440                 return;
441
442         current = tp->tap.state;
443
444         switch(tp->tap.state) {
445         case TAP_STATE_IDLE:
446                 tp_tap_idle_handle_event(tp, event, time);
447                 break;
448         case TAP_STATE_TOUCH:
449                 tp_tap_touch_handle_event(tp, event, time);
450                 break;
451         case TAP_STATE_HOLD:
452                 tp_tap_hold_handle_event(tp, event, time);
453                 break;
454         case TAP_STATE_TAPPED:
455                 tp_tap_tapped_handle_event(tp, event, time);
456                 break;
457         case TAP_STATE_TOUCH_2:
458                 tp_tap_touch2_handle_event(tp, event, time);
459                 break;
460         case TAP_STATE_TOUCH_2_HOLD:
461                 tp_tap_touch2_hold_handle_event(tp, event, time);
462                 break;
463         case TAP_STATE_TOUCH_3:
464                 tp_tap_touch3_handle_event(tp, event, time);
465                 break;
466         case TAP_STATE_TOUCH_3_HOLD:
467                 tp_tap_touch3_hold_handle_event(tp, event, time);
468                 break;
469         case TAP_STATE_DRAGGING_OR_DOUBLETAP:
470                 tp_tap_dragging_or_doubletap_handle_event(tp, event, time);
471                 break;
472         case TAP_STATE_DRAGGING:
473                 tp_tap_dragging_handle_event(tp, event, time);
474                 break;
475         case TAP_STATE_DRAGGING_WAIT:
476                 tp_tap_dragging_wait_handle_event(tp, event, time);
477                 break;
478         case TAP_STATE_DRAGGING_2:
479                 tp_tap_dragging2_handle_event(tp, event, time);
480                 break;
481         case TAP_STATE_DEAD:
482                 tp_tap_dead_handle_event(tp, event, time);
483                 break;
484         }
485
486         if (tp->tap.state == TAP_STATE_IDLE || tp->tap.state == TAP_STATE_DEAD)
487                 tp_tap_clear_timer(tp);
488
489         log_debug("%s → %s → %s\n", tap_state_to_str(current), tap_event_to_str(event), tap_state_to_str(tp->tap.state));
490 }
491
492 static bool
493 tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp, struct tp_touch *t)
494 {
495         int threshold = DEFAULT_TAP_MOVE_THRESHOLD;
496         double dx, dy;
497
498         tp_get_delta(t, &dx, &dy);
499
500         return dx * dx + dy * dy > threshold * threshold;
501 }
502
503 int
504 tp_tap_handle_state(struct tp_dispatch *tp, uint32_t time)
505 {
506         struct tp_touch *t;
507
508         if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
509                 tp_tap_handle_event(tp, TAP_EVENT_BUTTON, time);
510
511         tp_for_each_touch(tp, t) {
512                 if (!t->dirty || t->state == TOUCH_NONE)
513                         continue;
514
515                 if (t->state == TOUCH_BEGIN)
516                         tp_tap_handle_event(tp, TAP_EVENT_TOUCH, time);
517                 else if (t->state == TOUCH_END)
518                         tp_tap_handle_event(tp, TAP_EVENT_RELEASE, time);
519                 else if (tp->tap.state != TAP_STATE_IDLE &&
520                          tp_tap_exceeds_motion_threshold(tp, t))
521                         tp_tap_handle_event(tp, TAP_EVENT_MOTION, time);
522         }
523
524         return 0;
525 }
526
527 static void
528 tp_tap_timeout_handler(void *data)
529 {
530         struct tp_dispatch *touchpad = data;
531         uint64_t expires;
532         int len;
533         struct timespec ts;
534         uint32_t now;
535
536         len = read(touchpad->tap.timer_fd, &expires, sizeof expires);
537         if (len != sizeof expires)
538                 /* This will only happen if the application made the fd
539                  * non-blocking, but this function should only be called
540                  * upon the timeout, so lets continue anyway. */
541                 fprintf(stderr, "timerfd read error: %m\n");
542
543         clock_gettime(CLOCK_MONOTONIC, &ts);
544         now = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
545
546         tp_tap_handle_timeout(touchpad, now);
547 }
548
549 unsigned int
550 tp_tap_handle_timeout(struct tp_dispatch *tp, uint32_t time)
551 {
552         if (!tp->tap.enabled)
553                 return 0;
554
555         if (tp->tap.timeout && tp->tap.timeout <= time) {
556                 tp_tap_clear_timer(tp);
557                 tp_tap_handle_event(tp, TAP_EVENT_TIMEOUT, time);
558         }
559
560         return tp->tap.timeout;
561 }
562
563 int
564 tp_init_tap(struct tp_dispatch *tp)
565 {
566         tp->tap.state = TAP_STATE_IDLE;
567         tp->tap.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
568
569         if (tp->tap.timer_fd == -1)
570                 return -1;
571
572         tp->tap.source =
573                 libinput_add_fd(tp->device->base.seat->libinput,
574                                 tp->tap.timer_fd,
575                                 tp_tap_timeout_handler,
576                                 tp);
577
578         if (tp->tap.source == NULL) {
579                 close(tp->tap.timer_fd);
580                 return -1;
581         }
582
583         tp->tap.enabled = 1; /* FIXME */
584
585         return 0;
586 }