touchpad: hook up natural scrolling configuration
[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->device->pointer.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
496         if (tp->scroll.natural_scrolling_enabled) {
497                 dx = -dx;
498                 dy = -dy;
499         }
500
501         evdev_post_scroll(tp->device, time, dx, dy);
502 }
503
504 static int
505 tp_post_scroll_events(struct tp_dispatch *tp, uint64_t time)
506 {
507         struct tp_touch *t;
508         int nfingers_down = 0;
509
510         /* Only count active touches for 2 finger scrolling */
511         tp_for_each_touch(tp, t) {
512                 if (tp_touch_active(tp, t))
513                         nfingers_down++;
514         }
515
516         if (nfingers_down != 2) {
517                 evdev_stop_scroll(tp->device, time);
518                 return 0;
519         }
520
521         tp_post_twofinger_scroll(tp, time);
522         return 1;
523 }
524
525 static void
526 tp_post_events(struct tp_dispatch *tp, uint64_t time)
527 {
528         struct tp_touch *t = tp_current_touch(tp);
529         double dx, dy;
530         int consumed = 0;
531
532         /* Only post (top) button events while suspended */
533         if (tp->device->suspended) {
534                 tp_post_button_events(tp, time);
535                 return;
536         }
537
538         consumed |= tp_tap_handle_state(tp, time);
539         consumed |= tp_post_button_events(tp, time);
540
541         if (consumed) {
542                 evdev_stop_scroll(tp->device, time);
543                 return;
544         }
545
546         if (tp_post_scroll_events(tp, time) != 0)
547                 return;
548
549         if (!t->is_pointer) {
550                 tp_for_each_touch(tp, t) {
551                         if (t->is_pointer)
552                                 break;
553                 }
554         }
555
556         if (!t->is_pointer ||
557             !t->dirty ||
558             t->history.count < TOUCHPAD_MIN_SAMPLES)
559                 return;
560
561         tp_get_delta(t, &dx, &dy);
562         tp_filter_motion(tp, &dx, &dy, time);
563
564         if (dx != 0.0 || dy != 0.0)
565                 pointer_notify_motion(&tp->device->base, time, dx, dy);
566 }
567
568 static void
569 tp_handle_state(struct tp_dispatch *tp,
570                 uint64_t time)
571 {
572         tp_process_state(tp, time);
573         tp_post_events(tp, time);
574         tp_post_process_state(tp, time);
575 }
576
577 static void
578 tp_process(struct evdev_dispatch *dispatch,
579            struct evdev_device *device,
580            struct input_event *e,
581            uint64_t time)
582 {
583         struct tp_dispatch *tp =
584                 (struct tp_dispatch *)dispatch;
585
586         switch (e->type) {
587         case EV_ABS:
588                 if (tp->has_mt)
589                         tp_process_absolute(tp, e, time);
590                 else
591                         tp_process_absolute_st(tp, e, time);
592                 break;
593         case EV_KEY:
594                 tp_process_key(tp, e, time);
595                 break;
596         case EV_SYN:
597                 tp_handle_state(tp, time);
598                 break;
599         }
600 }
601
602 static void
603 tp_destroy(struct evdev_dispatch *dispatch)
604 {
605         struct tp_dispatch *tp =
606                 (struct tp_dispatch*)dispatch;
607
608         tp_destroy_tap(tp);
609         tp_destroy_buttons(tp);
610
611         free(tp->touches);
612         free(tp);
613 }
614
615 static void
616 tp_clear_state(struct tp_dispatch *tp, struct evdev_device *device)
617 {
618         uint64_t now = libinput_now(tp->device->base.seat->libinput);
619         struct tp_touch *t;
620
621         /* Unroll the touchpad state.
622          * Release buttons first. If tp is a clickpad, the button event
623          * must come before the touch up. If it isn't, the order doesn't
624          * matter anyway
625          *
626          * Then cancel all timeouts on the taps, triggering the last set
627          * of events.
628          *
629          * Then lift all touches so the touchpad is in a neutral state.
630          *
631          */
632         tp_release_all_buttons(tp, now);
633         tp_release_all_taps(tp, now);
634
635         tp_for_each_touch(tp, t) {
636                 tp_end_touch(tp, t, now);
637         }
638
639         tp_handle_state(tp, now);
640 }
641
642 static void
643 tp_suspend(struct tp_dispatch *tp, struct evdev_device *device)
644 {
645         tp_clear_state(tp, device);
646
647         /* On devices with top softwarebuttons we don't actually suspend the
648          * device, to keep the "trackpoint" buttons working. tp_post_events()
649          * will only send events for the trackpoint while suspended.
650          */
651         if (tp->buttons.has_topbuttons) {
652                 evdev_notify_suspended_device(device);
653                 /* Enlarge topbutton area while suspended */
654                 tp_init_softbuttons(tp, device, 1.5);
655         } else {
656                 evdev_device_suspend(device);
657         }
658 }
659
660 static void
661 tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
662 {
663         if (tp->buttons.has_topbuttons) {
664                 /* tap state-machine is offline while suspended, reset state */
665                 tp_clear_state(tp, device);
666                 /* restore original topbutton area size */
667                 tp_init_softbuttons(tp, device, 1.0);
668                 evdev_notify_resumed_device(device);
669         } else {
670                 evdev_device_resume(device);
671         }
672 }
673
674 static void
675 tp_device_added(struct evdev_device *device,
676                 struct evdev_device *added_device)
677 {
678         struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
679
680         if (tp->buttons.trackpoint == NULL &&
681             (added_device->tags & EVDEV_TAG_TRACKPOINT)) {
682                 /* Don't send any pending releases to the new trackpoint */
683                 tp->buttons.active_is_topbutton = false;
684                 tp->buttons.trackpoint = added_device;
685         }
686
687         if (tp->sendevents.current_mode !=
688             LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
689                 return;
690
691         if (added_device->tags & EVDEV_TAG_EXTERNAL_MOUSE)
692                 tp_suspend(tp, device);
693 }
694
695 static void
696 tp_device_removed(struct evdev_device *device,
697                   struct evdev_device *removed_device)
698 {
699         struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
700         struct libinput_device *dev;
701
702         if (removed_device == tp->buttons.trackpoint) {
703                 /* Clear any pending releases for the trackpoint */
704                 if (tp->buttons.active && tp->buttons.active_is_topbutton) {
705                         tp->buttons.active = 0;
706                         tp->buttons.active_is_topbutton = false;
707                 }
708                 tp->buttons.trackpoint = NULL;
709         }
710
711         if (tp->sendevents.current_mode !=
712             LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
713                 return;
714
715         list_for_each(dev, &device->base.seat->devices_list, link) {
716                 struct evdev_device *d = (struct evdev_device*)dev;
717                 if (d != removed_device &&
718                     (d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
719                         return;
720                 }
721         }
722
723         tp_resume(tp, device);
724 }
725
726 static void
727 tp_tag_device(struct evdev_device *device,
728               struct udev_device *udev_device)
729 {
730         int bustype;
731
732         /* simple approach: touchpads on USB or Bluetooth are considered
733          * external, anything else is internal. Exception is Apple -
734          * internal touchpads are connected over USB and it doesn't have
735          * external USB touchpads anyway.
736          */
737         bustype = libevdev_get_id_bustype(device->evdev);
738         if (bustype == BUS_USB) {
739                  if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_APPLE)
740                          device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
741         } else if (bustype != BUS_BLUETOOTH)
742                 device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
743 }
744
745 static struct evdev_dispatch_interface tp_interface = {
746         tp_process,
747         tp_destroy,
748         tp_device_added,
749         tp_device_removed,
750         tp_device_removed, /* device_suspended, treat as remove */
751         tp_device_added,   /* device_resumed, treat as add */
752         tp_tag_device,
753 };
754
755 static void
756 tp_init_touch(struct tp_dispatch *tp,
757               struct tp_touch *t)
758 {
759         t->tp = tp;
760 }
761
762 static int
763 tp_init_slots(struct tp_dispatch *tp,
764               struct evdev_device *device)
765 {
766         const struct input_absinfo *absinfo;
767         struct map {
768                 unsigned int code;
769                 int ntouches;
770         } max_touches[] = {
771                 { BTN_TOOL_QUINTTAP, 5 },
772                 { BTN_TOOL_QUADTAP, 4 },
773                 { BTN_TOOL_TRIPLETAP, 3 },
774                 { BTN_TOOL_DOUBLETAP, 2 },
775         };
776         struct map *m;
777         unsigned int i, n_btn_tool_touches = 1;
778
779         absinfo = libevdev_get_abs_info(device->evdev, ABS_MT_SLOT);
780         if (absinfo) {
781                 tp->real_touches = absinfo->maximum + 1;
782                 tp->slot = absinfo->value;
783                 tp->has_mt = true;
784         } else {
785                 tp->real_touches = 1;
786                 tp->slot = 0;
787                 tp->has_mt = false;
788         }
789
790         tp->semi_mt = libevdev_has_property(device->evdev, INPUT_PROP_SEMI_MT);
791
792         ARRAY_FOR_EACH(max_touches, m) {
793                 if (libevdev_has_event_code(device->evdev,
794                                             EV_KEY,
795                                             m->code)) {
796                         n_btn_tool_touches = m->ntouches;
797                         break;
798                 }
799         }
800
801         tp->ntouches = max(tp->real_touches, n_btn_tool_touches);
802         tp->touches = calloc(tp->ntouches, sizeof(struct tp_touch));
803         if (!tp->touches)
804                 return -1;
805
806         for (i = 0; i < tp->ntouches; i++)
807                 tp_init_touch(tp, &tp->touches[i]);
808
809         return 0;
810 }
811
812 static int
813 tp_init_accel(struct tp_dispatch *tp, double diagonal)
814 {
815         int res_x, res_y;
816
817         if (tp->has_mt) {
818                 res_x = libevdev_get_abs_resolution(tp->device->evdev,
819                                                     ABS_MT_POSITION_X);
820                 res_y = libevdev_get_abs_resolution(tp->device->evdev,
821                                                     ABS_MT_POSITION_Y);
822         } else {
823                 res_x = libevdev_get_abs_resolution(tp->device->evdev,
824                                                     ABS_X);
825                 res_y = libevdev_get_abs_resolution(tp->device->evdev,
826                                                     ABS_Y);
827         }
828
829         /*
830          * Not all touchpads report the same amount of units/mm (resolution).
831          * Normalize motion events to a resolution of 15.74 units/mm
832          * (== 400 dpi) as base (unaccelerated) speed. This also evens out any
833          * differences in x and y resolution, so that a circle on the
834          * touchpad does not turn into an elipse on the screen.
835          *
836          * We pick 400dpi as thats one of the many default resolutions
837          * for USB mice, so we end up with a similar base speed on the device.
838          */
839         if (res_x > 1 && res_y > 1) {
840                 tp->accel.x_scale_coeff = (400/25.4) / res_x;
841                 tp->accel.y_scale_coeff = (400/25.4) / res_y;
842         } else {
843         /*
844          * For touchpads where the driver does not provide resolution, fall
845          * back to scaling motion events based on the diagonal size in units.
846          */
847                 tp->accel.x_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
848                 tp->accel.y_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
849         }
850
851         if (evdev_device_init_pointer_acceleration(tp->device) == -1)
852                 return -1;
853
854         return 0;
855 }
856
857 static int
858 tp_scroll_config_natural_has(struct libinput_device *device)
859 {
860         return 1;
861 }
862
863 static enum libinput_config_status
864 tp_scroll_config_natural_set(struct libinput_device *device,
865                              int enabled)
866 {
867         struct evdev_dispatch *dispatch;
868         struct tp_dispatch *tp = NULL;
869
870         dispatch = ((struct evdev_device *) device)->dispatch;
871         tp = container_of(dispatch, tp, base);
872
873         tp->scroll.natural_scrolling_enabled = enabled ? true : false;
874
875         return LIBINPUT_CONFIG_STATUS_SUCCESS;
876 }
877
878 static int
879 tp_scroll_config_natural_get(struct libinput_device *device)
880 {
881         struct evdev_dispatch *dispatch;
882         struct tp_dispatch *tp = NULL;
883
884         dispatch = ((struct evdev_device *) device)->dispatch;
885         tp = container_of(dispatch, tp, base);
886
887         return tp->scroll.natural_scrolling_enabled ? 1 : 0;
888 }
889
890 static int
891 tp_scroll_config_natural_get_default(struct libinput_device *device)
892 {
893         /* could enable this on Apple touchpads. could do that, could
894          * very well do that... */
895         return 0;
896 }
897
898 static int
899 tp_init_scroll(struct tp_dispatch *tp)
900 {
901
902         tp->scroll.config.has = tp_scroll_config_natural_has;
903         tp->scroll.config.set_enabled = tp_scroll_config_natural_set;
904         tp->scroll.config.get_enabled = tp_scroll_config_natural_get;
905         tp->scroll.config.get_default_enabled = tp_scroll_config_natural_get_default;
906         tp->scroll.natural_scrolling_enabled = false;
907         tp->device->base.config.natural_scroll = &tp->scroll.config;
908
909         return 0;
910 }
911
912 static int
913 tp_init_palmdetect(struct tp_dispatch *tp,
914                    struct evdev_device *device)
915 {
916         int width;
917
918         tp->palm.right_edge = INT_MAX;
919         tp->palm.left_edge = INT_MIN;
920
921         width = abs(device->abs.absinfo_x->maximum -
922                     device->abs.absinfo_x->minimum);
923
924         /* Apple touchpads are always big enough to warrant palm detection */
925         if (evdev_device_get_id_vendor(device) != VENDOR_ID_APPLE) {
926                 /* We don't know how big the touchpad is */
927                 if (device->abs.absinfo_x->resolution == 1)
928                         return 0;
929
930                 /* Enable palm detection on touchpads >= 80 mm. Anything smaller
931                    probably won't need it, until we find out it does */
932                 if (width/device->abs.absinfo_x->resolution < 80)
933                         return 0;
934         }
935
936         /* palm edges are 5% of the width on each side */
937         tp->palm.right_edge = device->abs.absinfo_x->maximum - width * 0.05;
938         tp->palm.left_edge = device->abs.absinfo_x->minimum + width * 0.05;
939
940         return 0;
941 }
942
943 static int
944 tp_init(struct tp_dispatch *tp,
945         struct evdev_device *device)
946 {
947         int width, height;
948         double diagonal;
949
950         tp->base.interface = &tp_interface;
951         tp->device = device;
952
953         if (tp_init_slots(tp, device) != 0)
954                 return -1;
955
956         width = abs(device->abs.absinfo_x->maximum -
957                     device->abs.absinfo_x->minimum);
958         height = abs(device->abs.absinfo_y->maximum -
959                      device->abs.absinfo_y->minimum);
960         diagonal = sqrt(width*width + height*height);
961
962         tp->hysteresis.margin_x =
963                 diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
964         tp->hysteresis.margin_y =
965                 diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
966
967         if (tp_init_scroll(tp) != 0)
968                 return -1;
969
970         if (tp_init_accel(tp, diagonal) != 0)
971                 return -1;
972
973         if (tp_init_tap(tp) != 0)
974                 return -1;
975
976         if (tp_init_buttons(tp, device) != 0)
977                 return -1;
978
979         if (tp_init_palmdetect(tp, device) != 0)
980                 return -1;
981
982         device->seat_caps |= EVDEV_DEVICE_POINTER;
983
984         return 0;
985 }
986
987 static uint32_t
988 tp_sendevents_get_modes(struct libinput_device *device)
989 {
990         struct evdev_device *evdev = (struct evdev_device*)device;
991         uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
992                          LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
993
994         if (evdev->tags & EVDEV_TAG_INTERNAL_TOUCHPAD)
995                 modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
996
997         return modes;
998 }
999
1000 static void
1001 tp_suspend_conditional(struct tp_dispatch *tp,
1002                        struct evdev_device *device)
1003 {
1004         struct libinput_device *dev;
1005
1006         list_for_each(dev, &device->base.seat->devices_list, link) {
1007                 struct evdev_device *d = (struct evdev_device*)dev;
1008                 if (d->tags & EVDEV_TAG_EXTERNAL_MOUSE) {
1009                         tp_suspend(tp, device);
1010                         return;
1011                 }
1012         }
1013 }
1014
1015 static enum libinput_config_status
1016 tp_sendevents_set_mode(struct libinput_device *device,
1017                        enum libinput_config_send_events_mode mode)
1018 {
1019         struct evdev_device *evdev = (struct evdev_device*)device;
1020         struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
1021
1022         if (mode == tp->sendevents.current_mode)
1023                 return LIBINPUT_CONFIG_STATUS_SUCCESS;
1024
1025         switch(mode) {
1026         case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
1027                 tp_resume(tp, evdev);
1028                 break;
1029         case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
1030                 tp_suspend(tp, evdev);
1031                 break;
1032         case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
1033                 tp_suspend_conditional(tp, evdev);
1034                 break;
1035         default:
1036                 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
1037         }
1038
1039         tp->sendevents.current_mode = mode;
1040
1041         return LIBINPUT_CONFIG_STATUS_SUCCESS;
1042 }
1043
1044 static enum libinput_config_send_events_mode
1045 tp_sendevents_get_mode(struct libinput_device *device)
1046 {
1047         struct evdev_device *evdev = (struct evdev_device*)device;
1048         struct tp_dispatch *dispatch = (struct tp_dispatch*)evdev->dispatch;
1049
1050         return dispatch->sendevents.current_mode;
1051 }
1052
1053 static enum libinput_config_send_events_mode
1054 tp_sendevents_get_default_mode(struct libinput_device *device)
1055 {
1056         return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
1057 }
1058
1059 struct evdev_dispatch *
1060 evdev_mt_touchpad_create(struct evdev_device *device)
1061 {
1062         struct tp_dispatch *tp;
1063
1064         tp = zalloc(sizeof *tp);
1065         if (!tp)
1066                 return NULL;
1067
1068         if (tp_init(tp, device) != 0) {
1069                 tp_destroy(&tp->base);
1070                 return NULL;
1071         }
1072
1073         device->base.config.sendevents = &tp->sendevents.config;
1074
1075         tp->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
1076         tp->sendevents.config.get_modes = tp_sendevents_get_modes;
1077         tp->sendevents.config.set_mode = tp_sendevents_set_mode;
1078         tp->sendevents.config.get_mode = tp_sendevents_get_mode;
1079         tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode;
1080
1081         return  &tp->base;
1082 }