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, uint32_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, uint32_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, uint32_t now)
350 uint32_t min_timeout = INT_MAX;
352 tp_for_each_touch(tp, t) {
353 if (t->button.timeout != 0 && t->button.timeout <= now) {
354 tp_button_clear_timer(tp, t);
355 tp_button_handle_event(tp, t, BUTTON_EVENT_TIMEOUT, now);
357 if (t->button.timeout != 0)
358 min_timeout = min(t->button.timeout, min_timeout);
361 return min_timeout == INT_MAX ? 0 : min_timeout;
365 tp_process_button(struct tp_dispatch *tp,
366 const struct input_event *e,
369 uint32_t mask = 1 << (e->code - BTN_LEFT);
371 tp->buttons.state |= mask;
372 tp->queued |= TOUCHPAD_EVENT_BUTTON_PRESS;
374 tp->buttons.state &= ~mask;
375 tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
382 tp_button_timeout_handler(void *data)
384 struct tp_dispatch *tp = data;
390 len = read(tp->buttons.timer_fd, &expires, sizeof expires);
391 if (len != sizeof expires)
392 /* This will only happen if the application made the fd
393 * non-blocking, but this function should only be called
394 * upon the timeout, so lets continue anyway. */
395 log_error("timerfd read error: %s\n", strerror(errno));
397 clock_gettime(CLOCK_MONOTONIC, &ts);
398 now = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
400 tp_button_handle_timeout(tp, now);
404 tp_init_buttons(struct tp_dispatch *tp,
405 struct evdev_device *device)
410 tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
411 INPUT_PROP_BUTTONPAD);
413 if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE) ||
414 libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT)) {
415 if (tp->buttons.is_clickpad)
416 log_bug("clickpad advertising right button (kernel bug?)\n");
418 if (!tp->buttons.is_clickpad)
419 log_bug("non clickpad without right button (kernel bug)?\n");
422 width = abs(device->abs.max_x - device->abs.min_x);
423 height = abs(device->abs.max_y - device->abs.min_y);
424 diagonal = sqrt(width*width + height*height);
426 tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
428 if (libevdev_get_id_vendor(device->evdev) == 0x5ac) /* Apple */
429 tp->buttons.use_clickfinger = true;
431 if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) {
432 tp->buttons.area.top_edge = height * .8 + device->abs.min_y;
433 tp->buttons.area.rightbutton_left_edge = width/2 + device->abs.min_x;
434 tp->buttons.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
436 if (tp->buttons.timer_fd == -1)
440 libinput_add_fd(tp->device->base.seat->libinput,
441 tp->buttons.timer_fd,
442 tp_button_timeout_handler,
444 if (tp->buttons.source == NULL)
447 tp->buttons.area.top_edge = INT_MAX;
454 tp_destroy_buttons(struct tp_dispatch *tp)
456 if (tp->buttons.source) {
457 libinput_remove_source(tp->device->base.seat->libinput,
459 tp->buttons.source = NULL;
461 if (tp->buttons.timer_fd > -1) {
462 close(tp->buttons.timer_fd);
463 tp->buttons.timer_fd = -1;
468 tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint32_t time)
470 uint32_t current, old, button;
471 enum libinput_pointer_button_state state;
473 current = tp->buttons.state;
474 old = tp->buttons.old_state;
480 switch (tp->nfingers_down) {
481 case 1: button = BTN_LEFT; break;
482 case 2: button = BTN_RIGHT; break;
483 case 3: button = BTN_MIDDLE; break;
487 tp->buttons.active = button;
488 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
490 button = tp->buttons.active;
491 tp->buttons.active = 0;
492 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
496 pointer_notify_button(&tp->device->base,
504 tp_post_physical_buttons(struct tp_dispatch *tp, uint32_t time)
506 uint32_t current, old, button;
508 current = tp->buttons.state;
509 old = tp->buttons.old_state;
512 while (current || old) {
513 enum libinput_pointer_button_state state;
515 if ((current & 0x1) ^ (old & 0x1)) {
516 if (!!(current & 0x1))
517 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
519 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
521 pointer_notify_button(&tp->device->base,
536 tp_post_softbutton_buttons(struct tp_dispatch *tp, uint32_t time)
538 uint32_t current, old, button;
539 enum libinput_pointer_button_state state;
541 current = tp->buttons.state;
542 old = tp->buttons.old_state;
547 if (tp->nfingers_down == 0 || tp->nfingers_down > 2)
554 tp_for_each_touch(tp, t) {
555 if (t->button.curr == BUTTON_EVENT_IN_BOTTOM_R)
557 else if (t->button.curr == BUTTON_EVENT_IN_BOTTOM_L)
562 case 0: /* only in area */
563 case 1: /* only left area */
566 case 2: /* only right area */
569 case 3: /* left + right area */
574 tp->buttons.active = button;
575 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
577 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
578 button = tp->buttons.active;
581 pointer_notify_button(&tp->device->base,
589 tp_post_button_events(struct tp_dispatch *tp, uint32_t time)
592 (TOUCHPAD_EVENT_BUTTON_PRESS|TOUCHPAD_EVENT_BUTTON_RELEASE)) == 0)
595 if (tp->buttons.is_clickpad) {
596 if (tp->buttons.use_clickfinger)
597 return tp_post_clickfinger_buttons(tp, time);
599 return tp_post_softbutton_buttons(tp, time);
602 return tp_post_physical_buttons(tp, time);
606 tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
608 return t->button.state == BUTTON_STATE_AREA;