2 * Copyright © 2013 Red Hat, Inc.
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
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.
33 #include <sys/timerfd.h>
35 #include "evdev-mt-touchpad.h"
37 #define CASE_RETURN_STRING(a) case a: return #a;
39 #define DEFAULT_TAP_TIMEOUT_PERIOD 180
40 #define DEFAULT_TAP_MOVE_THRESHOLD 30
50 /*****************************************
51 * DO NOT EDIT THIS FILE!
53 * Look at the state diagram in doc/touchpad-tap-state-machine.svg, or
55 * https://drive.google.com/file/d/0B1NwWmji69noYTdMcU1kTUZuUVE/edit?usp=sharing
56 * (it's a http://draw.io diagram)
58 * Any changes in this file must be represented in the diagram.
61 static inline const char*
62 tap_state_to_str(enum tp_tap_state 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);
82 static inline const char*
83 tap_event_to_str(enum tap_event 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);
94 #undef CASE_RETURN_STRING
97 tp_tap_notify(struct tp_dispatch *tp,
100 enum libinput_pointer_button_state state)
105 case 1: button = BTN_LEFT; break;
106 case 2: button = BTN_RIGHT; break;
107 case 3: button = BTN_MIDDLE; break;
112 pointer_notify_button(&tp->device->base,
119 tp_tap_set_timer(struct tp_dispatch *tp, uint32_t time)
121 uint32_t timeout = time + DEFAULT_TAP_TIMEOUT_PERIOD;
122 struct itimerspec its;
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);
130 tp->tap.timeout = timeout;
134 tp_tap_clear_timer(struct tp_dispatch *tp)
140 tp_tap_idle_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
144 case TAP_EVENT_TOUCH:
145 tp->tap.state = TAP_STATE_TOUCH;
146 tp_tap_set_timer(tp, time);
148 case TAP_EVENT_RELEASE:
149 case TAP_EVENT_MOTION:
150 log_info("invalid event, no fingers are down\n");
152 case TAP_EVENT_TIMEOUT:
154 case TAP_EVENT_BUTTON:
155 tp->tap.state = TAP_STATE_DEAD;
161 tp_tap_touch_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
165 case TAP_EVENT_TOUCH:
166 tp->tap.state = TAP_STATE_TOUCH_2;
167 tp_tap_set_timer(tp, time);
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);
174 case TAP_EVENT_TIMEOUT:
175 case TAP_EVENT_MOTION:
176 tp->tap.state = TAP_STATE_HOLD;
177 tp_tap_clear_timer(tp);
179 case TAP_EVENT_BUTTON:
180 tp->tap.state = TAP_STATE_DEAD;
186 tp_tap_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
190 case TAP_EVENT_TOUCH:
191 tp->tap.state = TAP_STATE_TOUCH_2;
192 tp_tap_set_timer(tp, time);
194 case TAP_EVENT_RELEASE:
195 tp->tap.state = TAP_STATE_IDLE;
197 case TAP_EVENT_MOTION:
198 case TAP_EVENT_TIMEOUT:
200 case TAP_EVENT_BUTTON:
201 tp->tap.state = TAP_STATE_DEAD;
207 tp_tap_tapped_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
211 case TAP_EVENT_MOTION:
212 case TAP_EVENT_RELEASE:
213 log_info("invalid event when fingers are up\n");
215 case TAP_EVENT_TOUCH:
216 tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
217 tp_tap_clear_timer(tp);
219 case TAP_EVENT_TIMEOUT:
220 tp->tap.state = TAP_STATE_IDLE;
221 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
223 case TAP_EVENT_BUTTON:
224 tp->tap.state = TAP_STATE_DEAD;
225 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
231 tp_tap_touch2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
235 case TAP_EVENT_TOUCH:
236 tp->tap.state = TAP_STATE_TOUCH_3;
237 tp_tap_set_timer(tp, time);
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);
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;
250 case TAP_EVENT_BUTTON:
251 tp->tap.state = TAP_STATE_DEAD;
257 tp_tap_touch2_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
261 case TAP_EVENT_TOUCH:
262 tp->tap.state = TAP_STATE_TOUCH_3;
263 tp_tap_set_timer(tp, time);
265 case TAP_EVENT_RELEASE:
266 tp->tap.state = TAP_STATE_HOLD;
268 case TAP_EVENT_MOTION:
269 case TAP_EVENT_TIMEOUT:
270 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
272 case TAP_EVENT_BUTTON:
273 tp->tap.state = TAP_STATE_DEAD;
279 tp_tap_touch3_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
283 case TAP_EVENT_TOUCH:
284 tp->tap.state = TAP_STATE_DEAD;
285 tp_tap_clear_timer(tp);
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);
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);
297 case TAP_EVENT_BUTTON:
298 tp->tap.state = TAP_STATE_DEAD;
304 tp_tap_touch3_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
308 case TAP_EVENT_TOUCH:
309 tp->tap.state = TAP_STATE_DEAD;
310 tp_tap_set_timer(tp, time);
312 case TAP_EVENT_RELEASE:
313 tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
315 case TAP_EVENT_MOTION:
316 case TAP_EVENT_TIMEOUT:
318 case TAP_EVENT_BUTTON:
319 tp->tap.state = TAP_STATE_DEAD;
325 tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
328 case TAP_EVENT_TOUCH:
329 tp->tap.state = TAP_STATE_DRAGGING_2;
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);
338 case TAP_EVENT_MOTION:
339 case TAP_EVENT_TIMEOUT:
340 tp->tap.state = TAP_STATE_DRAGGING;
342 case TAP_EVENT_BUTTON:
343 tp->tap.state = TAP_STATE_DEAD;
344 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
350 tp_tap_dragging_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
354 case TAP_EVENT_TOUCH:
355 tp->tap.state = TAP_STATE_DRAGGING_2;
357 case TAP_EVENT_RELEASE:
358 tp->tap.state = TAP_STATE_DRAGGING_WAIT;
359 tp_tap_set_timer(tp, time);
361 case TAP_EVENT_MOTION:
362 case TAP_EVENT_TIMEOUT:
365 case TAP_EVENT_BUTTON:
366 tp->tap.state = TAP_STATE_DEAD;
367 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
373 tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
377 case TAP_EVENT_TOUCH:
378 tp->tap.state = TAP_STATE_DRAGGING;
379 tp_tap_clear_timer(tp);
381 case TAP_EVENT_RELEASE:
382 case TAP_EVENT_MOTION:
384 case TAP_EVENT_TIMEOUT:
385 tp->tap.state = TAP_STATE_IDLE;
386 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
388 case TAP_EVENT_BUTTON:
389 tp->tap.state = TAP_STATE_DEAD;
390 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
396 tp_tap_dragging2_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
400 case TAP_EVENT_RELEASE:
401 tp->tap.state = TAP_STATE_DRAGGING;
403 case TAP_EVENT_TOUCH:
404 tp->tap.state = TAP_STATE_DEAD;
405 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
407 case TAP_EVENT_MOTION:
408 case TAP_EVENT_TIMEOUT:
411 case TAP_EVENT_BUTTON:
412 tp->tap.state = TAP_STATE_DEAD;
413 tp_tap_notify(tp, time, 1, LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
419 tp_tap_dead_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
423 case TAP_EVENT_RELEASE:
424 if (tp->nfingers_down == 0)
425 tp->tap.state = TAP_STATE_IDLE;
427 case TAP_EVENT_TOUCH:
428 case TAP_EVENT_MOTION:
429 case TAP_EVENT_TIMEOUT:
430 case TAP_EVENT_BUTTON:
436 tp_tap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint32_t time)
438 enum tp_tap_state current;
439 if (!tp->tap.enabled)
442 current = tp->tap.state;
444 switch(tp->tap.state) {
446 tp_tap_idle_handle_event(tp, event, time);
448 case TAP_STATE_TOUCH:
449 tp_tap_touch_handle_event(tp, event, time);
452 tp_tap_hold_handle_event(tp, event, time);
454 case TAP_STATE_TAPPED:
455 tp_tap_tapped_handle_event(tp, event, time);
457 case TAP_STATE_TOUCH_2:
458 tp_tap_touch2_handle_event(tp, event, time);
460 case TAP_STATE_TOUCH_2_HOLD:
461 tp_tap_touch2_hold_handle_event(tp, event, time);
463 case TAP_STATE_TOUCH_3:
464 tp_tap_touch3_handle_event(tp, event, time);
466 case TAP_STATE_TOUCH_3_HOLD:
467 tp_tap_touch3_hold_handle_event(tp, event, time);
469 case TAP_STATE_DRAGGING_OR_DOUBLETAP:
470 tp_tap_dragging_or_doubletap_handle_event(tp, event, time);
472 case TAP_STATE_DRAGGING:
473 tp_tap_dragging_handle_event(tp, event, time);
475 case TAP_STATE_DRAGGING_WAIT:
476 tp_tap_dragging_wait_handle_event(tp, event, time);
478 case TAP_STATE_DRAGGING_2:
479 tp_tap_dragging2_handle_event(tp, event, time);
482 tp_tap_dead_handle_event(tp, event, time);
486 if (tp->tap.state == TAP_STATE_IDLE || tp->tap.state == TAP_STATE_DEAD)
487 tp_tap_clear_timer(tp);
489 log_debug("%s → %s → %s\n", tap_state_to_str(current), tap_event_to_str(event), tap_state_to_str(tp->tap.state));
493 tp_tap_exceeds_motion_threshold(struct tp_dispatch *tp, struct tp_touch *t)
495 int threshold = DEFAULT_TAP_MOVE_THRESHOLD;
498 tp_get_delta(t, &dx, &dy);
500 return dx * dx + dy * dy > threshold * threshold;
504 tp_tap_handle_state(struct tp_dispatch *tp, uint32_t time)
508 if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
509 tp_tap_handle_event(tp, TAP_EVENT_BUTTON, time);
511 tp_for_each_touch(tp, t) {
512 if (!t->dirty || t->state == TOUCH_NONE)
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);
528 tp_tap_timeout_handler(void *data)
530 struct tp_dispatch *touchpad = data;
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");
543 clock_gettime(CLOCK_MONOTONIC, &ts);
544 now = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
546 tp_tap_handle_timeout(touchpad, now);
550 tp_tap_handle_timeout(struct tp_dispatch *tp, uint32_t time)
552 if (!tp->tap.enabled)
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);
560 return tp->tap.timeout;
564 tp_init_tap(struct tp_dispatch *tp)
566 tp->tap.state = TAP_STATE_IDLE;
567 tp->tap.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
569 if (tp->tap.timer_fd == -1)
573 libinput_add_fd(tp->device->base.seat->libinput,
575 tp_tap_timeout_handler,
578 if (tp->tap.source == NULL) {
579 close(tp->tap.timer_fd);
583 tp->tap.enabled = 1; /* FIXME */