2 * Copyright © 2014 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 #include <linux/input.h>
30 #include <sys/timerfd.h>
32 #include "evdev-mt-touchpad.h"
34 #define DEFAULT_BUTTON_MOTION_THRESHOLD 0.02 /* 2% of size */
35 #define DEFAULT_BUTTON_ENTER_TIMEOUT 100 /* ms */
36 #define DEFAULT_BUTTON_LEAVE_TIMEOUT 300 /* ms */
38 /*****************************************
39 * BEFORE YOU EDIT THIS FILE, look at the state diagram in
40 * doc/touchpad-softbutton-state-machine.svg, or online at
41 * https://drive.google.com/file/d/0B1NwWmji69nocUs1cVJTbkdwMFk/edit?usp=sharing
42 * (it's a http://draw.io diagram)
44 * Any changes in this file must be represented in the diagram.
46 * The state machine only affects the soft button area code.
49 #define CASE_RETURN_STRING(a) case a: return #a;
51 static inline const char*
52 button_state_to_str(enum button_state state) {
54 CASE_RETURN_STRING(BUTTON_STATE_NONE);
55 CASE_RETURN_STRING(BUTTON_STATE_AREA);
56 CASE_RETURN_STRING(BUTTON_STATE_BOTTOM);
57 CASE_RETURN_STRING(BUTTON_STATE_BOTTOM_NEW);
58 CASE_RETURN_STRING(BUTTON_STATE_BOTTOM_TO_AREA);
63 static inline const char*
64 button_event_to_str(enum button_event event) {
66 CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_R);
67 CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_L);
68 CASE_RETURN_STRING(BUTTON_EVENT_IN_AREA);
69 CASE_RETURN_STRING(BUTTON_EVENT_UP);
70 CASE_RETURN_STRING(BUTTON_EVENT_PRESS);
71 CASE_RETURN_STRING(BUTTON_EVENT_RELEASE);
72 CASE_RETURN_STRING(BUTTON_EVENT_TIMEOUT);
78 is_inside_button_area(struct tp_dispatch *tp, struct tp_touch *t)
80 return t->y >= tp->buttons.area.top_edge;
84 is_inside_right_area(struct tp_dispatch *tp, struct tp_touch *t)
86 return is_inside_button_area(tp, t) &&
87 t->x > tp->buttons.area.rightbutton_left_edge;
91 is_inside_left_area(struct tp_dispatch *tp, struct tp_touch *t)
93 return is_inside_button_area(tp, t) &&
94 !is_inside_right_area(tp, t);
98 tp_button_set_timer(struct tp_dispatch *tp, uint64_t timeout)
100 struct itimerspec its;
101 its.it_interval.tv_sec = 0;
102 its.it_interval.tv_nsec = 0;
103 its.it_value.tv_sec = timeout / 1000;
104 its.it_value.tv_nsec = (timeout % 1000) * 1000 * 1000;
105 timerfd_settime(tp->buttons.timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
109 tp_button_set_enter_timer(struct tp_dispatch *tp, struct tp_touch *t)
111 t->button.timeout = t->millis + DEFAULT_BUTTON_ENTER_TIMEOUT;
112 tp_button_set_timer(tp, t->button.timeout);
116 tp_button_set_leave_timer(struct tp_dispatch *tp, struct tp_touch *t)
118 t->button.timeout = t->millis + DEFAULT_BUTTON_LEAVE_TIMEOUT;
119 tp_button_set_timer(tp, t->button.timeout);
123 tp_button_clear_timer(struct tp_dispatch *tp, struct tp_touch *t)
125 t->button.timeout = 0;
129 * tp_button_set_state, change state and implement on-entry behavior
130 * as described in the state machine diagram.
133 tp_button_set_state(struct tp_dispatch *tp, struct tp_touch *t,
134 enum button_state new_state, enum button_event event)
136 tp_button_clear_timer(tp, t);
138 t->button.state = new_state;
139 switch (t->button.state) {
140 case BUTTON_STATE_NONE:
143 case BUTTON_STATE_AREA:
144 t->button.curr = BUTTON_EVENT_IN_AREA;
145 tp_set_pointer(tp, t);
147 case BUTTON_STATE_BOTTOM:
149 case BUTTON_STATE_BOTTOM_NEW:
150 t->button.curr = event;
151 tp_button_set_enter_timer(tp, t);
153 case BUTTON_STATE_BOTTOM_TO_AREA:
154 tp_button_set_leave_timer(tp, t);
160 tp_button_none_handle_event(struct tp_dispatch *tp,
162 enum button_event event)
165 case BUTTON_EVENT_IN_BOTTOM_R:
166 case BUTTON_EVENT_IN_BOTTOM_L:
167 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW, event);
169 case BUTTON_EVENT_IN_AREA:
170 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
172 case BUTTON_EVENT_UP:
173 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
175 case BUTTON_EVENT_PRESS:
176 case BUTTON_EVENT_RELEASE:
177 case BUTTON_EVENT_TIMEOUT:
183 tp_button_area_handle_event(struct tp_dispatch *tp,
185 enum button_event event)
188 case BUTTON_EVENT_IN_BOTTOM_R:
189 case BUTTON_EVENT_IN_BOTTOM_L:
190 case BUTTON_EVENT_IN_AREA:
192 case BUTTON_EVENT_UP:
193 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
195 case BUTTON_EVENT_PRESS:
196 case BUTTON_EVENT_RELEASE:
197 case BUTTON_EVENT_TIMEOUT:
203 tp_button_bottom_handle_event(struct tp_dispatch *tp,
205 enum button_event event)
208 case BUTTON_EVENT_IN_BOTTOM_R:
209 case BUTTON_EVENT_IN_BOTTOM_L:
210 if (event != t->button.curr)
211 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
214 case BUTTON_EVENT_IN_AREA:
215 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_TO_AREA, event);
217 case BUTTON_EVENT_UP:
218 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
220 case BUTTON_EVENT_PRESS:
221 case BUTTON_EVENT_RELEASE:
222 case BUTTON_EVENT_TIMEOUT:
228 tp_button_bottom_new_handle_event(struct tp_dispatch *tp,
230 enum button_event event)
233 case BUTTON_EVENT_IN_BOTTOM_R:
234 case BUTTON_EVENT_IN_BOTTOM_L:
235 if (event != t->button.curr)
236 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
239 case BUTTON_EVENT_IN_AREA:
240 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
242 case BUTTON_EVENT_UP:
243 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
245 case BUTTON_EVENT_PRESS:
246 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event);
248 case BUTTON_EVENT_RELEASE:
250 case BUTTON_EVENT_TIMEOUT:
251 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event);
257 tp_button_bottom_to_area_handle_event(struct tp_dispatch *tp,
259 enum button_event event)
262 case BUTTON_EVENT_IN_BOTTOM_R:
263 case BUTTON_EVENT_IN_BOTTOM_L:
264 if (event == t->button.curr)
265 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM,
268 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
271 case BUTTON_EVENT_IN_AREA:
273 case BUTTON_EVENT_UP:
274 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
276 case BUTTON_EVENT_PRESS:
277 case BUTTON_EVENT_RELEASE:
279 case BUTTON_EVENT_TIMEOUT:
280 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
286 tp_button_handle_event(struct tp_dispatch *tp,
288 enum button_event event,
291 enum button_state current = t->button.state;
293 switch(t->button.state) {
294 case BUTTON_STATE_NONE:
295 tp_button_none_handle_event(tp, t, event);
297 case BUTTON_STATE_AREA:
298 tp_button_area_handle_event(tp, t, event);
300 case BUTTON_STATE_BOTTOM:
301 tp_button_bottom_handle_event(tp, t, event);
303 case BUTTON_STATE_BOTTOM_NEW:
304 tp_button_bottom_new_handle_event(tp, t, event);
306 case BUTTON_STATE_BOTTOM_TO_AREA:
307 tp_button_bottom_to_area_handle_event(tp, t, event);
311 if (current != t->button.state)
312 log_debug("button state: from %s, event %s to %s\n",
313 button_state_to_str(current),
314 button_event_to_str(event),
315 button_state_to_str(t->button.state));
319 tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
323 tp_for_each_touch(tp, t) {
324 if (t->state == TOUCH_NONE)
327 if (t->state == TOUCH_END) {
328 tp_button_handle_event(tp, t, BUTTON_EVENT_UP, time);
329 } else if (t->dirty) {
330 if (is_inside_right_area(tp, t))
331 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_R, time);
332 else if (is_inside_left_area(tp, t))
333 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_L, time);
335 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_AREA, time);
337 if (tp->queued & TOUCHPAD_EVENT_BUTTON_RELEASE)
338 tp_button_handle_event(tp, t, BUTTON_EVENT_RELEASE, time);
339 if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
340 tp_button_handle_event(tp, t, BUTTON_EVENT_PRESS, time);
347 tp_button_handle_timeout(struct tp_dispatch *tp, uint64_t now)
351 tp_for_each_touch(tp, t) {
352 if (t->button.timeout != 0 && t->button.timeout <= now) {
353 tp_button_clear_timer(tp, t);
354 tp_button_handle_event(tp, t, BUTTON_EVENT_TIMEOUT, now);
360 tp_process_button(struct tp_dispatch *tp,
361 const struct input_event *e,
364 uint32_t mask = 1 << (e->code - BTN_LEFT);
366 /* Ignore other buttons on clickpads */
367 if (tp->buttons.is_clickpad && e->code != BTN_LEFT) {
368 log_bug("received %s button event on a clickpad (kernel bug?)\n",
369 libevdev_event_code_get_name(EV_KEY, e->code));
374 tp->buttons.state |= mask;
375 tp->queued |= TOUCHPAD_EVENT_BUTTON_PRESS;
377 tp->buttons.state &= ~mask;
378 tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
385 tp_button_timeout_handler(void *data)
387 struct tp_dispatch *tp = data;
393 len = read(tp->buttons.timer_fd, &expires, sizeof expires);
394 if (len != sizeof expires)
395 /* This will only happen if the application made the fd
396 * non-blocking, but this function should only be called
397 * upon the timeout, so lets continue anyway. */
398 log_error("timerfd read error: %s\n", strerror(errno));
400 clock_gettime(CLOCK_MONOTONIC, &ts);
401 now = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
403 tp_button_handle_timeout(tp, now);
407 tp_init_buttons(struct tp_dispatch *tp,
408 struct evdev_device *device)
413 tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
414 INPUT_PROP_BUTTONPAD);
416 if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE) ||
417 libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT)) {
418 if (tp->buttons.is_clickpad)
419 log_bug("clickpad advertising right button (kernel bug?)\n");
421 if (!tp->buttons.is_clickpad)
422 log_bug("non clickpad without right button (kernel bug)?\n");
425 width = abs(device->abs.max_x - device->abs.min_x);
426 height = abs(device->abs.max_y - device->abs.min_y);
427 diagonal = sqrt(width*width + height*height);
429 tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
431 if (libevdev_get_id_vendor(device->evdev) == 0x5ac) /* Apple */
432 tp->buttons.use_clickfinger = true;
434 if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) {
435 tp->buttons.area.top_edge = height * .8 + device->abs.min_y;
436 tp->buttons.area.rightbutton_left_edge = width/2 + device->abs.min_x;
437 tp->buttons.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
439 if (tp->buttons.timer_fd == -1)
443 libinput_add_fd(tp->device->base.seat->libinput,
444 tp->buttons.timer_fd,
445 tp_button_timeout_handler,
447 if (tp->buttons.source == NULL)
450 tp->buttons.area.top_edge = INT_MAX;
457 tp_destroy_buttons(struct tp_dispatch *tp)
459 if (tp->buttons.source) {
460 libinput_remove_source(tp->device->base.seat->libinput,
462 tp->buttons.source = NULL;
464 if (tp->buttons.timer_fd > -1) {
465 close(tp->buttons.timer_fd);
466 tp->buttons.timer_fd = -1;
471 tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint64_t time)
473 uint32_t current, old, button;
474 enum libinput_pointer_button_state state;
476 current = tp->buttons.state;
477 old = tp->buttons.old_state;
483 switch (tp->nfingers_down) {
484 case 1: button = BTN_LEFT; break;
485 case 2: button = BTN_RIGHT; break;
486 case 3: button = BTN_MIDDLE; break;
490 tp->buttons.active = button;
491 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
493 button = tp->buttons.active;
494 tp->buttons.active = 0;
495 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
499 pointer_notify_button(&tp->device->base,
507 tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
509 uint32_t current, old, button;
511 current = tp->buttons.state;
512 old = tp->buttons.old_state;
515 while (current || old) {
516 enum libinput_pointer_button_state state;
518 if ((current & 0x1) ^ (old & 0x1)) {
519 if (!!(current & 0x1))
520 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
522 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
524 pointer_notify_button(&tp->device->base,
539 tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
541 uint32_t current, old, button;
542 enum libinput_pointer_button_state state;
543 enum { AREA = 0x01, LEFT = 0x02, RIGHT = 0x04 };
545 current = tp->buttons.state;
546 old = tp->buttons.old_state;
549 if (!tp->buttons.click_pending && current == old)
555 tp_for_each_touch(tp, t) {
556 switch (t->button.curr) {
557 case BUTTON_EVENT_IN_AREA:
560 case BUTTON_EVENT_IN_BOTTOM_L:
563 case BUTTON_EVENT_IN_BOTTOM_R:
573 /* No touches, wait for a touch before processing */
574 tp->buttons.click_pending = true;
578 /* Some touches in right, no touches in left */
582 case LEFT | RIGHT | AREA:
583 /* Some touches in left and some in right */
590 tp->buttons.active = button;
591 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
593 button = tp->buttons.active;
594 tp->buttons.active = 0;
595 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
598 tp->buttons.click_pending = false;
601 pointer_notify_button(&tp->device->base,
609 tp_post_button_events(struct tp_dispatch *tp, uint64_t time)
611 if (tp->buttons.is_clickpad) {
612 if (tp->buttons.use_clickfinger)
613 return tp_post_clickfinger_buttons(tp, time);
615 return tp_post_softbutton_buttons(tp, time);
618 return tp_post_physical_buttons(tp, time);
622 tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
624 return t->button.state == BUTTON_STATE_AREA;