touchpad: mark the first finger as pointer-controlling finger
[platform/upstream/libinput.git] / src / evdev-mt-touchpad.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 "config.h"
24
25 #include <assert.h>
26 #include <math.h>
27 #include <stdbool.h>
28
29 #include "evdev-mt-touchpad.h"
30
31 #define DEFAULT_CONSTANT_ACCEL_NUMERATOR 50
32 #define DEFAULT_MIN_ACCEL_FACTOR 0.16
33 #define DEFAULT_MAX_ACCEL_FACTOR 1.0
34 #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0
35
36 static inline int
37 tp_hysteresis(int in, int center, int margin)
38 {
39         int diff = in - center;
40         if (abs(diff) <= margin)
41                 return center;
42
43         if (diff > margin)
44                 return center + diff - margin;
45         else if (diff < -margin)
46                 return center + diff + margin;
47         return center + diff;
48 }
49
50 static double
51 tp_accel_profile(struct motion_filter *filter,
52                  void *data,
53                  double velocity,
54                  uint32_t time)
55 {
56         struct tp_dispatch *tp =
57                 (struct tp_dispatch *) data;
58
59         double accel_factor;
60
61         accel_factor = velocity * tp->accel.constant_factor;
62
63         if (accel_factor > tp->accel.max_factor)
64                 accel_factor = tp->accel.max_factor;
65         else if (accel_factor < tp->accel.min_factor)
66                 accel_factor = tp->accel.min_factor;
67
68         return accel_factor;
69 }
70
71 static inline struct tp_motion *
72 tp_motion_history_offset(struct tp_touch *t, int offset)
73 {
74         int offset_index =
75                 (t->history.index - offset + TOUCHPAD_HISTORY_LENGTH) %
76                 TOUCHPAD_HISTORY_LENGTH;
77
78         return &t->history.samples[offset_index];
79 }
80
81 static void
82 tp_filter_motion(struct tp_dispatch *tp,
83                  double *dx, double *dy, uint32_t time)
84 {
85         struct motion_params motion;
86
87         motion.dx = *dx;
88         motion.dy = *dy;
89
90         filter_dispatch(tp->filter, &motion, tp, time);
91
92         *dx = motion.dx;
93         *dy = motion.dy;
94 }
95
96 static inline void
97 tp_motion_history_push(struct tp_touch *t)
98 {
99         int motion_index = (t->history.index + 1) % TOUCHPAD_HISTORY_LENGTH;
100
101         if (t->history.count < TOUCHPAD_HISTORY_LENGTH)
102                 t->history.count++;
103
104         t->history.samples[motion_index].x = t->x;
105         t->history.samples[motion_index].y = t->y;
106         t->history.index = motion_index;
107 }
108
109 static inline void
110 tp_motion_hysteresis(struct tp_dispatch *tp,
111                      struct tp_touch *t)
112 {
113         int x = t->x,
114             y = t->y;
115
116         if (t->history.count == 0) {
117                 t->hysteresis.center_x = t->x;
118                 t->hysteresis.center_y = t->y;
119         } else {
120                 x = tp_hysteresis(x,
121                                   t->hysteresis.center_x,
122                                   tp->hysteresis.margin_x);
123                 y = tp_hysteresis(y,
124                                   t->hysteresis.center_y,
125                                   tp->hysteresis.margin_y);
126                 t->hysteresis.center_x = x;
127                 t->hysteresis.center_y = y;
128                 t->x = x;
129                 t->y = y;
130         }
131 }
132
133 static inline void
134 tp_motion_history_reset(struct tp_touch *t)
135 {
136         t->history.count = 0;
137 }
138
139 static inline struct tp_touch *
140 tp_current_touch(struct tp_dispatch *tp)
141 {
142         return &tp->touches[min(tp->slot, tp->ntouches)];
143 }
144
145 static inline struct tp_touch *
146 tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
147 {
148         assert(slot < tp->ntouches);
149         return &tp->touches[slot];
150 }
151
152 static inline void
153 tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t)
154 {
155         if (t->state != TOUCH_UPDATE) {
156                 tp_motion_history_reset(t);
157                 t->dirty = true;
158                 t->state = TOUCH_BEGIN;
159                 tp->nfingers_down++;
160                 assert(tp->nfingers_down >= 1);
161                 tp->queued |= TOUCHPAD_EVENT_MOTION;
162
163                 if (tp->nfingers_down == 1)
164                         t->is_pointer = true;
165         }
166 }
167
168 static inline void
169 tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t)
170 {
171         if (t->state == TOUCH_NONE)
172                 return;
173
174         t->dirty = true;
175         t->is_pointer = false;
176         t->state = TOUCH_END;
177         assert(tp->nfingers_down >= 1);
178         tp->nfingers_down--;
179         tp->queued |= TOUCHPAD_EVENT_MOTION;
180 }
181
182 static double
183 tp_estimate_delta(int x0, int x1, int x2, int x3)
184 {
185         return (x0 + x1 - x2 - x3) / 4;
186 }
187
188 void
189 tp_get_delta(struct tp_touch *t, double *dx, double *dy)
190 {
191         if (t->history.count < 4) {
192                 *dx = 0;
193                 *dy = 0;
194                 return;
195         }
196
197         *dx = tp_estimate_delta(tp_motion_history_offset(t, 0)->x,
198                                 tp_motion_history_offset(t, 1)->x,
199                                 tp_motion_history_offset(t, 2)->x,
200                                 tp_motion_history_offset(t, 3)->x);
201         *dy = tp_estimate_delta(tp_motion_history_offset(t, 0)->y,
202                                 tp_motion_history_offset(t, 1)->y,
203                                 tp_motion_history_offset(t, 2)->y,
204                                 tp_motion_history_offset(t, 3)->y);
205 }
206
207 static void
208 tp_process_absolute(struct tp_dispatch *tp,
209                     const struct input_event *e,
210                     uint32_t time)
211 {
212         struct tp_touch *t = tp_current_touch(tp);
213
214         switch(e->code) {
215         case ABS_MT_POSITION_X:
216                 t->x = e->value;
217                 t->millis = time;
218                 t->dirty = true;
219                 tp->queued |= TOUCHPAD_EVENT_MOTION;
220                 break;
221         case ABS_MT_POSITION_Y:
222                 t->y = e->value;
223                 t->millis = time;
224                 t->dirty = true;
225                 tp->queued |= TOUCHPAD_EVENT_MOTION;
226                 break;
227         case ABS_MT_SLOT:
228                 tp->slot = e->value;
229                 break;
230         case ABS_MT_TRACKING_ID:
231                 t->millis = time;
232                 if (e->value != -1)
233                         tp_begin_touch(tp, t);
234                 else
235                         tp_end_touch(tp, t);
236         }
237 }
238
239 static void
240 tp_process_absolute_st(struct tp_dispatch *tp,
241                        const struct input_event *e,
242                        uint32_t time)
243 {
244         struct tp_touch *t = tp_current_touch(tp);
245
246         switch(e->code) {
247         case ABS_X:
248                 t->x = e->value;
249                 t->millis = time;
250                 t->dirty = true;
251                 break;
252         case ABS_Y:
253                 t->y = e->value;
254                 t->millis = time;
255                 t->dirty = true;
256                 tp->queued |= TOUCHPAD_EVENT_MOTION;
257                 break;
258         }
259 }
260
261 static void
262 tp_process_fake_touch(struct tp_dispatch *tp,
263                       const struct input_event *e,
264                       uint32_t time)
265 {
266         struct tp_touch *t;
267         unsigned int fake_touches;
268         unsigned int nfake_touches;
269         unsigned int i;
270         unsigned int shift;
271
272         if (e->code != BTN_TOUCH &&
273             (e->code < BTN_TOOL_DOUBLETAP || e->code > BTN_TOOL_QUADTAP))
274                 return;
275
276         shift = e->code == BTN_TOUCH ? 0 : (e->code - BTN_TOOL_DOUBLETAP + 1);
277
278         if (e->value)
279                 tp->fake_touches |= 1 << shift;
280         else
281                 tp->fake_touches &= ~(0x1 << shift);
282
283         fake_touches = tp->fake_touches;
284         nfake_touches = 0;
285         while (fake_touches) {
286                 nfake_touches++;
287                 fake_touches >>= 1;
288         }
289
290         for (i = 0; i < tp->ntouches; i++) {
291                 t = tp_get_touch(tp, i);
292                 if (i >= nfake_touches) {
293                         if (t->state != TOUCH_NONE) {
294                                 tp_end_touch(tp, t);
295                                 t->millis = time;
296                         }
297                 } else if (t->state != TOUCH_UPDATE &&
298                            t->state != TOUCH_BEGIN) {
299                         t->state = TOUCH_NONE;
300                         tp_begin_touch(tp, t);
301                         t->millis = time;
302                         t->fake =true;
303                 }
304         }
305
306         assert(tp->nfingers_down == nfake_touches);
307 }
308
309 static void
310 tp_process_key(struct tp_dispatch *tp,
311                const struct input_event *e,
312                uint32_t time)
313 {
314         uint32_t mask;
315
316         switch (e->code) {
317                 case BTN_LEFT:
318                 case BTN_MIDDLE:
319                 case BTN_RIGHT:
320                         mask = 1 << (e->code - BTN_LEFT);
321                         if (e->value) {
322                                 tp->buttons.state |= mask;
323                                 tp->queued |= TOUCHPAD_EVENT_BUTTON_PRESS;
324                         } else {
325                                 tp->buttons.state &= ~mask;
326                                 tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
327                         }
328                         break;
329                 case BTN_TOUCH:
330                 case BTN_TOOL_DOUBLETAP:
331                 case BTN_TOOL_TRIPLETAP:
332                 case BTN_TOOL_QUADTAP:
333                         if (!tp->has_mt)
334                                 tp_process_fake_touch(tp, e, time);
335                         break;
336         }
337 }
338
339 static void
340 tp_process_state(struct tp_dispatch *tp, uint32_t time)
341 {
342         struct tp_touch *t;
343         struct tp_touch *first = tp_get_touch(tp, 0);
344
345         tp_for_each_touch(tp, t) {
346                 if (!tp->has_mt && t != first && first->fake) {
347                         t->x = first->x;
348                         t->y = first->y;
349                         if (!t->dirty)
350                                 t->dirty = first->dirty;
351                 } else if (!t->dirty)
352                         continue;
353
354                 tp_motion_hysteresis(tp, t);
355                 tp_motion_history_push(t);
356         }
357 }
358
359 static void
360 tp_post_process_state(struct tp_dispatch *tp, uint32_t time)
361 {
362         struct tp_touch *t;
363
364         tp_for_each_touch(tp, t) {
365                 if (!t->dirty)
366                         continue;
367
368                 if (t->state == TOUCH_END) {
369                         t->state = TOUCH_NONE;
370                         t->fake = false;
371                 } else if (t->state == TOUCH_BEGIN)
372                         t->state = TOUCH_UPDATE;
373
374                 t->dirty = false;
375         }
376
377         tp->buttons.old_state = tp->buttons.state;
378
379         tp->queued = TOUCHPAD_EVENT_NONE;
380 }
381
382 static void
383 tp_post_twofinger_scroll(struct tp_dispatch *tp, uint32_t time)
384 {
385         struct tp_touch *t;
386         int nchanged = 0;
387         double dx = 0, dy =0;
388         double tmpx, tmpy;
389
390         tp_for_each_touch(tp, t) {
391                 if (t->dirty) {
392                         nchanged++;
393                         tp_get_delta(t, &tmpx, &tmpy);
394
395                         dx += tmpx;
396                         dy += tmpy;
397                 }
398         }
399
400         if (nchanged == 0)
401                 return;
402
403         dx /= nchanged;
404         dy /= nchanged;
405
406         tp_filter_motion(tp, &dx, &dy, time);
407
408         if (tp->scroll.state == SCROLL_STATE_NONE) {
409                 /* Require at least one px scrolling to start */
410                 if (dx <= -1.0 || dx >= 1.0) {
411                         tp->scroll.state = SCROLL_STATE_SCROLLING;
412                         tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL);
413                 }
414
415                 if (dy <= -1.0 || dy >= 1.0) {
416                         tp->scroll.state = SCROLL_STATE_SCROLLING;
417                         tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL);
418                 }
419
420                 if (tp->scroll.state == SCROLL_STATE_NONE)
421                         return;
422         }
423
424         if (dy != 0.0 &&
425             (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL))) {
426                 pointer_notify_axis(&tp->device->base,
427                                     time,
428                                     LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL,
429                                     li_fixed_from_double(dy));
430         }
431
432         if (dx != 0.0 &&
433             (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL))) {
434                 pointer_notify_axis(&tp->device->base,
435                                     time,
436                                     LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
437                                     li_fixed_from_double(dx));
438         }
439 }
440
441 static int
442 tp_post_scroll_events(struct tp_dispatch *tp, uint32_t time)
443 {
444         if (tp->nfingers_down != 2) {
445                 /* terminate scrolling with a zero scroll event to notify
446                  * caller that it really ended now */
447                 if (tp->scroll.state != SCROLL_STATE_NONE) {
448                         tp->scroll.state = SCROLL_STATE_NONE;
449                         tp->scroll.direction = 0;
450                         if (tp->scroll.direction & LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL)
451                                 pointer_notify_axis(&tp->device->base,
452                                                     time,
453                                                     LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL,
454                                                     0);
455                         if (tp->scroll.direction & LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL)
456                                 pointer_notify_axis(&tp->device->base,
457                                                     time,
458                                                     LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
459                                                     0);
460                 }
461         } else {
462                 tp_post_twofinger_scroll(tp, time);
463                 return 1;
464         }
465         return 0;
466 }
467
468 static int
469 tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint32_t time)
470 {
471         uint32_t current, old, button;
472         enum libinput_pointer_button_state state;
473
474         current = tp->buttons.state;
475         old = tp->buttons.old_state;
476
477         if (current == old)
478                 return 0;
479
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;
484                 default:
485                         return 0;
486         }
487
488         if (current)
489                 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
490         else
491                 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
492
493         pointer_notify_button(&tp->device->base,
494                               time,
495                               button,
496                               state);
497         return 1;
498 }
499
500 static int
501 tp_post_physical_buttons(struct tp_dispatch *tp, uint32_t time)
502 {
503         uint32_t current, old, button;
504
505         current = tp->buttons.state;
506         old = tp->buttons.old_state;
507         button = BTN_LEFT;
508
509         while (current || old) {
510                 enum libinput_pointer_button_state state;
511
512                 if ((current & 0x1) ^ (old & 0x1)) {
513                         if (!!(current & 0x1))
514                                 state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
515                         else
516                                 state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
517
518                         pointer_notify_button(&tp->device->base,
519                                               time,
520                                               button,
521                                               state);
522                 }
523
524                 button++;
525                 current >>= 1;
526                 old >>= 1;
527         }
528
529         return 0;
530 }
531
532 static int
533 tp_post_button_events(struct tp_dispatch *tp, uint32_t time)
534 {
535         int rc;
536
537         if ((tp->queued &
538                 (TOUCHPAD_EVENT_BUTTON_PRESS|TOUCHPAD_EVENT_BUTTON_RELEASE)) == 0)
539                                 return 0;
540
541         if (tp->buttons.has_buttons)
542                 rc = tp_post_physical_buttons(tp, time);
543         else
544                 rc = tp_post_clickfinger_buttons(tp, time);
545
546         return rc;
547 }
548
549 static void
550 tp_post_events(struct tp_dispatch *tp, uint32_t time)
551 {
552         struct tp_touch *t = tp_current_touch(tp);
553         double dx, dy;
554
555         if (tp_post_button_events(tp, time) != 0)
556                 return;
557
558         if (tp_tap_handle_state(tp, time) != 0)
559                 return;
560
561         if (tp_post_scroll_events(tp, time) != 0)
562                 return;
563
564         if (t->history.count >= TOUCHPAD_MIN_SAMPLES &&
565             tp->nfingers_down == 1) {
566                 tp_get_delta(t, &dx, &dy);
567                 tp_filter_motion(tp, &dx, &dy, time);
568
569                 if (dx != 0 || dy != 0)
570                         pointer_notify_motion(
571                                 &tp->device->base,
572                                 time,
573                                 li_fixed_from_double(dx),
574                                 li_fixed_from_double(dy));
575         }
576 }
577
578 static void
579 tp_process(struct evdev_dispatch *dispatch,
580            struct evdev_device *device,
581            struct input_event *e,
582            uint32_t time)
583 {
584         struct tp_dispatch *tp =
585                 (struct tp_dispatch *)dispatch;
586
587         switch (e->type) {
588         case EV_ABS:
589                 if (tp->has_mt)
590                         tp_process_absolute(tp, e, time);
591                 else
592                         tp_process_absolute_st(tp, e, time);
593                 break;
594         case EV_KEY:
595                 tp_process_key(tp, e, time);
596                 break;
597         case EV_SYN:
598                 tp_process_state(tp, time);
599                 tp_post_events(tp, time);
600                 tp_post_process_state(tp, time);
601                 break;
602         }
603 }
604
605 static void
606 tp_destroy(struct evdev_dispatch *dispatch)
607 {
608         struct tp_dispatch *tp =
609                 (struct tp_dispatch*)dispatch;
610
611         if (tp->filter)
612                 tp->filter->interface->destroy(tp->filter);
613         free(tp->touches);
614         free(tp);
615 }
616
617 static struct evdev_dispatch_interface tp_interface = {
618         tp_process,
619         tp_destroy
620 };
621
622 static int
623 tp_init_slots(struct tp_dispatch *tp,
624               struct evdev_device *device)
625 {
626         const struct input_absinfo *absinfo;
627
628         absinfo = libevdev_get_abs_info(device->evdev, ABS_MT_SLOT);
629         if (absinfo) {
630                 tp->ntouches = absinfo->maximum + 1;
631                 tp->slot = absinfo->value;
632                 tp->has_mt = true;
633         } else {
634                 tp->ntouches = 5; /* FIXME: based on DOUBLETAP, etc. */
635                 tp->slot = 0;
636                 tp->has_mt = false;
637         }
638         tp->touches = calloc(tp->ntouches,
639                              sizeof(struct tp_touch));
640
641         return 0;
642 }
643
644 static int
645 tp_init_accel(struct tp_dispatch *touchpad, double diagonal)
646 {
647         struct motion_filter *accel;
648
649         touchpad->accel.constant_factor =
650                 DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
651         touchpad->accel.min_factor = DEFAULT_MIN_ACCEL_FACTOR;
652         touchpad->accel.max_factor = DEFAULT_MAX_ACCEL_FACTOR;
653
654         accel = create_pointer_accelator_filter(tp_accel_profile);
655         if (accel == NULL)
656                 return -1;
657
658         touchpad->filter = accel;
659
660         return 0;
661 }
662
663 static int
664 tp_init_scroll(struct tp_dispatch *tp)
665 {
666         tp->scroll.direction = 0;
667         tp->scroll.state = SCROLL_STATE_NONE;
668
669         return 0;
670 }
671
672 static int
673 tp_init(struct tp_dispatch *tp,
674         struct evdev_device *device)
675 {
676         int width, height;
677         double diagonal;
678
679         tp->base.interface = &tp_interface;
680         tp->device = device;
681
682         if (tp_init_slots(tp, device) != 0)
683                 return -1;
684
685         width = abs(device->abs.max_x - device->abs.min_x);
686         height = abs(device->abs.max_y - device->abs.min_y);
687         diagonal = sqrt(width*width + height*height);
688
689         tp->hysteresis.margin_x =
690                 diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
691         tp->hysteresis.margin_y =
692                 diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
693
694         if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT) ||
695             libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT))
696                 tp->buttons.has_buttons = true;
697
698         if (tp_init_scroll(tp) != 0)
699                 return -1;
700
701         if (tp_init_accel(tp, diagonal) != 0)
702                 return -1;
703
704         if (tp_init_tap(tp) != 0)
705                 return -1;
706
707         return 0;
708 }
709
710 struct evdev_dispatch *
711 evdev_mt_touchpad_create(struct evdev_device *device)
712 {
713         struct tp_dispatch *tp;
714
715         tp = zalloc(sizeof *tp);
716         if (!tp)
717                 return NULL;
718
719         if (tp_init(tp, device) != 0) {
720                 tp_destroy(&tp->base);
721                 return NULL;
722         }
723
724         return  &tp->base;
725 }