fa6d4a797c11cc8a2221cf6eb1637bcf1c3e2292
[platform/upstream/libinput.git] / src / evdev-mt-touchpad-buttons.c
1 /*
2  * Copyright © 2014 Red Hat, Inc.
3  *
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.
13  *
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.
21  */
22
23 #include <errno.h>
24 #include <limits.h>
25 #include <time.h>
26 #include <math.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <linux/input.h>
30 #include <sys/timerfd.h>
31
32 #include "evdev-mt-touchpad.h"
33
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 */
37
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)
43  *
44  * Any changes in this file must be represented in the diagram.
45  *
46  * The state machine only affects the soft button area code.
47  */
48
49 #define CASE_RETURN_STRING(a) case a: return #a;
50
51 static inline const char*
52 button_state_to_str(enum button_state state) {
53         switch(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);
59         }
60         return NULL;
61 }
62
63 static inline const char*
64 button_event_to_str(enum button_event event) {
65         switch(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);
73         }
74         return NULL;
75 }
76
77 static inline bool
78 is_inside_bottom_button_area(struct tp_dispatch *tp, struct tp_touch *t)
79 {
80         return t->y >= tp->buttons.bottom_area.top_edge;
81 }
82
83 static inline bool
84 is_inside_bottom_right_area(struct tp_dispatch *tp, struct tp_touch *t)
85 {
86         return is_inside_bottom_button_area(tp, t) &&
87                t->x > tp->buttons.bottom_area.rightbutton_left_edge;
88 }
89
90 static inline bool
91 is_inside_bottom_left_area(struct tp_dispatch *tp, struct tp_touch *t)
92 {
93         return is_inside_bottom_button_area(tp, t) &&
94                !is_inside_bottom_right_area(tp, t);
95 }
96
97 static void
98 tp_button_set_timer(struct tp_dispatch *tp, uint64_t timeout)
99 {
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);
106 }
107
108 static void
109 tp_button_set_enter_timer(struct tp_dispatch *tp, struct tp_touch *t)
110 {
111         t->button.timeout = t->millis + DEFAULT_BUTTON_ENTER_TIMEOUT;
112         tp_button_set_timer(tp, t->button.timeout);
113 }
114
115 static void
116 tp_button_set_leave_timer(struct tp_dispatch *tp, struct tp_touch *t)
117 {
118         t->button.timeout = t->millis + DEFAULT_BUTTON_LEAVE_TIMEOUT;
119         tp_button_set_timer(tp, t->button.timeout);
120 }
121
122 static void
123 tp_button_clear_timer(struct tp_dispatch *tp, struct tp_touch *t)
124 {
125         t->button.timeout = 0;
126 }
127
128 /*
129  * tp_button_set_state, change state and implement on-entry behavior
130  * as described in the state machine diagram.
131  */
132 static void
133 tp_button_set_state(struct tp_dispatch *tp, struct tp_touch *t,
134                     enum button_state new_state, enum button_event event)
135 {
136         tp_button_clear_timer(tp, t);
137
138         t->button.state = new_state;
139         switch (t->button.state) {
140         case BUTTON_STATE_NONE:
141                 t->button.curr = 0;
142                 break;
143         case BUTTON_STATE_AREA:
144                 t->button.curr = BUTTON_EVENT_IN_AREA;
145                 tp_set_pointer(tp, t);
146                 break;
147         case BUTTON_STATE_BOTTOM:
148                 break;
149         case BUTTON_STATE_BOTTOM_NEW:
150                 t->button.curr = event;
151                 tp_button_set_enter_timer(tp, t);
152                 break;
153         case BUTTON_STATE_BOTTOM_TO_AREA:
154                 tp_button_set_leave_timer(tp, t);
155                 break;
156         }
157 }
158
159 static void
160 tp_button_none_handle_event(struct tp_dispatch *tp,
161                             struct tp_touch *t,
162                             enum button_event event)
163 {
164         switch (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);
168                 break;
169         case BUTTON_EVENT_IN_AREA:
170                 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
171                 break;
172         case BUTTON_EVENT_UP:
173                 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
174                 break;
175         case BUTTON_EVENT_PRESS:
176         case BUTTON_EVENT_RELEASE:
177         case BUTTON_EVENT_TIMEOUT:
178                 break;
179         }
180 }
181
182 static void
183 tp_button_area_handle_event(struct tp_dispatch *tp,
184                             struct tp_touch *t,
185                             enum button_event event)
186 {
187         switch (event) {
188         case BUTTON_EVENT_IN_BOTTOM_R:
189         case BUTTON_EVENT_IN_BOTTOM_L:
190         case BUTTON_EVENT_IN_AREA:
191                 break;
192         case BUTTON_EVENT_UP:
193                 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
194                 break;
195         case BUTTON_EVENT_PRESS:
196         case BUTTON_EVENT_RELEASE:
197         case BUTTON_EVENT_TIMEOUT:
198                 break;
199         }
200 }
201
202 static void
203 tp_button_bottom_handle_event(struct tp_dispatch *tp,
204                             struct tp_touch *t,
205                             enum button_event event)
206 {
207         switch (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,
212                                             event);
213                 break;
214         case BUTTON_EVENT_IN_AREA:
215                 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_TO_AREA, event);
216                 break;
217         case BUTTON_EVENT_UP:
218                 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
219                 break;
220         case BUTTON_EVENT_PRESS:
221         case BUTTON_EVENT_RELEASE:
222         case BUTTON_EVENT_TIMEOUT:
223                 break;
224         }
225 }
226
227 static void
228 tp_button_bottom_new_handle_event(struct tp_dispatch *tp,
229                                 struct tp_touch *t,
230                                 enum button_event event)
231 {
232         switch(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,
237                                             event);
238                 break;
239         case BUTTON_EVENT_IN_AREA:
240                 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
241                 break;
242         case BUTTON_EVENT_UP:
243                 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
244                 break;
245         case BUTTON_EVENT_PRESS:
246                 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event);
247                 break;
248         case BUTTON_EVENT_RELEASE:
249                 break;
250         case BUTTON_EVENT_TIMEOUT:
251                 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event);
252                 break;
253         }
254 }
255
256 static void
257 tp_button_bottom_to_area_handle_event(struct tp_dispatch *tp,
258                                       struct tp_touch *t,
259                                       enum button_event event)
260 {
261         switch(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,
266                                             event);
267                 else
268                         tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
269                                             event);
270                 break;
271         case BUTTON_EVENT_IN_AREA:
272                 break;
273         case BUTTON_EVENT_UP:
274                 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
275                 break;
276         case BUTTON_EVENT_PRESS:
277         case BUTTON_EVENT_RELEASE:
278                 break;
279         case BUTTON_EVENT_TIMEOUT:
280                 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
281                 break;
282         }
283 }
284
285 static void
286 tp_button_handle_event(struct tp_dispatch *tp,
287                        struct tp_touch *t,
288                        enum button_event event,
289                        uint64_t time)
290 {
291         enum button_state current = t->button.state;
292
293         switch(t->button.state) {
294         case BUTTON_STATE_NONE:
295                 tp_button_none_handle_event(tp, t, event);
296                 break;
297         case BUTTON_STATE_AREA:
298                 tp_button_area_handle_event(tp, t, event);
299                 break;
300         case BUTTON_STATE_BOTTOM:
301                 tp_button_bottom_handle_event(tp, t, event);
302                 break;
303         case BUTTON_STATE_BOTTOM_NEW:
304                 tp_button_bottom_new_handle_event(tp, t, event);
305                 break;
306         case BUTTON_STATE_BOTTOM_TO_AREA:
307                 tp_button_bottom_to_area_handle_event(tp, t, event);
308                 break;
309         }
310
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));
316 }
317
318 int
319 tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
320 {
321         struct tp_touch *t;
322
323         tp_for_each_touch(tp, t) {
324                 if (t->state == TOUCH_NONE)
325                         continue;
326
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_bottom_right_area(tp, t))
331                                 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_R, time);
332                         else if (is_inside_bottom_left_area(tp, t))
333                                 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_L, time);
334                         else
335                                 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_AREA, time);
336                 }
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);
341         }
342
343         return 0;
344 }
345
346 static void
347 tp_button_handle_timeout(struct tp_dispatch *tp, uint64_t now)
348 {
349         struct tp_touch *t;
350
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);
355                 }
356         }
357 }
358
359 int
360 tp_process_button(struct tp_dispatch *tp,
361                   const struct input_event *e,
362                   uint64_t time)
363 {
364         uint32_t mask = 1 << (e->code - BTN_LEFT);
365
366         /* Ignore other buttons on clickpads */
367         if (tp->buttons.is_clickpad && e->code != BTN_LEFT) {
368                 log_bug_kernel("received %s button event on a clickpad\n",
369                                libevdev_event_code_get_name(EV_KEY, e->code));
370                 return 0;
371         }
372
373         if (e->value) {
374                 tp->buttons.state |= mask;
375                 tp->queued |= TOUCHPAD_EVENT_BUTTON_PRESS;
376         } else {
377                 tp->buttons.state &= ~mask;
378                 tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
379         }
380
381         return 0;
382 }
383
384 static void
385 tp_button_timeout_handler(void *data)
386 {
387         struct tp_dispatch *tp = data;
388         uint64_t expires;
389         int len;
390         struct timespec ts;
391         uint64_t now;
392
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));
399
400         clock_gettime(CLOCK_MONOTONIC, &ts);
401         now = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
402
403         tp_button_handle_timeout(tp, now);
404 }
405
406 int
407 tp_init_buttons(struct tp_dispatch *tp,
408                 struct evdev_device *device)
409 {
410         int width, height;
411         double diagonal;
412
413         tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
414                                                         INPUT_PROP_BUTTONPAD);
415
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_kernel("clickpad advertising right button\n");
420         } else {
421                 if (!tp->buttons.is_clickpad)
422                         log_bug_kernel("non clickpad without right button?\n");
423         }
424
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);
428
429         tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
430
431         if (libevdev_get_id_vendor(device->evdev) == 0x5ac) /* Apple */
432                 tp->buttons.use_clickfinger = true;
433
434         if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) {
435                 tp->buttons.bottom_area.top_edge = height * .8 + device->abs.min_y;
436                 tp->buttons.bottom_area.rightbutton_left_edge = width/2 + device->abs.min_x;
437                 tp->buttons.timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
438
439                 if (tp->buttons.timer_fd == -1)
440                         return -1;
441
442                 tp->buttons.source =
443                         libinput_add_fd(tp->device->base.seat->libinput,
444                                         tp->buttons.timer_fd,
445                                         tp_button_timeout_handler,
446                                         tp);
447                 if (tp->buttons.source == NULL)
448                         return -1;
449         } else {
450                 tp->buttons.bottom_area.top_edge = INT_MAX;
451         }
452
453         return 0;
454 }
455
456 void
457 tp_destroy_buttons(struct tp_dispatch *tp)
458 {
459         if (tp->buttons.source) {
460                 libinput_remove_source(tp->device->base.seat->libinput,
461                                        tp->buttons.source);
462                 tp->buttons.source = NULL;
463         }
464         if (tp->buttons.timer_fd > -1) {
465                 close(tp->buttons.timer_fd);
466                 tp->buttons.timer_fd = -1;
467         }
468 }
469
470 static int
471 tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint64_t time)
472 {
473         uint32_t current, old, button;
474         enum libinput_pointer_button_state state;
475
476         current = tp->buttons.state;
477         old = tp->buttons.old_state;
478
479         if (current == old)
480                 return 0;
481
482         if (current) {
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;
487                 default:
488                         return 0;
489                 }
490                 tp->buttons.active = button;
491                 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
492         } else {
493                 button = tp->buttons.active;
494                 tp->buttons.active = 0;
495                 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
496         }
497
498         if (button)
499                 pointer_notify_button(&tp->device->base,
500                                       time,
501                                       button,
502                                       state);
503         return 1;
504 }
505
506 static int
507 tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
508 {
509         uint32_t current, old, button;
510
511         current = tp->buttons.state;
512         old = tp->buttons.old_state;
513         button = BTN_LEFT;
514
515         while (current || old) {
516                 enum libinput_pointer_button_state state;
517
518                 if ((current & 0x1) ^ (old & 0x1)) {
519                         if (!!(current & 0x1))
520                                 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
521                         else
522                                 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
523
524                         pointer_notify_button(&tp->device->base,
525                                               time,
526                                               button,
527                                               state);
528                 }
529
530                 button++;
531                 current >>= 1;
532                 old >>= 1;
533         }
534
535         return 0;
536 }
537
538 static int
539 tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
540 {
541         uint32_t current, old, button;
542         enum libinput_pointer_button_state state;
543         enum { AREA = 0x01, LEFT = 0x02, RIGHT = 0x04 };
544
545         current = tp->buttons.state;
546         old = tp->buttons.old_state;
547         button = 0;
548
549         if (!tp->buttons.click_pending && current == old)
550                 return 0;
551
552         if (current) {
553                 struct tp_touch *t;
554
555                 tp_for_each_touch(tp, t) {
556                         switch (t->button.curr) {
557                         case BUTTON_EVENT_IN_AREA:
558                                 button |= AREA;
559                                 break;
560                         case BUTTON_EVENT_IN_BOTTOM_L:
561                                 button |= LEFT;
562                                 break;
563                         case BUTTON_EVENT_IN_BOTTOM_R:
564                                 button |= RIGHT;
565                                 break;
566                         default:
567                                 break;
568                         }
569                 }
570
571                 switch (button) {
572                 case 0:
573                         /* No touches, wait for a touch before processing */
574                         tp->buttons.click_pending = true;
575                         return 0;
576                 case RIGHT:
577                 case RIGHT | AREA:
578                         /* Some touches in right, no touches in left */
579                         button = BTN_RIGHT;
580                         break;
581                 case LEFT | RIGHT:
582                 case LEFT | RIGHT | AREA:
583                         /* Some touches in left and some in right */
584                         button = BTN_MIDDLE;
585                         break;
586                 default:
587                         button = BTN_LEFT;
588                 }
589
590                 tp->buttons.active = button;
591                 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
592         } else {
593                 button = tp->buttons.active;
594                 tp->buttons.active = 0;
595                 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
596         }
597
598         tp->buttons.click_pending = false;
599
600         if (button)
601                 pointer_notify_button(&tp->device->base,
602                                       time,
603                                       button,
604                                       state);
605         return 1;
606 }
607
608 int
609 tp_post_button_events(struct tp_dispatch *tp, uint64_t time)
610 {
611         if (tp->buttons.is_clickpad) {
612                 if (tp->buttons.use_clickfinger)
613                         return tp_post_clickfinger_buttons(tp, time);
614                 else
615                         return tp_post_softbutton_buttons(tp, time);
616         }
617
618         return tp_post_physical_buttons(tp, time);
619 }
620
621 int
622 tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
623 {
624         return t->button.state == BUTTON_STATE_AREA;
625 }