Replace pointer acceleration with a much simpler linear one
[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 #include <limits.h>
29
30 #include "evdev-mt-touchpad.h"
31
32 #define DEFAULT_ACCEL_NUMERATOR 1200.0
33 #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0
34
35 static inline int
36 tp_hysteresis(int in, int center, int margin)
37 {
38         int diff = in - center;
39         if (abs(diff) <= margin)
40                 return center;
41
42         if (diff > margin)
43                 return center + diff - margin;
44         else
45                 return center + diff + margin;
46 }
47
48 static inline struct tp_motion *
49 tp_motion_history_offset(struct tp_touch *t, int offset)
50 {
51         int offset_index =
52                 (t->history.index - offset + TOUCHPAD_HISTORY_LENGTH) %
53                 TOUCHPAD_HISTORY_LENGTH;
54
55         return &t->history.samples[offset_index];
56 }
57
58 static void
59 tp_filter_motion(struct tp_dispatch *tp,
60                  double *dx, double *dy, uint64_t time)
61 {
62         struct motion_params motion;
63
64         motion.dx = *dx * tp->accel.x_scale_coeff;
65         motion.dy = *dy * tp->accel.y_scale_coeff;
66
67         if (motion.dx != 0.0 || motion.dy != 0.0)
68                 filter_dispatch(tp->filter, &motion, tp, time);
69
70         *dx = motion.dx;
71         *dy = motion.dy;
72 }
73
74 static inline void
75 tp_motion_history_push(struct tp_touch *t)
76 {
77         int motion_index = (t->history.index + 1) % TOUCHPAD_HISTORY_LENGTH;
78
79         if (t->history.count < TOUCHPAD_HISTORY_LENGTH)
80                 t->history.count++;
81
82         t->history.samples[motion_index].x = t->x;
83         t->history.samples[motion_index].y = t->y;
84         t->history.index = motion_index;
85 }
86
87 static inline void
88 tp_motion_hysteresis(struct tp_dispatch *tp,
89                      struct tp_touch *t)
90 {
91         int x = t->x,
92             y = t->y;
93
94         if (t->history.count == 0) {
95                 t->hysteresis.center_x = t->x;
96                 t->hysteresis.center_y = t->y;
97         } else {
98                 x = tp_hysteresis(x,
99                                   t->hysteresis.center_x,
100                                   tp->hysteresis.margin_x);
101                 y = tp_hysteresis(y,
102                                   t->hysteresis.center_y,
103                                   tp->hysteresis.margin_y);
104                 t->hysteresis.center_x = x;
105                 t->hysteresis.center_y = y;
106                 t->x = x;
107                 t->y = y;
108         }
109 }
110
111 static inline void
112 tp_motion_history_reset(struct tp_touch *t)
113 {
114         t->history.count = 0;
115 }
116
117 static inline struct tp_touch *
118 tp_current_touch(struct tp_dispatch *tp)
119 {
120         return &tp->touches[min(tp->slot, tp->ntouches - 1)];
121 }
122
123 static inline struct tp_touch *
124 tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
125 {
126         assert(slot < tp->ntouches);
127         return &tp->touches[slot];
128 }
129
130 static inline void
131 tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
132 {
133         if (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE)
134                 return;
135
136         tp_motion_history_reset(t);
137         t->dirty = true;
138         t->state = TOUCH_BEGIN;
139         t->pinned.is_pinned = false;
140         t->millis = time;
141         tp->nfingers_down++;
142         assert(tp->nfingers_down >= 1);
143         tp->queued |= TOUCHPAD_EVENT_MOTION;
144 }
145
146 static inline void
147 tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
148 {
149         if (t->state == TOUCH_END || t->state == TOUCH_NONE)
150                 return;
151
152         t->dirty = true;
153         t->is_pointer = false;
154         t->palm.is_palm = false;
155         t->state = TOUCH_END;
156         t->pinned.is_pinned = false;
157         t->millis = time;
158         assert(tp->nfingers_down >= 1);
159         tp->nfingers_down--;
160         tp->queued |= TOUCHPAD_EVENT_MOTION;
161 }
162
163 static double
164 tp_estimate_delta(int x0, int x1, int x2, int x3)
165 {
166         return (x0 + x1 - x2 - x3) / 4.0;
167 }
168
169 void
170 tp_get_delta(struct tp_touch *t, double *dx, double *dy)
171 {
172         if (t->history.count < 4) {
173                 *dx = 0;
174                 *dy = 0;
175                 return;
176         }
177
178         *dx = tp_estimate_delta(tp_motion_history_offset(t, 0)->x,
179                                 tp_motion_history_offset(t, 1)->x,
180                                 tp_motion_history_offset(t, 2)->x,
181                                 tp_motion_history_offset(t, 3)->x);
182         *dy = tp_estimate_delta(tp_motion_history_offset(t, 0)->y,
183                                 tp_motion_history_offset(t, 1)->y,
184                                 tp_motion_history_offset(t, 2)->y,
185                                 tp_motion_history_offset(t, 3)->y);
186 }
187
188 static void
189 tp_process_absolute(struct tp_dispatch *tp,
190                     const struct input_event *e,
191                     uint64_t time)
192 {
193         struct tp_touch *t = tp_current_touch(tp);
194
195         switch(e->code) {
196         case ABS_MT_POSITION_X:
197                 t->x = e->value;
198                 t->millis = time;
199                 t->dirty = true;
200                 tp->queued |= TOUCHPAD_EVENT_MOTION;
201                 break;
202         case ABS_MT_POSITION_Y:
203                 t->y = e->value;
204                 t->millis = time;
205                 t->dirty = true;
206                 tp->queued |= TOUCHPAD_EVENT_MOTION;
207                 break;
208         case ABS_MT_SLOT:
209                 tp->slot = e->value;
210                 break;
211         case ABS_MT_TRACKING_ID:
212                 if (e->value != -1)
213                         tp_begin_touch(tp, t, time);
214                 else
215                         tp_end_touch(tp, t, time);
216         }
217 }
218
219 static void
220 tp_process_absolute_st(struct tp_dispatch *tp,
221                        const struct input_event *e,
222                        uint64_t time)
223 {
224         struct tp_touch *t = tp_current_touch(tp);
225
226         switch(e->code) {
227         case ABS_X:
228                 t->x = e->value;
229                 t->millis = time;
230                 t->dirty = true;
231                 tp->queued |= TOUCHPAD_EVENT_MOTION;
232                 break;
233         case ABS_Y:
234                 t->y = e->value;
235                 t->millis = time;
236                 t->dirty = true;
237                 tp->queued |= TOUCHPAD_EVENT_MOTION;
238                 break;
239         }
240 }
241
242 static void
243 tp_process_fake_touch(struct tp_dispatch *tp,
244                       const struct input_event *e,
245                       uint64_t time)
246 {
247         struct tp_touch *t;
248         unsigned int fake_touches;
249         unsigned int nfake_touches;
250         unsigned int i, start;
251         unsigned int shift;
252
253         if (e->code != BTN_TOUCH &&
254             (e->code < BTN_TOOL_DOUBLETAP || e->code > BTN_TOOL_QUADTAP))
255                 return;
256
257         shift = e->code == BTN_TOUCH ? 0 : (e->code - BTN_TOOL_DOUBLETAP + 1);
258
259         if (e->value)
260                 tp->fake_touches |= 1 << shift;
261         else
262                 tp->fake_touches &= ~(0x1 << shift);
263
264         fake_touches = tp->fake_touches;
265         nfake_touches = 0;
266         while (fake_touches) {
267                 nfake_touches++;
268                 fake_touches >>= 1;
269         }
270
271         /* For single touch tps we use BTN_TOUCH for begin / end of touch 0 */
272         start = tp->has_mt ? tp->real_touches : 0;
273         for (i = start; i < tp->ntouches; i++) {
274                 t = tp_get_touch(tp, i);
275                 if (i < nfake_touches)
276                         tp_begin_touch(tp, t, time);
277                 else
278                         tp_end_touch(tp, t, time);
279         }
280
281         /* On mt the actual touch info may arrive after BTN_TOOL_FOO */
282         assert(tp->has_mt || tp->nfingers_down == nfake_touches);
283 }
284
285 static void
286 tp_process_key(struct tp_dispatch *tp,
287                const struct input_event *e,
288                uint64_t time)
289 {
290         switch (e->code) {
291                 case BTN_LEFT:
292                 case BTN_MIDDLE:
293                 case BTN_RIGHT:
294                         tp_process_button(tp, e, time);
295                         break;
296                 case BTN_TOUCH:
297                 case BTN_TOOL_DOUBLETAP:
298                 case BTN_TOOL_TRIPLETAP:
299                 case BTN_TOOL_QUADTAP:
300                         tp_process_fake_touch(tp, e, time);
301                         break;
302         }
303 }
304
305 static void
306 tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
307 {
308         unsigned int xdist, ydist;
309
310         if (!t->pinned.is_pinned)
311                 return;
312
313         xdist = abs(t->x - t->pinned.center_x);
314         ydist = abs(t->y - t->pinned.center_y);
315
316         if (xdist * xdist + ydist * ydist >=
317                         tp->buttons.motion_dist * tp->buttons.motion_dist) {
318                 t->pinned.is_pinned = false;
319                 tp_set_pointer(tp, t);
320         }
321 }
322
323 static void
324 tp_pin_fingers(struct tp_dispatch *tp)
325 {
326         struct tp_touch *t;
327
328         tp_for_each_touch(tp, t) {
329                 t->is_pointer = false;
330                 t->pinned.is_pinned = true;
331                 t->pinned.center_x = t->x;
332                 t->pinned.center_y = t->y;
333         }
334 }
335
336 static int
337 tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
338 {
339         return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) &&
340                 !t->palm.is_palm &&
341                 !t->pinned.is_pinned && tp_button_touch_active(tp, t);
342 }
343
344 void
345 tp_set_pointer(struct tp_dispatch *tp, struct tp_touch *t)
346 {
347         struct tp_touch *tmp = NULL;
348
349         /* Only set the touch as pointer if we don't have one yet */
350         tp_for_each_touch(tp, tmp) {
351                 if (tmp->is_pointer)
352                         return;
353         }
354
355         if (tp_touch_active(tp, t))
356                 t->is_pointer = true;
357 }
358
359 static void
360 tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
361 {
362         const int PALM_TIMEOUT = 200; /* ms */
363         const int DIRECTIONS = NE|E|SE|SW|W|NW;
364
365         /* If labelled a touch as palm, we unlabel as palm when
366            we move out of the palm edge zone within the timeout, provided
367            the direction is within 45 degrees of the horizontal.
368          */
369         if (t->palm.is_palm) {
370                 if (time < t->palm.time + PALM_TIMEOUT &&
371                     (t->x > tp->palm.left_edge && t->x < tp->palm.right_edge)) {
372                         int dirs = vector_get_direction(t->x - t->palm.x, t->y - t->palm.y);
373                         if ((dirs & DIRECTIONS) && !(dirs & ~DIRECTIONS)) {
374                                 t->palm.is_palm = false;
375                                 tp_set_pointer(tp, t);
376                         }
377                 }
378                 return;
379         }
380
381         /* palm must start in exclusion zone, it's ok to move into
382            the zone without being a palm */
383         if (t->state != TOUCH_BEGIN ||
384             (t->x > tp->palm.left_edge && t->x < tp->palm.right_edge))
385                 return;
386
387         /* don't detect palm in software button areas, it's
388            likely that legitimate touches start in the area
389            covered by the exclusion zone */
390         if (tp->buttons.is_clickpad &&
391             tp_button_is_inside_softbutton_area(tp, t))
392                 return;
393
394         t->palm.is_palm = true;
395         t->palm.time = time;
396         t->palm.x = t->x;
397         t->palm.y = t->y;
398 }
399
400 static void
401 tp_process_state(struct tp_dispatch *tp, uint64_t time)
402 {
403         struct tp_touch *t;
404         struct tp_touch *first = tp_get_touch(tp, 0);
405         unsigned int i;
406
407         for (i = 0; i < tp->ntouches; i++) {
408                 t = tp_get_touch(tp, i);
409
410                 /* semi-mt finger postions may "jump" when nfingers changes */
411                 if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
412                         tp_motion_history_reset(t);
413
414                 if (i >= tp->real_touches && t->state != TOUCH_NONE) {
415                         t->x = first->x;
416                         t->y = first->y;
417                         if (!t->dirty)
418                                 t->dirty = first->dirty;
419                 }
420
421                 if (!t->dirty)
422                         continue;
423
424                 tp_palm_detect(tp, t, time);
425
426                 tp_motion_hysteresis(tp, t);
427                 tp_motion_history_push(t);
428
429                 tp_unpin_finger(tp, t);
430         }
431
432         tp_button_handle_state(tp, time);
433
434         /*
435          * We have a physical button down event on a clickpad. To avoid
436          * spurious pointer moves by the clicking finger we pin all fingers.
437          * We unpin fingers when they move more then a certain threshold to
438          * to allow drag and drop.
439          */
440         if ((tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) &&
441             tp->buttons.is_clickpad)
442                 tp_pin_fingers(tp);
443 }
444
445 static void
446 tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
447 {
448         struct tp_touch *t;
449
450         tp_for_each_touch(tp, t) {
451                 if (!t->dirty)
452                         continue;
453
454                 if (t->state == TOUCH_END)
455                         t->state = TOUCH_NONE;
456                 else if (t->state == TOUCH_BEGIN)
457                         t->state = TOUCH_UPDATE;
458
459                 t->dirty = false;
460         }
461
462         tp->old_nfingers_down = tp->nfingers_down;
463         tp->buttons.old_state = tp->buttons.state;
464
465         tp->queued = TOUCHPAD_EVENT_NONE;
466 }
467
468 static void
469 tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
470 {
471         struct tp_touch *t;
472         int nchanged = 0;
473         double dx = 0, dy =0;
474         double tmpx, tmpy;
475
476         tp_for_each_touch(tp, t) {
477                 if (tp_touch_active(tp, t) && t->dirty) {
478                         nchanged++;
479                         tp_get_delta(t, &tmpx, &tmpy);
480
481                         dx += tmpx;
482                         dy += tmpy;
483                 }
484                 /* Stop spurious MOTION events at the end of scrolling */
485                 t->is_pointer = false;
486         }
487
488         if (nchanged == 0)
489                 return;
490
491         dx /= nchanged;
492         dy /= nchanged;
493
494         tp_filter_motion(tp, &dx, &dy, time);
495         evdev_post_scroll(tp->device, time, dx, dy);
496 }
497
498 static int
499 tp_post_scroll_events(struct tp_dispatch *tp, uint64_t time)
500 {
501         struct tp_touch *t;
502         int nfingers_down = 0;
503
504         /* Only count active touches for 2 finger scrolling */
505         tp_for_each_touch(tp, t) {
506                 if (tp_touch_active(tp, t))
507                         nfingers_down++;
508         }
509
510         if (nfingers_down != 2) {
511                 evdev_stop_scroll(tp->device, time);
512                 return 0;
513         }
514
515         tp_post_twofinger_scroll(tp, time);
516         return 1;
517 }
518
519 static void
520 tp_post_events(struct tp_dispatch *tp, uint64_t time)
521 {
522         struct tp_touch *t = tp_current_touch(tp);
523         double dx, dy;
524         int consumed = 0;
525
526         /* Only post (top) button events while suspended */
527         if (tp->device->suspended) {
528                 tp_post_button_events(tp, time);
529                 return;
530         }
531
532         consumed |= tp_tap_handle_state(tp, time);
533         consumed |= tp_post_button_events(tp, time);
534
535         if (consumed) {
536                 evdev_stop_scroll(tp->device, time);
537                 return;
538         }
539
540         if (tp_post_scroll_events(tp, time) != 0)
541                 return;
542
543         if (!t->is_pointer) {
544                 tp_for_each_touch(tp, t) {
545                         if (t->is_pointer)
546                                 break;
547                 }
548         }
549
550         if (!t->is_pointer ||
551             !t->dirty ||
552             t->history.count < TOUCHPAD_MIN_SAMPLES)
553                 return;
554
555         tp_get_delta(t, &dx, &dy);
556         tp_filter_motion(tp, &dx, &dy, time);
557
558         if (dx != 0.0 || dy != 0.0)
559                 pointer_notify_motion(&tp->device->base, time, dx, dy);
560 }
561
562 static void
563 tp_handle_state(struct tp_dispatch *tp,
564                 uint64_t time)
565 {
566         tp_process_state(tp, time);
567         tp_post_events(tp, time);
568         tp_post_process_state(tp, time);
569 }
570
571 static void
572 tp_process(struct evdev_dispatch *dispatch,
573            struct evdev_device *device,
574            struct input_event *e,
575            uint64_t time)
576 {
577         struct tp_dispatch *tp =
578                 (struct tp_dispatch *)dispatch;
579
580         switch (e->type) {
581         case EV_ABS:
582                 if (tp->has_mt)
583                         tp_process_absolute(tp, e, time);
584                 else
585                         tp_process_absolute_st(tp, e, time);
586                 break;
587         case EV_KEY:
588                 tp_process_key(tp, e, time);
589                 break;
590         case EV_SYN:
591                 tp_handle_state(tp, time);
592                 break;
593         }
594 }
595
596 static void
597 tp_destroy(struct evdev_dispatch *dispatch)
598 {
599         struct tp_dispatch *tp =
600                 (struct tp_dispatch*)dispatch;
601
602         tp_destroy_tap(tp);
603         tp_destroy_buttons(tp);
604
605         filter_destroy(tp->filter);
606         free(tp->touches);
607         free(tp);
608 }
609
610 static void
611 tp_clear_state(struct tp_dispatch *tp, struct evdev_device *device)
612 {
613         uint64_t now = libinput_now(tp->device->base.seat->libinput);
614         struct tp_touch *t;
615
616         /* Unroll the touchpad state.
617          * Release buttons first. If tp is a clickpad, the button event
618          * must come before the touch up. If it isn't, the order doesn't
619          * matter anyway
620          *
621          * Then cancel all timeouts on the taps, triggering the last set
622          * of events.
623          *
624          * Then lift all touches so the touchpad is in a neutral state.
625          *
626          */
627         tp_release_all_buttons(tp, now);
628         tp_release_all_taps(tp, now);
629
630         tp_for_each_touch(tp, t) {
631                 tp_end_touch(tp, t, now);
632         }
633
634         tp_handle_state(tp, now);
635 }
636
637 static void
638 tp_suspend(struct tp_dispatch *tp, struct evdev_device *device)
639 {
640         tp_clear_state(tp, device);
641
642         /* On devices with top softwarebuttons we don't actually suspend the
643          * device, to keep the "trackpoint" buttons working. tp_post_events()
644          * will only send events for the trackpoint while suspended.
645          */
646         if (tp->buttons.has_topbuttons) {
647                 evdev_notify_suspended_device(device);
648                 /* Enlarge topbutton area while suspended */
649                 tp_init_softbuttons(tp, device, 1.5);
650         } else {
651                 evdev_device_suspend(device);
652         }
653 }
654
655 static void
656 tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
657 {
658         if (tp->buttons.has_topbuttons) {
659                 /* tap state-machine is offline while suspended, reset state */
660                 tp_clear_state(tp, device);
661                 /* restore original topbutton area size */
662                 tp_init_softbuttons(tp, device, 1.0);
663                 evdev_notify_resumed_device(device);
664         } else {
665                 evdev_device_resume(device);
666         }
667 }
668
669 static void
670 tp_device_added(struct evdev_device *device,
671                 struct evdev_device *added_device)
672 {
673         struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
674
675         if (tp->buttons.trackpoint == NULL &&
676             (added_device->tags & EVDEV_TAG_TRACKPOINT)) {
677                 /* Don't send any pending releases to the new trackpoint */
678                 tp->buttons.active_is_topbutton = false;
679                 tp->buttons.trackpoint = added_device;
680         }
681
682         if (tp->sendevents.current_mode !=
683             LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
684                 return;
685
686         if (added_device->tags & EVDEV_TAG_EXTERNAL_MOUSE)
687                 tp_suspend(tp, device);
688 }
689
690 static void
691 tp_device_removed(struct evdev_device *device,
692                   struct evdev_device *removed_device)
693 {
694         struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
695         struct libinput_device *dev;
696
697         if (removed_device == tp->buttons.trackpoint) {
698                 /* Clear any pending releases for the trackpoint */
699                 if (tp->buttons.active && tp->buttons.active_is_topbutton) {
700                         tp->buttons.active = 0;
701                         tp->buttons.active_is_topbutton = false;
702                 }
703                 tp->buttons.trackpoint = NULL;
704         }
705
706         if (tp->sendevents.current_mode !=
707             LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
708                 return;
709
710         list_for_each(dev, &device->base.seat->devices_list, link) {
711                 struct evdev_device *d = (struct evdev_device*)dev;
712                 if (d != removed_device &&
713                     (d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
714                         return;
715                 }
716         }
717
718         tp_resume(tp, device);
719 }
720
721 static void
722 tp_tag_device(struct evdev_device *device,
723               struct udev_device *udev_device)
724 {
725         int bustype;
726
727         /* simple approach: touchpads on USB or Bluetooth are considered
728          * external, anything else is internal. Exception is Apple -
729          * internal touchpads are connected over USB and it doesn't have
730          * external USB touchpads anyway.
731          */
732         bustype = libevdev_get_id_bustype(device->evdev);
733         if (bustype == BUS_USB) {
734                  if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_APPLE)
735                          device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
736         } else if (bustype != BUS_BLUETOOTH)
737                 device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
738 }
739
740 static struct evdev_dispatch_interface tp_interface = {
741         tp_process,
742         tp_destroy,
743         tp_device_added,
744         tp_device_removed,
745         tp_device_removed, /* device_suspended, treat as remove */
746         tp_device_added,   /* device_resumed, treat as add */
747         tp_tag_device,
748 };
749
750 static void
751 tp_init_touch(struct tp_dispatch *tp,
752               struct tp_touch *t)
753 {
754         t->tp = tp;
755 }
756
757 static int
758 tp_init_slots(struct tp_dispatch *tp,
759               struct evdev_device *device)
760 {
761         const struct input_absinfo *absinfo;
762         struct map {
763                 unsigned int code;
764                 int ntouches;
765         } max_touches[] = {
766                 { BTN_TOOL_QUINTTAP, 5 },
767                 { BTN_TOOL_QUADTAP, 4 },
768                 { BTN_TOOL_TRIPLETAP, 3 },
769                 { BTN_TOOL_DOUBLETAP, 2 },
770         };
771         struct map *m;
772         unsigned int i, n_btn_tool_touches = 1;
773
774         absinfo = libevdev_get_abs_info(device->evdev, ABS_MT_SLOT);
775         if (absinfo) {
776                 tp->real_touches = absinfo->maximum + 1;
777                 tp->slot = absinfo->value;
778                 tp->has_mt = true;
779         } else {
780                 tp->real_touches = 1;
781                 tp->slot = 0;
782                 tp->has_mt = false;
783         }
784
785         tp->semi_mt = libevdev_has_property(device->evdev, INPUT_PROP_SEMI_MT);
786
787         ARRAY_FOR_EACH(max_touches, m) {
788                 if (libevdev_has_event_code(device->evdev,
789                                             EV_KEY,
790                                             m->code)) {
791                         n_btn_tool_touches = m->ntouches;
792                         break;
793                 }
794         }
795
796         tp->ntouches = max(tp->real_touches, n_btn_tool_touches);
797         tp->touches = calloc(tp->ntouches, sizeof(struct tp_touch));
798         if (!tp->touches)
799                 return -1;
800
801         for (i = 0; i < tp->ntouches; i++)
802                 tp_init_touch(tp, &tp->touches[i]);
803
804         return 0;
805 }
806
807 static int
808 tp_init_accel(struct tp_dispatch *tp, double diagonal)
809 {
810         struct motion_filter *accel;
811         int res_x, res_y;
812
813         if (tp->has_mt) {
814                 res_x = libevdev_get_abs_resolution(tp->device->evdev,
815                                                     ABS_MT_POSITION_X);
816                 res_y = libevdev_get_abs_resolution(tp->device->evdev,
817                                                     ABS_MT_POSITION_Y);
818         } else {
819                 res_x = libevdev_get_abs_resolution(tp->device->evdev,
820                                                     ABS_X);
821                 res_y = libevdev_get_abs_resolution(tp->device->evdev,
822                                                     ABS_Y);
823         }
824
825         /*
826          * Not all touchpads report the same amount of units/mm (resolution).
827          * Normalize motion events to a resolution of 15.74 units/mm
828          * (== 400 dpi) as base (unaccelerated) speed. This also evens out any
829          * differences in x and y resolution, so that a circle on the
830          * touchpad does not turn into an elipse on the screen.
831          *
832          * We pick 400dpi as thats one of the many default resolutions
833          * for USB mice, so we end up with a similar base speed on the device.
834          */
835         if (res_x > 1 && res_y > 1) {
836                 tp->accel.x_scale_coeff = (400/25.4) / res_x;
837                 tp->accel.y_scale_coeff = (400/25.4) / res_y;
838         } else {
839         /*
840          * For touchpads where the driver does not provide resolution, fall
841          * back to scaling motion events based on the diagonal size in units.
842          */
843                 tp->accel.x_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
844                 tp->accel.y_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
845         }
846
847         accel = create_pointer_accelator_filter(
848                         pointer_accel_profile_linear);
849         if (accel == NULL)
850                 return -1;
851
852         tp->filter = accel;
853
854         return 0;
855 }
856
857 static int
858 tp_init_palmdetect(struct tp_dispatch *tp,
859                    struct evdev_device *device)
860 {
861         int width;
862
863         tp->palm.right_edge = INT_MAX;
864         tp->palm.left_edge = INT_MIN;
865
866         width = abs(device->abs.absinfo_x->maximum -
867                     device->abs.absinfo_x->minimum);
868
869         /* Apple touchpads are always big enough to warrant palm detection */
870         if (evdev_device_get_id_vendor(device) != VENDOR_ID_APPLE) {
871                 /* We don't know how big the touchpad is */
872                 if (device->abs.absinfo_x->resolution == 1)
873                         return 0;
874
875                 /* Enable palm detection on touchpads >= 80 mm. Anything smaller
876                    probably won't need it, until we find out it does */
877                 if (width/device->abs.absinfo_x->resolution < 80)
878                         return 0;
879         }
880
881         /* palm edges are 5% of the width on each side */
882         tp->palm.right_edge = device->abs.absinfo_x->maximum - width * 0.05;
883         tp->palm.left_edge = device->abs.absinfo_x->minimum + width * 0.05;
884
885         return 0;
886 }
887
888 static int
889 tp_init(struct tp_dispatch *tp,
890         struct evdev_device *device)
891 {
892         int width, height;
893         double diagonal;
894
895         tp->base.interface = &tp_interface;
896         tp->device = device;
897
898         if (tp_init_slots(tp, device) != 0)
899                 return -1;
900
901         width = abs(device->abs.absinfo_x->maximum -
902                     device->abs.absinfo_x->minimum);
903         height = abs(device->abs.absinfo_y->maximum -
904                      device->abs.absinfo_y->minimum);
905         diagonal = sqrt(width*width + height*height);
906
907         tp->hysteresis.margin_x =
908                 diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
909         tp->hysteresis.margin_y =
910                 diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
911
912         if (tp_init_accel(tp, diagonal) != 0)
913                 return -1;
914
915         if (tp_init_tap(tp) != 0)
916                 return -1;
917
918         if (tp_init_buttons(tp, device) != 0)
919                 return -1;
920
921         if (tp_init_palmdetect(tp, device) != 0)
922                 return -1;
923
924         device->seat_caps |= EVDEV_DEVICE_POINTER;
925
926         return 0;
927 }
928
929 static uint32_t
930 tp_sendevents_get_modes(struct libinput_device *device)
931 {
932         struct evdev_device *evdev = (struct evdev_device*)device;
933         uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
934                          LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
935
936         if (evdev->tags & EVDEV_TAG_INTERNAL_TOUCHPAD)
937                 modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
938
939         return modes;
940 }
941
942 static void
943 tp_suspend_conditional(struct tp_dispatch *tp,
944                        struct evdev_device *device)
945 {
946         struct libinput_device *dev;
947
948         list_for_each(dev, &device->base.seat->devices_list, link) {
949                 struct evdev_device *d = (struct evdev_device*)dev;
950                 if (d->tags & EVDEV_TAG_EXTERNAL_MOUSE) {
951                         tp_suspend(tp, device);
952                         return;
953                 }
954         }
955 }
956
957 static enum libinput_config_status
958 tp_sendevents_set_mode(struct libinput_device *device,
959                        enum libinput_config_send_events_mode mode)
960 {
961         struct evdev_device *evdev = (struct evdev_device*)device;
962         struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
963
964         if (mode == tp->sendevents.current_mode)
965                 return LIBINPUT_CONFIG_STATUS_SUCCESS;
966
967         switch(mode) {
968         case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
969                 tp_resume(tp, evdev);
970                 break;
971         case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
972                 tp_suspend(tp, evdev);
973                 break;
974         case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
975                 tp_suspend_conditional(tp, evdev);
976                 break;
977         default:
978                 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
979         }
980
981         tp->sendevents.current_mode = mode;
982
983         return LIBINPUT_CONFIG_STATUS_SUCCESS;
984 }
985
986 static enum libinput_config_send_events_mode
987 tp_sendevents_get_mode(struct libinput_device *device)
988 {
989         struct evdev_device *evdev = (struct evdev_device*)device;
990         struct tp_dispatch *dispatch = (struct tp_dispatch*)evdev->dispatch;
991
992         return dispatch->sendevents.current_mode;
993 }
994
995 static enum libinput_config_send_events_mode
996 tp_sendevents_get_default_mode(struct libinput_device *device)
997 {
998         return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
999 }
1000
1001 struct evdev_dispatch *
1002 evdev_mt_touchpad_create(struct evdev_device *device)
1003 {
1004         struct tp_dispatch *tp;
1005
1006         tp = zalloc(sizeof *tp);
1007         if (!tp)
1008                 return NULL;
1009
1010         if (tp_init(tp, device) != 0) {
1011                 tp_destroy(&tp->base);
1012                 return NULL;
1013         }
1014
1015         device->base.config.sendevents = &tp->sendevents.config;
1016
1017         tp->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
1018         tp->sendevents.config.get_modes = tp_sendevents_get_modes;
1019         tp->sendevents.config.set_mode = tp_sendevents_set_mode;
1020         tp->sendevents.config.get_mode = tp_sendevents_get_mode;
1021         tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode;
1022
1023         return  &tp->base;
1024 }