Remove old touchpad code
[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 <errno.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <time.h>
34 #include <unistd.h>
35 #include <sys/timerfd.h>
36
37 #include "evdev-mt-touchpad.h"
38
39 #define CASE_RETURN_STRING(a) case a: return #a;
40
41 #define DEFAULT_TAP_TIMEOUT_PERIOD 180
42 #define DEFAULT_TAP_MOVE_THRESHOLD 30
43
44 enum tap_event {
45         TAP_EVENT_TOUCH = 12,
46         TAP_EVENT_MOTION,
47         TAP_EVENT_RELEASE,
48         TAP_EVENT_BUTTON,
49         TAP_EVENT_TIMEOUT,
50 };
51
52 /*****************************************
53  * DO NOT EDIT THIS FILE!
54  *
55  * Look at the state diagram in doc/touchpad-tap-state-machine.svg, or
56  * online at
57  * https://drive.google.com/file/d/0B1NwWmji69noYTdMcU1kTUZuUVE/edit?usp=sharing
58  * (it's a http://draw.io diagram)
59  *
60  * Any changes in this file must be represented in the diagram.
61  */
62
63 static inline const char*
64 tap_state_to_str(enum tp_tap_state state) {
65
66         switch(state) {
67         CASE_RETURN_STRING(TAP_STATE_IDLE);
68         CASE_RETURN_STRING(TAP_STATE_HOLD);
69         CASE_RETURN_STRING(TAP_STATE_TOUCH);
70         CASE_RETURN_STRING(TAP_STATE_TAPPED);
71         CASE_RETURN_STRING(TAP_STATE_TOUCH_2);
72         CASE_RETURN_STRING(TAP_STATE_TOUCH_2_HOLD);
73         CASE_RETURN_STRING(TAP_STATE_TOUCH_3);
74         CASE_RETURN_STRING(TAP_STATE_TOUCH_3_HOLD);
75         CASE_RETURN_STRING(TAP_STATE_DRAGGING);
76         CASE_RETURN_STRING(TAP_STATE_DRAGGING_WAIT);
77         CASE_RETURN_STRING(TAP_STATE_DRAGGING_OR_DOUBLETAP);
78         CASE_RETURN_STRING(TAP_STATE_DRAGGING_2);
79         CASE_RETURN_STRING(TAP_STATE_DEAD);
80         }
81         return NULL;
82 }
83
84 static inline const char*
85 tap_event_to_str(enum tap_event event) {
86
87         switch(event) {
88         CASE_RETURN_STRING(TAP_EVENT_TOUCH);
89         CASE_RETURN_STRING(TAP_EVENT_MOTION);
90         CASE_RETURN_STRING(TAP_EVENT_RELEASE);
91         CASE_RETURN_STRING(TAP_EVENT_TIMEOUT);
92         CASE_RETURN_STRING(TAP_EVENT_BUTTON);
93         }
94         return NULL;
95 }
96 #undef CASE_RETURN_STRING
97
98 static void
99 tp_tap_notify(struct tp_dispatch *tp,
100               uint64_t time,
101               int nfingers,
102               enum libinput_pointer_button_state state)
103 {
104         int32_t button;
105
106         switch (nfingers) {
107         case 1: button = BTN_LEFT; break;
108         case 2: button = BTN_RIGHT; break;
109         case 3: button = BTN_MIDDLE; break;
110         default:
111                 return;
112         }
113
114         pointer_notify_button(&tp->device->base,
115                               time,
116                               button,
117                               state);
118 }
119
120 static void
121 tp_tap_set_timer(struct tp_dispatch *tp, uint64_t time)
122 {
123         uint64_t timeout = time + DEFAULT_TAP_TIMEOUT_PERIOD;
124         struct itimerspec its;
125
126         its.it_interval.tv_sec = 0;
127         its.it_interval.tv_nsec = 0;
128         its.it_value.tv_sec = timeout / 1000;
129         its.it_value.tv_nsec = (timeout % 1000) * 1000 * 1000;
130         timerfd_settime(tp->tap.timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
131
132         tp->tap.timeout = timeout;
133 }
134
135 static void
136 tp_tap_clear_timer(struct tp_dispatch *tp)
137 {
138         tp->tap.timeout = 0;
139 }
140
141 static void
142 tp_tap_idle_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
143 {
144
145         switch (event) {
146         case TAP_EVENT_TOUCH:
147                 tp->tap.state = TAP_STATE_TOUCH;
148                 tp_tap_set_timer(tp, time);
149                 break;
150         case TAP_EVENT_RELEASE:
151         case TAP_EVENT_MOTION:
152                 log_info("invalid event, no fingers are down\n");
153                 break;
154         case TAP_EVENT_TIMEOUT:
155                 break;
156         case TAP_EVENT_BUTTON:
157                 tp->tap.state = TAP_STATE_DEAD;
158                 break;
159         }
160 }
161
162 static void
163 tp_tap_touch_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
164 {
165
166         switch (event) {
167         case TAP_EVENT_TOUCH:
168                 tp->tap.state = TAP_STATE_TOUCH_2;
169                 tp_tap_set_timer(tp, time);
170                 break;
171         case TAP_EVENT_RELEASE:
172                 tp->tap.state = TAP_STATE_TAPPED;
173                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
174                 tp_tap_set_timer(tp, time);
175                 break;
176         case TAP_EVENT_TIMEOUT:
177         case TAP_EVENT_MOTION:
178                 tp->tap.state = TAP_STATE_HOLD;
179                 tp_tap_clear_timer(tp);
180                 break;
181         case TAP_EVENT_BUTTON:
182                 tp->tap.state = TAP_STATE_DEAD;
183                 break;
184         }
185 }
186
187 static void
188 tp_tap_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
189 {
190
191         switch (event) {
192         case TAP_EVENT_TOUCH:
193                 tp->tap.state = TAP_STATE_TOUCH_2;
194                 tp_tap_set_timer(tp, time);
195                 break;
196         case TAP_EVENT_RELEASE:
197                 tp->tap.state = TAP_STATE_IDLE;
198                 break;
199         case TAP_EVENT_MOTION:
200         case TAP_EVENT_TIMEOUT:
201                 break;
202         case TAP_EVENT_BUTTON:
203                 tp->tap.state = TAP_STATE_DEAD;
204                 break;
205         }
206 }
207
208 static void
209 tp_tap_tapped_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
210 {
211
212         switch (event) {
213         case TAP_EVENT_MOTION:
214         case TAP_EVENT_RELEASE:
215                 log_info("invalid event when fingers are up\n");
216                 break;
217         case TAP_EVENT_TOUCH:
218                 tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
219                 tp_tap_clear_timer(tp);
220                 break;
221         case TAP_EVENT_TIMEOUT:
222                 tp->tap.state = TAP_STATE_IDLE;
223                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
224                 break;
225         case TAP_EVENT_BUTTON:
226                 tp->tap.state = TAP_STATE_DEAD;
227                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
228                 break;
229         }
230 }
231
232 static void
233 tp_tap_touch2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
234 {
235
236         switch (event) {
237         case TAP_EVENT_TOUCH:
238                 tp->tap.state = TAP_STATE_TOUCH_3;
239                 tp_tap_set_timer(tp, time);
240                 break;
241         case TAP_EVENT_RELEASE:
242                 tp->tap.state = TAP_STATE_HOLD;
243                 tp_tap_notify(tp, time, 2, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
244                 tp_tap_notify(tp, time, 2, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
245                 tp_tap_clear_timer(tp);
246                 break;
247         case TAP_EVENT_MOTION:
248                 tp_tap_clear_timer(tp);
249         case TAP_EVENT_TIMEOUT:
250                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
251                 break;
252         case TAP_EVENT_BUTTON:
253                 tp->tap.state = TAP_STATE_DEAD;
254                 break;
255         }
256 }
257
258 static void
259 tp_tap_touch2_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
260 {
261
262         switch (event) {
263         case TAP_EVENT_TOUCH:
264                 tp->tap.state = TAP_STATE_TOUCH_3;
265                 tp_tap_set_timer(tp, time);
266                 break;
267         case TAP_EVENT_RELEASE:
268                 tp->tap.state = TAP_STATE_HOLD;
269                 break;
270         case TAP_EVENT_MOTION:
271         case TAP_EVENT_TIMEOUT:
272                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
273                 break;
274         case TAP_EVENT_BUTTON:
275                 tp->tap.state = TAP_STATE_DEAD;
276                 break;
277         }
278 }
279
280 static void
281 tp_tap_touch3_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
282 {
283
284         switch (event) {
285         case TAP_EVENT_TOUCH:
286                 tp->tap.state = TAP_STATE_DEAD;
287                 tp_tap_clear_timer(tp);
288                 break;
289         case TAP_EVENT_MOTION:
290         case TAP_EVENT_TIMEOUT:
291                 tp->tap.state = TAP_STATE_TOUCH_3_HOLD;
292                 tp_tap_clear_timer(tp);
293                 break;
294         case TAP_EVENT_RELEASE:
295                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
296                 tp_tap_notify(tp, time, 3, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
297                 tp_tap_notify(tp, time, 3, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
298                 break;
299         case TAP_EVENT_BUTTON:
300                 tp->tap.state = TAP_STATE_DEAD;
301                 break;
302         }
303 }
304
305 static void
306 tp_tap_touch3_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
307 {
308
309         switch (event) {
310         case TAP_EVENT_TOUCH:
311                 tp->tap.state = TAP_STATE_DEAD;
312                 tp_tap_set_timer(tp, time);
313                 break;
314         case TAP_EVENT_RELEASE:
315                 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
316                 break;
317         case TAP_EVENT_MOTION:
318         case TAP_EVENT_TIMEOUT:
319                 break;
320         case TAP_EVENT_BUTTON:
321                 tp->tap.state = TAP_STATE_DEAD;
322                 break;
323         }
324 }
325
326 static void
327 tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
328 {
329         switch (event) {
330         case TAP_EVENT_TOUCH:
331                 tp->tap.state = TAP_STATE_DRAGGING_2;
332                 break;
333         case TAP_EVENT_RELEASE:
334                 tp->tap.state = TAP_STATE_IDLE;
335                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
336                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
337                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
338                 tp_tap_clear_timer(tp);
339                 break;
340         case TAP_EVENT_MOTION:
341         case TAP_EVENT_TIMEOUT:
342                 tp->tap.state = TAP_STATE_DRAGGING;
343                 break;
344         case TAP_EVENT_BUTTON:
345                 tp->tap.state = TAP_STATE_DEAD;
346                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
347                 break;
348         }
349 }
350
351 static void
352 tp_tap_dragging_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
353 {
354
355         switch (event) {
356         case TAP_EVENT_TOUCH:
357                 tp->tap.state = TAP_STATE_DRAGGING_2;
358                 break;
359         case TAP_EVENT_RELEASE:
360                 tp->tap.state = TAP_STATE_DRAGGING_WAIT;
361                 tp_tap_set_timer(tp, time);
362                 break;
363         case TAP_EVENT_MOTION:
364         case TAP_EVENT_TIMEOUT:
365                 /* noop */
366                 break;
367         case TAP_EVENT_BUTTON:
368                 tp->tap.state = TAP_STATE_DEAD;
369                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
370                 break;
371         }
372 }
373
374 static void
375 tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
376 {
377
378         switch (event) {
379         case TAP_EVENT_TOUCH:
380                 tp->tap.state = TAP_STATE_DRAGGING;
381                 tp_tap_clear_timer(tp);
382                 break;
383         case TAP_EVENT_RELEASE:
384         case TAP_EVENT_MOTION:
385                 break;
386         case TAP_EVENT_TIMEOUT:
387                 tp->tap.state = TAP_STATE_IDLE;
388                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
389                 break;
390         case TAP_EVENT_BUTTON:
391                 tp->tap.state = TAP_STATE_DEAD;
392                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
393                 break;
394         }
395 }
396
397 static void
398 tp_tap_dragging2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
399 {
400
401         switch (event) {
402         case TAP_EVENT_RELEASE:
403                 tp->tap.state = TAP_STATE_DRAGGING;
404                 break;
405         case TAP_EVENT_TOUCH:
406                 tp->tap.state = TAP_STATE_DEAD;
407                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
408                 break;
409         case TAP_EVENT_MOTION:
410         case TAP_EVENT_TIMEOUT:
411                 /* noop */
412                 break;
413         case TAP_EVENT_BUTTON:
414                 tp->tap.state = TAP_STATE_DEAD;
415                 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
416                 break;
417         }
418 }
419
420 static void
421 tp_tap_dead_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
422 {
423
424         switch (event) {
425         case TAP_EVENT_RELEASE:
426                 if (tp->nfingers_down == 0)
427                         tp->tap.state = TAP_STATE_IDLE;
428                 break;
429         case TAP_EVENT_TOUCH:
430         case TAP_EVENT_MOTION:
431         case TAP_EVENT_TIMEOUT:
432         case TAP_EVENT_BUTTON:
433                 break;
434         }
435 }
436
437 static void
438 tp_tap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time)
439 {
440         enum tp_tap_state current;
441         if (!tp->tap.enabled)
442                 return;
443
444         current = tp->tap.state;
445
446         switch(tp->tap.state) {
447         case TAP_STATE_IDLE:
448                 tp_tap_idle_handle_event(tp, event, time);
449                 break;
450         case TAP_STATE_TOUCH:
451                 tp_tap_touch_handle_event(tp, event, time);
452                 break;
453         case TAP_STATE_HOLD:
454                 tp_tap_hold_handle_event(tp, event, time);
455                 break;
456         case TAP_STATE_TAPPED:
457                 tp_tap_tapped_handle_event(tp, event, time);
458                 break;
459         case TAP_STATE_TOUCH_2:
460                 tp_tap_touch2_handle_event(tp, event, time);
461                 break;
462         case TAP_STATE_TOUCH_2_HOLD:
463                 tp_tap_touch2_hold_handle_event(tp, event, time);
464                 break;
465         case TAP_STATE_TOUCH_3:
466                 tp_tap_touch3_handle_event(tp, event, time);
467                 break;
468         case TAP_STATE_TOUCH_3_HOLD:
469                 tp_tap_touch3_hold_handle_event(tp, event, time);
470                 break;
471         case TAP_STATE_DRAGGING_OR_DOUBLETAP:
472                 tp_tap_dragging_or_doubletap_handle_event(tp, event, time);
473                 break;
474         case TAP_STATE_DRAGGING:
475                 tp_tap_dragging_handle_event(tp, event, time);
476                 break;
477         case TAP_STATE_DRAGGING_WAIT:
478                 tp_tap_dragging_wait_handle_event(tp, event, time);
479                 break;
480         case TAP_STATE_DRAGGING_2:
481                 tp_tap_dragging2_handle_event(tp, event, time);
482                 break;
483         case TAP_STATE_DEAD:
484                 tp_tap_dead_handle_event(tp, event, time);
485                 break;
486         }
487
488         if (tp->tap.state == TAP_STATE_IDLE || tp->tap.state == TAP_STATE_DEAD)
489                 tp_tap_clear_timer(tp);
490
491         log_debug("%s → %s → %s\n", tap_state_to_str(current), tap_event_to_str(event), tap_state_to_str(tp->tap.state));
492 }
493
494 static bool
495 tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp, struct tp_touch *t)
496 {
497         int threshold = DEFAULT_TAP_MOVE_THRESHOLD;
498         double dx, dy;
499
500         tp_get_delta(t, &dx, &dy);
501
502         return dx * dx + dy * dy > threshold * threshold;
503 }
504
505 int
506 tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
507 {
508         struct tp_touch *t;
509         int filter_motion = 0;
510
511         if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
512                 tp_tap_handle_event(tp, TAP_EVENT_BUTTON, time);
513
514         tp_for_each_touch(tp, t) {
515                 if (!t->dirty || t->state == TOUCH_NONE)
516                         continue;
517
518                 if (t->state == TOUCH_BEGIN)
519                         tp_tap_handle_event(tp, TAP_EVENT_TOUCH, time);
520                 else if (t->state == TOUCH_END)
521                         tp_tap_handle_event(tp, TAP_EVENT_RELEASE, time);
522                 else if (tp->tap.state != TAP_STATE_IDLE &&
523                          tp_tap_exceeds_motion_threshold(tp, t))
524                         tp_tap_handle_event(tp, TAP_EVENT_MOTION, time);
525         }
526
527         /**
528          * In any state where motion exceeding the move threshold would
529          * move to the next state, filter that motion until we actually
530          * exceed it. This prevents small motion events while we're waiting
531          * on a decision if a tap is a tap.
532          */
533         switch (tp->tap.state) {
534         case TAP_STATE_TOUCH:
535         case TAP_STATE_TAPPED:
536         case TAP_STATE_DRAGGING_OR_DOUBLETAP:
537         case TAP_STATE_TOUCH_2:
538         case TAP_STATE_TOUCH_3:
539                 filter_motion = 1;
540                 break;
541
542         default:
543                 break;
544
545         }
546
547         return filter_motion;
548 }
549
550 static void
551 tp_tap_timeout_handler(void *data)
552 {
553         struct tp_dispatch *touchpad = data;
554         uint64_t expires;
555         int len;
556         struct timespec ts;
557         uint64_t now;
558
559         len = read(touchpad->tap.timer_fd, &expires, sizeof expires);
560         if (len != sizeof expires)
561                 /* This will only happen if the application made the fd
562                  * non-blocking, but this function should only be called
563                  * upon the timeout, so lets continue anyway. */
564                 log_error("timerfd read error: %s\n", strerror(errno));
565
566         clock_gettime(CLOCK_MONOTONIC, &ts);
567         now = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
568
569         tp_tap_handle_timeout(touchpad, now);
570 }
571
572 unsigned int
573 tp_tap_handle_timeout(struct tp_dispatch *tp, uint64_t time)
574 {
575         if (!tp->tap.enabled)
576                 return 0;
577
578         if (tp->tap.timeout && tp->tap.timeout <= time) {
579                 tp_tap_clear_timer(tp);
580                 tp_tap_handle_event(tp, TAP_EVENT_TIMEOUT, time);
581         }
582
583         return tp->tap.timeout;
584 }
585
586 int
587 tp_init_tap(struct tp_dispatch *tp)
588 {
589         tp->tap.state = TAP_STATE_IDLE;
590         tp->tap.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
591
592         if (tp->tap.timer_fd == -1)
593                 return -1;
594
595         tp->tap.source =
596                 libinput_add_fd(tp->device->base.seat->libinput,
597                                 tp->tap.timer_fd,
598                                 tp_tap_timeout_handler,
599                                 tp);
600
601         if (tp->tap.source == NULL) {
602                 close(tp->tap.timer_fd);
603                 return -1;
604         }
605
606         tp->tap.enabled = 1; /* FIXME */
607
608         return 0;
609 }
610
611 void
612 tp_destroy_tap(struct tp_dispatch *tp)
613 {
614         if (tp->tap.source) {
615                 libinput_remove_source(tp->device->base.seat->libinput, tp->tap.source);
616                 tp->tap.source = NULL;
617         }
618         if (tp->tap.timer_fd > -1) {
619                 close(tp->tap.timer_fd);
620                 tp->tap.timer_fd = -1;
621         }
622 }