1 /*
2 * Copyright © 2014-2015 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "config.h"
25
26 #include <assert.h>
27 #include <math.h>
28 #include <stdbool.h>
29 #include <limits.h>
30
31 #include "quirks.h"
32 #include "evdev-mt-touchpad.h"
33
34 #define DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT ms2us(300)
35 #define DEFAULT_TRACKPOINT_EVENT_TIMEOUT ms2us(40)
36 #define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1 ms2us(200)
37 #define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2 ms2us(500)
38 #define THUMB_MOVE_TIMEOUT ms2us(300)
39 #define FAKE_FINGER_OVERFLOW (1 << 7)
40 #define THUMB_IGNORE_SPEED_THRESHOLD 20 /* mm/s */
41
42 static inline struct tp_history_point*
tp_motion_history_offset(struct tp_touch * t,int offset)43 tp_motion_history_offset(struct tp_touch *t, int offset)
44 {
45 int offset_index =
46 (t->history.index - offset + TOUCHPAD_HISTORY_LENGTH) %
47 TOUCHPAD_HISTORY_LENGTH;
48
49 return &t->history.samples[offset_index];
50 }
51
52 struct normalized_coords
tp_filter_motion(struct tp_dispatch * tp,const struct device_float_coords * unaccelerated,uint64_t time)53 tp_filter_motion(struct tp_dispatch *tp,
54 const struct device_float_coords *unaccelerated,
55 uint64_t time)
56 {
57 struct device_float_coords raw;
58 const struct normalized_coords zero = { 0.0, 0.0 };
59
60 if (device_float_is_zero(*unaccelerated))
61 return zero;
62
63 /* Convert to device units with x/y in the same resolution */
64 raw = tp_scale_to_xaxis(tp, *unaccelerated);
65
66 return filter_dispatch(tp->device->pointer.filter,
67 &raw, tp, time);
68 }
69
70 struct normalized_coords
tp_filter_motion_unaccelerated(struct tp_dispatch * tp,const struct device_float_coords * unaccelerated,uint64_t time)71 tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
72 const struct device_float_coords *unaccelerated,
73 uint64_t time)
74 {
75 struct device_float_coords raw;
76 const struct normalized_coords zero = { 0.0, 0.0 };
77
78 if (device_float_is_zero(*unaccelerated))
79 return zero;
80
81 /* Convert to device units with x/y in the same resolution */
82 raw = tp_scale_to_xaxis(tp, *unaccelerated);
83
84 return filter_dispatch_constant(tp->device->pointer.filter,
85 &raw, tp, time);
86 }
87
88 static inline void
tp_calculate_motion_speed(struct tp_dispatch * tp,struct tp_touch * t)89 tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t)
90 {
91 const struct tp_history_point *last;
92 struct device_coords delta;
93 struct phys_coords mm;
94 double distance;
95 double speed;
96
97 /* Don't do this on single-touch or semi-mt devices */
98 if (!tp->has_mt || tp->semi_mt)
99 return;
100
101 if (t->state != TOUCH_UPDATE)
102 return;
103
104 /* This doesn't kick in until we have at least 4 events in the
105 * motion history. As a side-effect, this automatically handles the
106 * 2fg scroll where a finger is down and moving fast before the
107 * other finger comes down for the scroll.
108 *
109 * We do *not* reset the speed to 0 here though. The motion history
110 * is reset whenever a new finger is down, so we'd be resetting the
111 * speed and failing.
112 */
113 if (t->history.count < 4)
114 return;
115
116 /* TODO: we probably need a speed history here so we can average
117 * across a few events */
118 last = tp_motion_history_offset(t, 1);
119 delta.x = abs(t->point.x - last->point.x);
120 delta.y = abs(t->point.y - last->point.y);
121 mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
122
123 distance = length_in_mm(mm);
124 speed = distance/(t->time - last->time); /* mm/us */
125 speed *= 1000000; /* mm/s */
126
127 t->speed.last_speed = speed;
128 }
129
130 static inline void
tp_motion_history_push(struct tp_touch * t)131 tp_motion_history_push(struct tp_touch *t)
132 {
133 int motion_index = (t->history.index + 1) % TOUCHPAD_HISTORY_LENGTH;
134
135 if (t->history.count < TOUCHPAD_HISTORY_LENGTH)
136 t->history.count++;
137
138 t->history.samples[motion_index].point = t->point;
139 t->history.samples[motion_index].time = t->time;
140 t->history.index = motion_index;
141 }
142
143 /* Idea: if we got a tuple of *very* quick moves like {Left, Right,
144 * Left}, or {Right, Left, Right}, it means touchpad jitters since no
145 * human can move like that within thresholds.
146 *
147 * We encode left moves as zeroes, and right as ones. We also drop
148 * the array to all zeroes when contraints are not satisfied. Then we
149 * search for the pattern {1,0,1}. It can't match {Left, Right, Left},
150 * but it does match {Left, Right, Left, Right}, so it's okay.
151 *
152 * This only looks at x changes, y changes are ignored.
153 */
154 static inline void
tp_detect_wobbling(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)155 tp_detect_wobbling(struct tp_dispatch *tp,
156 struct tp_touch *t,
157 uint64_t time)
158 {
159 int dx, dy;
160 uint64_t dtime;
161 const struct device_coords* prev_point;
162
163 if (tp->nfingers_down != 1 ||
164 tp->nfingers_down != tp->old_nfingers_down)
165 return;
166
167 if (tp->hysteresis.enabled || t->history.count == 0)
168 return;
169
170 if (!(tp->queued & TOUCHPAD_EVENT_MOTION)) {
171 t->hysteresis.x_motion_history = 0;
172 return;
173 }
174
175 prev_point = &tp_motion_history_offset(t, 0)->point;
176 dx = prev_point->x - t->point.x;
177 dy = prev_point->y - t->point.y;
178 dtime = time - tp->hysteresis.last_motion_time;
179
180 tp->hysteresis.last_motion_time = time;
181
182 if ((dx == 0 && dy != 0) || dtime > ms2us(40)) {
183 t->hysteresis.x_motion_history = 0;
184 return;
185 }
186
187 t->hysteresis.x_motion_history >>= 1;
188 if (dx > 0) { /* right move */
189 static const char r_l_r = 0x5; /* {Right, Left, Right} */
190
191 t->hysteresis.x_motion_history |= (1 << 2);
192 if (t->hysteresis.x_motion_history == r_l_r) {
193 tp->hysteresis.enabled = true;
194 evdev_log_debug(tp->device,
195 "hysteresis enabled. "
196 "See %stouchpad-jitter.html for details\n",
197 HTTP_DOC_LINK);
198 }
199 }
200 }
201
202 static inline void
tp_motion_hysteresis(struct tp_dispatch * tp,struct tp_touch * t)203 tp_motion_hysteresis(struct tp_dispatch *tp,
204 struct tp_touch *t)
205 {
206 if (!tp->hysteresis.enabled)
207 return;
208
209 if (t->history.count > 0)
210 t->point = evdev_hysteresis(&t->point,
211 &t->hysteresis.center,
212 &tp->hysteresis.margin);
213
214 t->hysteresis.center = t->point;
215 }
216
217 static inline void
tp_motion_history_reset(struct tp_touch * t)218 tp_motion_history_reset(struct tp_touch *t)
219 {
220 t->history.count = 0;
221 }
222
223 static inline struct tp_touch *
tp_current_touch(struct tp_dispatch * tp)224 tp_current_touch(struct tp_dispatch *tp)
225 {
226 return &tp->touches[min(tp->slot, tp->ntouches - 1)];
227 }
228
229 static inline struct tp_touch *
tp_get_touch(struct tp_dispatch * tp,unsigned int slot)230 tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
231 {
232 assert(slot < tp->ntouches);
233 return &tp->touches[slot];
234 }
235
236 static inline unsigned int
tp_fake_finger_count(struct tp_dispatch * tp)237 tp_fake_finger_count(struct tp_dispatch *tp)
238 {
239 /* Only one of BTN_TOOL_DOUBLETAP/TRIPLETAP/... may be set at any
240 * time */
241 if (__builtin_popcount(
242 tp->fake_touches & ~(FAKE_FINGER_OVERFLOW|0x1)) > 1)
243 evdev_log_bug_kernel(tp->device,
244 "Invalid fake finger state %#x\n",
245 tp->fake_touches);
246
247 if (tp->fake_touches & FAKE_FINGER_OVERFLOW)
248 return FAKE_FINGER_OVERFLOW;
249 else /* don't count BTN_TOUCH */
250 return ffs(tp->fake_touches >> 1);
251 }
252
253 static inline bool
tp_fake_finger_is_touching(struct tp_dispatch * tp)254 tp_fake_finger_is_touching(struct tp_dispatch *tp)
255 {
256 return tp->fake_touches & 0x1;
257 }
258
259 static inline void
tp_fake_finger_set(struct tp_dispatch * tp,unsigned int code,bool is_press)260 tp_fake_finger_set(struct tp_dispatch *tp,
261 unsigned int code,
262 bool is_press)
263 {
264 unsigned int shift;
265
266 switch (code) {
267 case BTN_TOUCH:
268 if (!is_press)
269 tp->fake_touches &= ~FAKE_FINGER_OVERFLOW;
270 shift = 0;
271 break;
272 case BTN_TOOL_FINGER:
273 shift = 1;
274 break;
275 case BTN_TOOL_DOUBLETAP:
276 case BTN_TOOL_TRIPLETAP:
277 case BTN_TOOL_QUADTAP:
278 shift = code - BTN_TOOL_DOUBLETAP + 2;
279 break;
280 /* when QUINTTAP is released we're either switching to 6 fingers
281 (flag stays in place until BTN_TOUCH is released) or
282 one of DOUBLE/TRIPLE/QUADTAP (will clear the flag on press) */
283 case BTN_TOOL_QUINTTAP:
284 if (is_press)
285 tp->fake_touches |= FAKE_FINGER_OVERFLOW;
286 return;
287 default:
288 return;
289 }
290
291 if (is_press) {
292 tp->fake_touches &= ~FAKE_FINGER_OVERFLOW;
293 tp->fake_touches |= 1 << shift;
294
295 } else {
296 tp->fake_touches &= ~(0x1 << shift);
297 }
298 }
299
300 static inline void
tp_new_touch(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)301 tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
302 {
303 if (t->state == TOUCH_BEGIN ||
304 t->state == TOUCH_UPDATE ||
305 t->state == TOUCH_HOVERING)
306 return;
307
308 /* Bug #161: touch ends in the same event frame where it restarts
309 again. That's a kernel bug, so let's complain. */
310 if (t->state == TOUCH_MAYBE_END) {
311 evdev_log_bug_kernel(tp->device,
312 "touch %d ended and began in in same frame.\n",
313 t->index);
314 tp->nfingers_down++;
315 t->state = TOUCH_UPDATE;
316 t->has_ended = false;
317 return;
318 }
319
320 /* we begin the touch as hovering because until BTN_TOUCH happens we
321 * don't know if it's a touch down or not. And BTN_TOUCH may happen
322 * after ABS_MT_TRACKING_ID */
323 tp_motion_history_reset(t);
324 t->dirty = true;
325 t->has_ended = false;
326 t->was_down = false;
327 t->palm.state = PALM_NONE;
328 t->state = TOUCH_HOVERING;
329 t->pinned.is_pinned = false;
330 t->time = time;
331 t->speed.last_speed = 0;
332 t->speed.exceeded_count = 0;
333 t->hysteresis.x_motion_history = 0;
334 tp->queued |= TOUCHPAD_EVENT_MOTION;
335 }
336
337 static inline void
tp_begin_touch(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)338 tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
339 {
340 t->dirty = true;
341 t->state = TOUCH_BEGIN;
342 t->time = time;
343 t->was_down = true;
344 tp->nfingers_down++;
345 t->palm.time = time;
346 t->thumb.state = THUMB_STATE_MAYBE;
347 t->thumb.first_touch_time = time;
348 t->tap.is_thumb = false;
349 t->tap.is_palm = false;
350 t->speed.exceeded_count = 0;
351 assert(tp->nfingers_down >= 1);
352 tp->hysteresis.last_motion_time = time;
353 }
354
355 /**
356 * Schedule a touch to be ended, based on either the events or some
357 * attributes of the touch (size, pressure). In some cases we need to
358 * resurrect a touch that has ended, so this doesn't actually end the touch
359 * yet. All the TOUCH_MAYBE_END touches get properly ended once the device
360 * state has been processed once and we know how many zombie touches we
361 * need.
362 */
363 static inline void
tp_maybe_end_touch(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)364 tp_maybe_end_touch(struct tp_dispatch *tp,
365 struct tp_touch *t,
366 uint64_t time)
367 {
368 switch (t->state) {
369 case TOUCH_NONE:
370 case TOUCH_MAYBE_END:
371 return;
372 case TOUCH_END:
373 evdev_log_bug_libinput(tp->device,
374 "touch %d: already in TOUCH_END\n",
375 t->index);
376 return;
377 case TOUCH_HOVERING:
378 case TOUCH_BEGIN:
379 case TOUCH_UPDATE:
380 break;
381 }
382
383 if (t->state != TOUCH_HOVERING) {
384 assert(tp->nfingers_down >= 1);
385 tp->nfingers_down--;
386 t->state = TOUCH_MAYBE_END;
387 } else {
388 t->state = TOUCH_NONE;
389 }
390
391 t->dirty = true;
392 }
393
394 /**
395 * Inverse to tp_maybe_end_touch(), restores a touch back to its previous
396 * state.
397 */
398 static inline void
tp_recover_ended_touch(struct tp_dispatch * tp,struct tp_touch * t)399 tp_recover_ended_touch(struct tp_dispatch *tp,
400 struct tp_touch *t)
401 {
402 t->dirty = true;
403 t->state = TOUCH_UPDATE;
404 tp->nfingers_down++;
405 }
406
407 /**
408 * End a touch, even if the touch sequence is still active.
409 * Use tp_maybe_end_touch() instead.
410 */
411 static inline void
tp_end_touch(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)412 tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
413 {
414 if (t->state != TOUCH_MAYBE_END) {
415 evdev_log_bug_libinput(tp->device,
416 "touch %d should be MAYBE_END, is %d\n",
417 t->index,
418 t->state);
419 return;
420 }
421
422 t->dirty = true;
423 t->palm.state = PALM_NONE;
424 t->state = TOUCH_END;
425 t->pinned.is_pinned = false;
426 t->time = time;
427 t->palm.time = 0;
428 t->speed.exceeded_count = 0;
429 tp->queued |= TOUCHPAD_EVENT_MOTION;
430 }
431
432 /**
433 * End the touch sequence on ABS_MT_TRACKING_ID -1 or when the BTN_TOOL_* 0 is received.
434 */
435 static inline void
tp_end_sequence(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)436 tp_end_sequence(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
437 {
438 t->has_ended = true;
439 tp_maybe_end_touch(tp, t, time);
440 }
441
442 static void
tp_stop_actions(struct tp_dispatch * tp,uint64_t time)443 tp_stop_actions(struct tp_dispatch *tp, uint64_t time)
444 {
445 tp_edge_scroll_stop_events(tp, time);
446 tp_gesture_cancel(tp, time);
447 tp_tap_suspend(tp, time);
448 }
449
450 struct device_coords
tp_get_delta(struct tp_touch * t)451 tp_get_delta(struct tp_touch *t)
452 {
453 struct device_coords delta;
454 const struct device_coords zero = { 0.0, 0.0 };
455
456 if (t->history.count <= 1)
457 return zero;
458
459 delta.x = tp_motion_history_offset(t, 0)->point.x -
460 tp_motion_history_offset(t, 1)->point.x;
461 delta.y = tp_motion_history_offset(t, 0)->point.y -
462 tp_motion_history_offset(t, 1)->point.y;
463
464 return delta;
465 }
466
467 static void
tp_process_absolute(struct tp_dispatch * tp,const struct input_event * e,uint64_t time)468 tp_process_absolute(struct tp_dispatch *tp,
469 const struct input_event *e,
470 uint64_t time)
471 {
472 struct tp_touch *t = tp_current_touch(tp);
473
474 switch(e->code) {
475 case ABS_MT_POSITION_X:
476 evdev_device_check_abs_axis_range(tp->device,
477 e->code,
478 e->value);
479 t->point.x = e->value;
480 t->time = time;
481 t->dirty = true;
482 tp->queued |= TOUCHPAD_EVENT_MOTION;
483 break;
484 case ABS_MT_POSITION_Y:
485 evdev_device_check_abs_axis_range(tp->device,
486 e->code,
487 e->value);
488 t->point.y = e->value;
489 t->time = time;
490 t->dirty = true;
491 tp->queued |= TOUCHPAD_EVENT_MOTION;
492 break;
493 case ABS_MT_SLOT:
494 tp->slot = e->value;
495 break;
496 case ABS_MT_TRACKING_ID:
497 if (e->value != -1)
498 tp_new_touch(tp, t, time);
499 else
500 tp_end_sequence(tp, t, time);
501 break;
502 case ABS_MT_PRESSURE:
503 t->pressure = e->value;
504 t->time = time;
505 t->dirty = true;
506 tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
507 break;
508 case ABS_MT_TOOL_TYPE:
509 t->is_tool_palm = e->value == MT_TOOL_PALM;
510 t->time = time;
511 t->dirty = true;
512 tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
513 break;
514 case ABS_MT_TOUCH_MAJOR:
515 t->major = e->value;
516 t->dirty = true;
517 tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
518 break;
519 case ABS_MT_TOUCH_MINOR:
520 t->minor = e->value;
521 t->dirty = true;
522 tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
523 break;
524 }
525 }
526
527 static void
tp_process_absolute_st(struct tp_dispatch * tp,const struct input_event * e,uint64_t time)528 tp_process_absolute_st(struct tp_dispatch *tp,
529 const struct input_event *e,
530 uint64_t time)
531 {
532 struct tp_touch *t = tp_current_touch(tp);
533
534 switch(e->code) {
535 case ABS_X:
536 evdev_device_check_abs_axis_range(tp->device,
537 e->code,
538 e->value);
539 t->point.x = e->value;
540 t->time = time;
541 t->dirty = true;
542 tp->queued |= TOUCHPAD_EVENT_MOTION;
543 break;
544 case ABS_Y:
545 evdev_device_check_abs_axis_range(tp->device,
546 e->code,
547 e->value);
548 t->point.y = e->value;
549 t->time = time;
550 t->dirty = true;
551 tp->queued |= TOUCHPAD_EVENT_MOTION;
552 break;
553 case ABS_PRESSURE:
554 t->pressure = e->value;
555 t->time = time;
556 t->dirty = true;
557 tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
558 break;
559 }
560 }
561
562 static inline void
tp_restore_synaptics_touches(struct tp_dispatch * tp,uint64_t time)563 tp_restore_synaptics_touches(struct tp_dispatch *tp,
564 uint64_t time)
565 {
566 unsigned int i;
567 unsigned int nfake_touches;
568
569 nfake_touches = tp_fake_finger_count(tp);
570 if (nfake_touches < 3)
571 return;
572
573 if (tp->nfingers_down >= nfake_touches ||
574 (tp->nfingers_down == tp->num_slots && nfake_touches == tp->num_slots))
575 return;
576
577 /* Synaptics devices may end touch 2 on BTN_TOOL_TRIPLETAP
578 * and start it again on the next frame with different coordinates
579 * (#91352). We search the touches we have, if there is one that has
580 * just ended despite us being on tripletap, we move it back to
581 * update.
582 */
583 for (i = 0; i < tp->num_slots; i++) {
584 struct tp_touch *t = tp_get_touch(tp, i);
585
586 if (t->state != TOUCH_MAYBE_END)
587 continue;
588
589 /* new touch, move it through begin to update immediately */
590 tp_recover_ended_touch(tp, t);
591 }
592 }
593
594 static void
tp_process_fake_touches(struct tp_dispatch * tp,uint64_t time)595 tp_process_fake_touches(struct tp_dispatch *tp,
596 uint64_t time)
597 {
598 struct tp_touch *t;
599 unsigned int nfake_touches;
600 unsigned int i, start;
601
602 nfake_touches = tp_fake_finger_count(tp);
603 if (nfake_touches == FAKE_FINGER_OVERFLOW)
604 return;
605
606 if (tp->device->model_flags &
607 EVDEV_MODEL_SYNAPTICS_SERIAL_TOUCHPAD)
608 tp_restore_synaptics_touches(tp, time);
609
610 start = tp->has_mt ? tp->num_slots : 0;
611 for (i = start; i < tp->ntouches; i++) {
612 t = tp_get_touch(tp, i);
613 if (i < nfake_touches)
614 tp_new_touch(tp, t, time);
615 else
616 tp_end_sequence(tp, t, time);
617 }
618 }
619
620 static void
tp_process_trackpoint_button(struct tp_dispatch * tp,const struct input_event * e,uint64_t time)621 tp_process_trackpoint_button(struct tp_dispatch *tp,
622 const struct input_event *e,
623 uint64_t time)
624 {
625 struct evdev_dispatch *dispatch;
626 struct input_event event;
627 struct input_event syn_report = {
628 .input_event_sec = 0,
629 .input_event_usec = 0,
630 .type = EV_SYN,
631 .code = SYN_REPORT,
632 .value = 0
633 };
634
635 if (!tp->buttons.trackpoint)
636 return;
637
638 dispatch = tp->buttons.trackpoint->dispatch;
639
640 event = *e;
641 syn_report.input_event_sec = e->input_event_sec;
642 syn_report.input_event_usec = e->input_event_usec;
643
644 switch (event.code) {
645 case BTN_0:
646 event.code = BTN_LEFT;
647 break;
648 case BTN_1:
649 event.code = BTN_RIGHT;
650 break;
651 case BTN_2:
652 event.code = BTN_MIDDLE;
653 break;
654 default:
655 return;
656 }
657
658 dispatch->interface->process(dispatch,
659 tp->buttons.trackpoint,
660 &event, time);
661 dispatch->interface->process(dispatch,
662 tp->buttons.trackpoint,
663 &syn_report, time);
664 }
665
666 static void
tp_process_key(struct tp_dispatch * tp,const struct input_event * e,uint64_t time)667 tp_process_key(struct tp_dispatch *tp,
668 const struct input_event *e,
669 uint64_t time)
670 {
671 switch (e->code) {
672 case BTN_LEFT:
673 case BTN_MIDDLE:
674 case BTN_RIGHT:
675 tp_process_button(tp, e, time);
676 break;
677 case BTN_TOUCH:
678 case BTN_TOOL_FINGER:
679 case BTN_TOOL_DOUBLETAP:
680 case BTN_TOOL_TRIPLETAP:
681 case BTN_TOOL_QUADTAP:
682 case BTN_TOOL_QUINTTAP:
683 tp_fake_finger_set(tp, e->code, !!e->value);
684 break;
685 case BTN_0:
686 case BTN_1:
687 case BTN_2:
688 tp_process_trackpoint_button(tp, e, time);
689 break;
690 }
691 }
692
693 static void
tp_process_msc(struct tp_dispatch * tp,const struct input_event * e,uint64_t time)694 tp_process_msc(struct tp_dispatch *tp,
695 const struct input_event *e,
696 uint64_t time)
697 {
698 if (e->code != MSC_TIMESTAMP)
699 return;
700
701 tp->quirks.msc_timestamp.now = e->value;
702 tp->queued |= TOUCHPAD_EVENT_TIMESTAMP;
703 }
704
705 static void
tp_unpin_finger(const struct tp_dispatch * tp,struct tp_touch * t)706 tp_unpin_finger(const struct tp_dispatch *tp, struct tp_touch *t)
707 {
708 struct phys_coords mm;
709 struct device_coords delta;
710
711 if (!t->pinned.is_pinned)
712 return;
713
714 delta.x = abs(t->point.x - t->pinned.center.x);
715 delta.y = abs(t->point.y - t->pinned.center.y);
716
717 mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
718
719 /* 1.5mm movement -> unpin */
720 if (hypot(mm.x, mm.y) >= 1.5) {
721 t->pinned.is_pinned = false;
722 return;
723 }
724 }
725
726 static void
tp_pin_fingers(struct tp_dispatch * tp)727 tp_pin_fingers(struct tp_dispatch *tp)
728 {
729 struct tp_touch *t;
730
731 tp_for_each_touch(tp, t) {
732 t->pinned.is_pinned = true;
733 t->pinned.center = t->point;
734 }
735 }
736
737 bool
tp_touch_active(const struct tp_dispatch * tp,const struct tp_touch * t)738 tp_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t)
739 {
740 return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) &&
741 t->palm.state == PALM_NONE &&
742 !t->pinned.is_pinned &&
743 t->thumb.state != THUMB_STATE_YES &&
744 tp_button_touch_active(tp, t) &&
745 tp_edge_scroll_touch_active(tp, t);
746 }
747
748 static inline bool
tp_palm_was_in_side_edge(const struct tp_dispatch * tp,const struct tp_touch * t)749 tp_palm_was_in_side_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
750 {
751 return t->palm.first.x < tp->palm.left_edge ||
752 t->palm.first.x > tp->palm.right_edge;
753 }
754
755 static inline bool
tp_palm_was_in_top_edge(const struct tp_dispatch * tp,const struct tp_touch * t)756 tp_palm_was_in_top_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
757 {
758 return t->palm.first.y < tp->palm.upper_edge;
759 }
760
761 static inline bool
tp_palm_in_side_edge(const struct tp_dispatch * tp,const struct tp_touch * t)762 tp_palm_in_side_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
763 {
764 return t->point.x < tp->palm.left_edge ||
765 t->point.x > tp->palm.right_edge;
766 }
767
768 static inline bool
tp_palm_in_top_edge(const struct tp_dispatch * tp,const struct tp_touch * t)769 tp_palm_in_top_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
770 {
771 return t->point.y < tp->palm.upper_edge;
772 }
773
774 static inline bool
tp_palm_in_edge(const struct tp_dispatch * tp,const struct tp_touch * t)775 tp_palm_in_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
776 {
777 return tp_palm_in_side_edge(tp, t) || tp_palm_in_top_edge(tp, t);
778 }
779
780 bool
tp_palm_tap_is_palm(const struct tp_dispatch * tp,const struct tp_touch * t)781 tp_palm_tap_is_palm(const struct tp_dispatch *tp, const struct tp_touch *t)
782 {
783 if (t->state != TOUCH_BEGIN)
784 return false;
785
786 if (!tp_palm_in_edge(tp, t))
787 return false;
788
789 evdev_log_debug(tp->device,
790 "palm: touch %d: palm-tap detected\n",
791 t->index);
792 return true;
793 }
794
795 static bool
tp_palm_detect_dwt_triggered(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)796 tp_palm_detect_dwt_triggered(struct tp_dispatch *tp,
797 struct tp_touch *t,
798 uint64_t time)
799 {
800 if (tp->dwt.dwt_enabled &&
801 tp->dwt.keyboard_active &&
802 t->state == TOUCH_BEGIN) {
803 t->palm.state = PALM_TYPING;
804 t->palm.first = t->point;
805 return true;
806 } else if (!tp->dwt.keyboard_active &&
807 t->state == TOUCH_UPDATE &&
808 t->palm.state == PALM_TYPING) {
809 /* If a touch has started before the first or after the last
810 key press, release it on timeout. Benefit: a palm rested
811 while typing on the touchpad will be ignored, but a touch
812 started once we stop typing will be able to control the
813 pointer (alas not tap, etc.).
814 */
815 if (t->palm.time == 0 ||
816 t->palm.time > tp->dwt.keyboard_last_press_time) {
817 t->palm.state = PALM_NONE;
818 evdev_log_debug(tp->device,
819 "palm: touch %d released, timeout after typing\n",
820 t->index);
821 }
822 }
823
824 return false;
825 }
826
827 static bool
tp_palm_detect_trackpoint_triggered(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)828 tp_palm_detect_trackpoint_triggered(struct tp_dispatch *tp,
829 struct tp_touch *t,
830 uint64_t time)
831 {
832 if (!tp->palm.monitor_trackpoint)
833 return false;
834
835 if (t->palm.state == PALM_NONE &&
836 t->state == TOUCH_BEGIN &&
837 tp->palm.trackpoint_active) {
838 t->palm.state = PALM_TRACKPOINT;
839 return true;
840 } else if (t->palm.state == PALM_TRACKPOINT &&
841 t->state == TOUCH_UPDATE &&
842 !tp->palm.trackpoint_active) {
843
844 if (t->palm.time == 0 ||
845 t->palm.time > tp->palm.trackpoint_last_event_time) {
846 t->palm.state = PALM_NONE;
847 evdev_log_debug(tp->device,
848 "palm: touch %d released, timeout after trackpoint\n", t->index);
849 }
850 }
851
852 return false;
853 }
854
855 static bool
tp_palm_detect_tool_triggered(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)856 tp_palm_detect_tool_triggered(struct tp_dispatch *tp,
857 struct tp_touch *t,
858 uint64_t time)
859 {
860 if (!tp->palm.use_mt_tool)
861 return false;
862
863 if (t->palm.state != PALM_NONE &&
864 t->palm.state != PALM_TOOL_PALM)
865 return false;
866
867 if (t->palm.state == PALM_NONE &&
868 t->is_tool_palm)
869 t->palm.state = PALM_TOOL_PALM;
870 else if (t->palm.state == PALM_TOOL_PALM &&
871 !t->is_tool_palm)
872 t->palm.state = PALM_NONE;
873
874 return t->palm.state == PALM_TOOL_PALM;
875 }
876
877 static inline bool
tp_palm_detect_move_out_of_edge(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)878 tp_palm_detect_move_out_of_edge(struct tp_dispatch *tp,
879 struct tp_touch *t,
880 uint64_t time)
881 {
882 const int PALM_TIMEOUT = ms2us(200);
883 int directions = 0;
884 struct device_float_coords delta;
885 int dirs;
886
887 if (time < t->palm.time + PALM_TIMEOUT && !tp_palm_in_edge(tp, t)) {
888 if (tp_palm_was_in_side_edge(tp, t))
889 directions = NE|E|SE|SW|W|NW;
890 else if (tp_palm_was_in_top_edge(tp, t))
891 directions = S|SE|SW;
892
893 if (directions) {
894 delta = device_delta(t->point, t->palm.first);
895 dirs = phys_get_direction(tp_phys_delta(tp, delta));
896 if ((dirs & directions) && !(dirs & ~directions))
897 return true;
898 }
899 }
900
901 return false;
902 }
903
904 static inline bool
tp_palm_detect_multifinger(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)905 tp_palm_detect_multifinger(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
906 {
907 struct tp_touch *other;
908
909 if (tp->nfingers_down < 2)
910 return false;
911
912 /* If we have at least one other active non-palm touch make this
913 * touch non-palm too. This avoids palm detection during two-finger
914 * scrolling.
915 *
916 * Note: if both touches start in the palm zone within the same
917 * frame the second touch will still be PALM_NONE and thus detected
918 * here as non-palm touch. This is too niche to worry about for now.
919 */
920 tp_for_each_touch(tp, other) {
921 if (other == t)
922 continue;
923
924 if (tp_touch_active(tp, other) &&
925 other->palm.state == PALM_NONE) {
926 return true;
927 }
928 }
929
930 return false;
931 }
932
933 static inline bool
tp_palm_detect_touch_size_triggered(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)934 tp_palm_detect_touch_size_triggered(struct tp_dispatch *tp,
935 struct tp_touch *t,
936 uint64_t time)
937 {
938 if (!tp->palm.use_size)
939 return false;
940
941 /* If a finger size is large enough for palm, we stick with that and
942 * force the user to release and reset the finger */
943 if (t->palm.state != PALM_NONE && t->palm.state != PALM_TOUCH_SIZE)
944 return false;
945
946 if (t->major > tp->palm.size_threshold ||
947 t->minor > tp->palm.size_threshold) {
948 if (t->palm.state != PALM_TOUCH_SIZE)
949 evdev_log_debug(tp->device,
950 "palm: touch %d size exceeded\n",
951 t->index);
952 t->palm.state = PALM_TOUCH_SIZE;
953 return true;
954 }
955
956 return false;
957 }
958
959 static inline bool
tp_palm_detect_edge(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)960 tp_palm_detect_edge(struct tp_dispatch *tp,
961 struct tp_touch *t,
962 uint64_t time)
963 {
964 if (t->palm.state == PALM_EDGE) {
965 if (tp_palm_detect_multifinger(tp, t, time)) {
966 t->palm.state = PALM_NONE;
967 evdev_log_debug(tp->device,
968 "palm: touch %d released, multiple fingers\n",
969 t->index);
970
971 /* If labelled a touch as palm, we unlabel as palm when
972 we move out of the palm edge zone within the timeout, provided
973 the direction is within 45 degrees of the horizontal.
974 */
975 } else if (tp_palm_detect_move_out_of_edge(tp, t, time)) {
976 t->palm.state = PALM_NONE;
977 evdev_log_debug(tp->device,
978 "palm: touch %d released, out of edge zone\n",
979 t->index);
980 }
981 return false;
982 } else if (tp_palm_detect_multifinger(tp, t, time)) {
983 return false;
984 }
985
986 /* palm must start in exclusion zone, it's ok to move into
987 the zone without being a palm */
988 if (t->state != TOUCH_BEGIN || !tp_palm_in_edge(tp, t))
989 return false;
990
991 /* don't detect palm in software button areas, it's
992 likely that legitimate touches start in the area
993 covered by the exclusion zone */
994 if (tp->buttons.is_clickpad &&
995 tp_button_is_inside_softbutton_area(tp, t))
996 return false;
997
998 if (tp_touch_get_edge(tp, t) & EDGE_RIGHT)
999 return false;
1000
1001 t->palm.state = PALM_EDGE;
1002 t->palm.time = time;
1003 t->palm.first = t->point;
1004
1005 return true;
1006 }
1007
1008 static bool
tp_palm_detect_pressure_triggered(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)1009 tp_palm_detect_pressure_triggered(struct tp_dispatch *tp,
1010 struct tp_touch *t,
1011 uint64_t time)
1012 {
1013 if (!tp->palm.use_pressure)
1014 return false;
1015
1016 if (t->palm.state != PALM_NONE &&
1017 t->palm.state != PALM_PRESSURE)
1018 return false;
1019
1020 if (t->pressure > tp->palm.pressure_threshold)
1021 t->palm.state = PALM_PRESSURE;
1022
1023 return t->palm.state == PALM_PRESSURE;
1024 }
1025
1026 static bool
tp_palm_detect_arbitration_triggered(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)1027 tp_palm_detect_arbitration_triggered(struct tp_dispatch *tp,
1028 struct tp_touch *t,
1029 uint64_t time)
1030 {
1031 if (!tp->arbitration.in_arbitration)
1032 return false;
1033
1034 t->palm.state = PALM_ARBITRATION;
1035
1036 return true;
1037 }
1038
1039 static void
tp_palm_detect(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)1040 tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
1041 {
1042 const char *palm_state;
1043 enum touch_palm_state oldstate = t->palm.state;
1044
1045 if (tp_palm_detect_pressure_triggered(tp, t, time))
1046 goto out;
1047
1048 if (tp_palm_detect_arbitration_triggered(tp, t, time))
1049 goto out;
1050
1051 if (tp_palm_detect_dwt_triggered(tp, t, time))
1052 goto out;
1053
1054 if (tp_palm_detect_trackpoint_triggered(tp, t, time))
1055 goto out;
1056
1057 if (tp_palm_detect_tool_triggered(tp, t, time))
1058 goto out;
1059
1060 if (tp_palm_detect_touch_size_triggered(tp, t, time))
1061 goto out;
1062
1063 if (tp_palm_detect_edge(tp, t, time))
1064 goto out;
1065
1066 /* Pressure is highest priority because it cannot be released and
1067 * overrides all other checks. So we check once before anything else
1068 * in case pressure triggers on a non-palm touch. And again after
1069 * everything in case one of the others released but we have a
1070 * pressure trigger now.
1071 */
1072 if (tp_palm_detect_pressure_triggered(tp, t, time))
1073 goto out;
1074
1075 return;
1076 out:
1077
1078 if (oldstate == t->palm.state)
1079 return;
1080
1081 switch (t->palm.state) {
1082 case PALM_EDGE:
1083 palm_state = "edge";
1084 break;
1085 case PALM_TYPING:
1086 palm_state = "typing";
1087 break;
1088 case PALM_TRACKPOINT:
1089 palm_state = "trackpoint";
1090 break;
1091 case PALM_TOOL_PALM:
1092 palm_state = "tool-palm";
1093 break;
1094 case PALM_PRESSURE:
1095 palm_state = "pressure";
1096 break;
1097 case PALM_TOUCH_SIZE:
1098 palm_state = "touch size";
1099 break;
1100 case PALM_ARBITRATION:
1101 palm_state = "arbitration";
1102 break;
1103 case PALM_NONE:
1104 default:
1105 abort();
1106 break;
1107 }
1108 evdev_log_debug(tp->device,
1109 "palm: touch %d, palm detected (%s)\n",
1110 t->index,
1111 palm_state);
1112 }
1113
1114 static inline const char*
thumb_state_to_str(enum tp_thumb_state state)1115 thumb_state_to_str(enum tp_thumb_state state)
1116 {
1117 switch(state){
1118 CASE_RETURN_STRING(THUMB_STATE_NO);
1119 CASE_RETURN_STRING(THUMB_STATE_YES);
1120 CASE_RETURN_STRING(THUMB_STATE_MAYBE);
1121 }
1122
1123 return NULL;
1124 }
1125
1126 static void
tp_thumb_detect(struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)1127 tp_thumb_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
1128 {
1129 enum tp_thumb_state state = t->thumb.state;
1130
1131 /* once a thumb, always a thumb, once ruled out always ruled out */
1132 if (!tp->thumb.detect_thumbs ||
1133 t->thumb.state != THUMB_STATE_MAYBE)
1134 return;
1135
1136 if (t->point.y < tp->thumb.upper_thumb_line) {
1137 /* if a potential thumb is above the line, it won't ever
1138 * label as thumb */
1139 t->thumb.state = THUMB_STATE_NO;
1140 goto out;
1141 }
1142
1143 /* If the thumb moves by more than 7mm, it's not a resting thumb */
1144 if (t->state == TOUCH_BEGIN) {
1145 t->thumb.initial = t->point;
1146 } else if (t->state == TOUCH_UPDATE) {
1147 struct device_float_coords delta;
1148 struct phys_coords mm;
1149
1150 delta = device_delta(t->point, t->thumb.initial);
1151 mm = tp_phys_delta(tp, delta);
1152 if (length_in_mm(mm) > 7) {
1153 t->thumb.state = THUMB_STATE_NO;
1154 goto out;
1155 }
1156 }
1157
1158 /* If the finger is below the upper thumb line and we have another
1159 * finger in the same area, neither finger is a thumb (unless we've
1160 * already labeled it as such).
1161 */
1162 if (t->point.y > tp->thumb.upper_thumb_line &&
1163 tp->nfingers_down > 1) {
1164 struct tp_touch *other;
1165
1166 tp_for_each_touch(tp, other) {
1167 if (other->state != TOUCH_BEGIN &&
1168 other->state != TOUCH_UPDATE)
1169 continue;
1170
1171 if (other->point.y > tp->thumb.upper_thumb_line) {
1172 t->thumb.state = THUMB_STATE_NO;
1173 if (other->thumb.state == THUMB_STATE_MAYBE)
1174 other->thumb.state = THUMB_STATE_NO;
1175 break;
1176 }
1177 }
1178 }
1179
1180 /* Note: a thumb at the edge of the touchpad won't trigger the
1181 * threshold, the surface area is usually too small. So we have a
1182 * two-stage detection: pressure and time within the area.
1183 * A finger that remains at the very bottom of the touchpad becomes
1184 * a thumb.
1185 */
1186 if (tp->thumb.use_pressure &&
1187 t->pressure > tp->thumb.pressure_threshold) {
1188 t->thumb.state = THUMB_STATE_YES;
1189 } else if (tp->thumb.use_size &&
1190 (t->major > tp->thumb.size_threshold) &&
1191 (t->minor < (tp->thumb.size_threshold * 0.6))) {
1192 t->thumb.state = THUMB_STATE_YES;
1193 } else if (t->point.y > tp->thumb.lower_thumb_line &&
1194 tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE &&
1195 t->thumb.first_touch_time + THUMB_MOVE_TIMEOUT < time) {
1196 t->thumb.state = THUMB_STATE_YES;
1197 }
1198
1199 /* now what? we marked it as thumb, so:
1200 *
1201 * - pointer motion must ignore this touch
1202 * - clickfinger must ignore this touch for finger count
1203 * - software buttons are unaffected
1204 * - edge scrolling unaffected
1205 * - gestures: unaffected
1206 * - tapping: honour thumb on begin, ignore it otherwise for now,
1207 * this gets a tad complicated otherwise
1208 */
1209 out:
1210 if (t->thumb.state != state)
1211 evdev_log_debug(tp->device,
1212 "thumb state: touch %d, %s → %s\n",
1213 t->index,
1214 thumb_state_to_str(state),
1215 thumb_state_to_str(t->thumb.state));
1216 }
1217
1218 static void
tp_unhover_pressure(struct tp_dispatch * tp,uint64_t time)1219 tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
1220 {
1221 struct tp_touch *t;
1222 int i;
1223 unsigned int nfake_touches;
1224 unsigned int real_fingers_down = 0;
1225
1226 nfake_touches = tp_fake_finger_count(tp);
1227 if (nfake_touches == FAKE_FINGER_OVERFLOW)
1228 nfake_touches = 0;
1229
1230 for (i = 0; i < (int)tp->num_slots; i++) {
1231 t = tp_get_touch(tp, i);
1232
1233 if (t->state == TOUCH_NONE)
1234 continue;
1235
1236 if (t->dirty) {
1237 if (t->state == TOUCH_HOVERING) {
1238 if (t->pressure >= tp->pressure.high) {
1239 evdev_log_debug(tp->device,
1240 "pressure: begin touch %d\n",
1241 t->index);
1242 /* avoid jumps when landing a finger */
1243 tp_motion_history_reset(t);
1244 tp_begin_touch(tp, t, time);
1245 }
1246 /* don't unhover for pressure if we have too many
1247 * fake fingers down, see comment below. Except
1248 * for single-finger touches where the real touch
1249 * decides for the rest.
1250 */
1251 } else if (nfake_touches <= tp->num_slots ||
1252 tp->num_slots == 1) {
1253 if (t->pressure < tp->pressure.low) {
1254 evdev_log_debug(tp->device,
1255 "pressure: end touch %d\n",
1256 t->index);
1257 tp_maybe_end_touch(tp, t, time);
1258 }
1259 }
1260 }
1261
1262 if (t->state == TOUCH_BEGIN ||
1263 t->state == TOUCH_UPDATE)
1264 real_fingers_down++;
1265 }
1266
1267 if (nfake_touches <= tp->num_slots ||
1268 tp->nfingers_down == 0)
1269 return;
1270
1271 /* if we have more fake fingers down than slots, we assume
1272 * _all_ fingers have enough pressure, even if some of the slotted
1273 * ones don't. Anything else gets insane quickly.
1274 */
1275 if (real_fingers_down > 0) {
1276 tp_for_each_touch(tp, t) {
1277 if (t->state == TOUCH_HOVERING) {
1278 /* avoid jumps when landing a finger */
1279 tp_motion_history_reset(t);
1280 tp_begin_touch(tp, t, time);
1281
1282 if (tp->nfingers_down >= nfake_touches)
1283 break;
1284 }
1285 }
1286 }
1287
1288 if (tp->nfingers_down > nfake_touches ||
1289 real_fingers_down == 0) {
1290 for (i = tp->ntouches - 1; i >= 0; i--) {
1291 t = tp_get_touch(tp, i);
1292
1293 if (t->state == TOUCH_HOVERING ||
1294 t->state == TOUCH_NONE ||
1295 t->state == TOUCH_MAYBE_END)
1296 continue;
1297
1298 tp_maybe_end_touch(tp, t, time);
1299
1300 if (real_fingers_down > 0 &&
1301 tp->nfingers_down == nfake_touches)
1302 break;
1303 }
1304 }
1305 }
1306
1307 static void
tp_unhover_size(struct tp_dispatch * tp,uint64_t time)1308 tp_unhover_size(struct tp_dispatch *tp, uint64_t time)
1309 {
1310 struct tp_touch *t;
1311 int low = tp->touch_size.low,
1312 high = tp->touch_size.high;
1313 int i;
1314
1315 /* We require 5 slots for size handling, so we don't need to care
1316 * about fake touches here */
1317
1318 for (i = 0; i < (int)tp->num_slots; i++) {
1319 t = tp_get_touch(tp, i);
1320
1321 if (t->state == TOUCH_NONE)
1322 continue;
1323
1324 if (!t->dirty)
1325 continue;
1326
1327 if (t->state == TOUCH_HOVERING) {
1328 if ((t->major > high && t->minor > low) ||
1329 (t->major > low && t->minor > high)) {
1330 evdev_log_debug(tp->device,
1331 "touch-size: begin touch %d\n",
1332 t->index);
1333 /* avoid jumps when landing a finger */
1334 tp_motion_history_reset(t);
1335 tp_begin_touch(tp, t, time);
1336 }
1337 } else {
1338 if (t->major < low || t->minor < low) {
1339 evdev_log_debug(tp->device,
1340 "touch-size: end touch %d\n",
1341 t->index);
1342 tp_maybe_end_touch(tp, t, time);
1343 }
1344 }
1345 }
1346 }
1347
1348 static void
tp_unhover_fake_touches(struct tp_dispatch * tp,uint64_t time)1349 tp_unhover_fake_touches(struct tp_dispatch *tp, uint64_t time)
1350 {
1351 struct tp_touch *t;
1352 unsigned int nfake_touches;
1353 int i;
1354
1355 if (!tp->fake_touches && !tp->nfingers_down)
1356 return;
1357
1358 nfake_touches = tp_fake_finger_count(tp);
1359 if (nfake_touches == FAKE_FINGER_OVERFLOW)
1360 return;
1361
1362 if (tp->nfingers_down == nfake_touches &&
1363 ((tp->nfingers_down == 0 && !tp_fake_finger_is_touching(tp)) ||
1364 (tp->nfingers_down > 0 && tp_fake_finger_is_touching(tp))))
1365 return;
1366
1367 /* if BTN_TOUCH is set and we have less fingers down than fake
1368 * touches, switch each hovering touch to BEGIN
1369 * until nfingers_down matches nfake_touches
1370 */
1371 if (tp_fake_finger_is_touching(tp) &&
1372 tp->nfingers_down < nfake_touches) {
1373 tp_for_each_touch(tp, t) {
1374 if (t->state == TOUCH_HOVERING) {
1375 tp_begin_touch(tp, t, time);
1376
1377 if (tp->nfingers_down >= nfake_touches)
1378 break;
1379 }
1380 }
1381 }
1382
1383 /* if BTN_TOUCH is unset end all touches, we're hovering now. If we
1384 * have too many touches also end some of them. This is done in
1385 * reverse order.
1386 */
1387 if (tp->nfingers_down > nfake_touches ||
1388 !tp_fake_finger_is_touching(tp)) {
1389 for (i = tp->ntouches - 1; i >= 0; i--) {
1390 t = tp_get_touch(tp, i);
1391
1392 if (t->state == TOUCH_HOVERING ||
1393 t->state == TOUCH_NONE)
1394 continue;
1395
1396 tp_maybe_end_touch(tp, t, time);
1397
1398 if (tp_fake_finger_is_touching(tp) &&
1399 tp->nfingers_down == nfake_touches)
1400 break;
1401 }
1402 }
1403 }
1404
1405 static void
tp_unhover_touches(struct tp_dispatch * tp,uint64_t time)1406 tp_unhover_touches(struct tp_dispatch *tp, uint64_t time)
1407 {
1408 if (tp->pressure.use_pressure)
1409 tp_unhover_pressure(tp, time);
1410 else if (tp->touch_size.use_touch_size)
1411 tp_unhover_size(tp, time);
1412 else
1413 tp_unhover_fake_touches(tp, time);
1414
1415 }
1416
1417 static inline void
tp_position_fake_touches(struct tp_dispatch * tp)1418 tp_position_fake_touches(struct tp_dispatch *tp)
1419 {
1420 struct tp_touch *t;
1421 struct tp_touch *topmost = NULL;
1422 unsigned int start, i;
1423
1424 if (tp_fake_finger_count(tp) <= tp->num_slots ||
1425 tp->nfingers_down == 0)
1426 return;
1427
1428 /* We have at least one fake touch down. Find the top-most real
1429 * touch and copy its coordinates over to to all fake touches.
1430 * This is more reliable than just taking the first touch.
1431 */
1432 for (i = 0; i < tp->num_slots; i++) {
1433 t = tp_get_touch(tp, i);
1434 if (t->state == TOUCH_END ||
1435 t->state == TOUCH_NONE)
1436 continue;
1437
1438 if (topmost == NULL || t->point.y < topmost->point.y)
1439 topmost = t;
1440 }
1441
1442 if (!topmost) {
1443 evdev_log_bug_libinput(tp->device,
1444 "Unable to find topmost touch\n");
1445 return;
1446 }
1447
1448 start = tp->has_mt ? tp->num_slots : 1;
1449 for (i = start; i < tp->ntouches; i++) {
1450 t = tp_get_touch(tp, i);
1451 if (t->state == TOUCH_NONE)
1452 continue;
1453
1454 t->point = topmost->point;
1455 t->pressure = topmost->pressure;
1456 if (!t->dirty)
1457 t->dirty = topmost->dirty;
1458 }
1459 }
1460
1461 static inline bool
tp_need_motion_history_reset(struct tp_dispatch * tp)1462 tp_need_motion_history_reset(struct tp_dispatch *tp)
1463 {
1464 bool rc = false;
1465
1466 /* Changing the numbers of fingers can cause a jump in the
1467 * coordinates, always reset the motion history for all touches when
1468 * that happens.
1469 */
1470 if (tp->nfingers_down != tp->old_nfingers_down)
1471 return true;
1472
1473 /* Quirk: if we had multiple events without x/y axis
1474 information, the next x/y event is going to be a jump. So we
1475 reset that touch to non-dirty effectively swallowing that event
1476 and restarting with the next event again.
1477 */
1478 if (tp->device->model_flags & EVDEV_MODEL_LENOVO_T450_TOUCHPAD) {
1479 if (tp->queued & TOUCHPAD_EVENT_MOTION) {
1480 if (tp->quirks.nonmotion_event_count > 10) {
1481 tp->queued &= ~TOUCHPAD_EVENT_MOTION;
1482 rc = true;
1483 }
1484 tp->quirks.nonmotion_event_count = 0;
1485 }
1486
1487 if ((tp->queued & (TOUCHPAD_EVENT_OTHERAXIS|TOUCHPAD_EVENT_MOTION)) ==
1488 TOUCHPAD_EVENT_OTHERAXIS)
1489 tp->quirks.nonmotion_event_count++;
1490 }
1491
1492 return rc;
1493 }
1494
1495 static bool
tp_detect_jumps(const struct tp_dispatch * tp,struct tp_touch * t,uint64_t time)1496 tp_detect_jumps(const struct tp_dispatch *tp,
1497 struct tp_touch *t,
1498 uint64_t time)
1499 {
1500 struct device_coords delta;
1501 struct phys_coords mm;
1502 struct tp_history_point *last;
1503 double abs_distance, rel_distance;
1504 bool is_jump = false;
1505 uint64_t tdelta;
1506 /* Reference interval from the touchpad the various thresholds
1507 * were measured from */
1508 unsigned int reference_interval = ms2us(12);
1509
1510 /* We haven't seen pointer jumps on Wacom tablets yet, so exclude
1511 * those.
1512 */
1513 if (tp->device->model_flags & EVDEV_MODEL_WACOM_TOUCHPAD)
1514 return false;
1515
1516 if (t->history.count == 0) {
1517 t->jumps.last_delta_mm = 0.0;
1518 return false;
1519 }
1520
1521 /* called before tp_motion_history_push, so offset 0 is the most
1522 * recent coordinate */
1523 last = tp_motion_history_offset(t, 0);
1524 tdelta = time - last->time;
1525
1526 /* For test devices we always force the time delta to 12, at least
1527 until the test suite actually does proper intervals. */
1528 if (tp->device->model_flags & EVDEV_MODEL_TEST_DEVICE)
1529 reference_interval = tdelta;
1530
1531 /* If the last frame is more than 25ms ago, we have irregular
1532 * frames, who knows what's a pointer jump here and what's
1533 * legitimate movement.... */
1534 if (tdelta > 2 * reference_interval || tdelta == 0)
1535 return false;
1536
1537 /* We historically expected ~12ms frame intervals, so the numbers
1538 below are normalized to that (and that's also where the
1539 measured data came from) */
1540 delta.x = abs(t->point.x - last->point.x);
1541 delta.y = abs(t->point.y - last->point.y);
1542 mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
1543 abs_distance = hypot(mm.x, mm.y) * reference_interval/tdelta;
1544 rel_distance = abs_distance - t->jumps.last_delta_mm;
1545
1546 /* Cursor jump if:
1547 * - current single-event delta is >20mm, or
1548 * - we increased the delta by over 7mm within a 12ms frame.
1549 * (12ms simply because that's what I measured)
1550 */
1551 is_jump = abs_distance > 20.0 || rel_distance > 7;
1552 t->jumps.last_delta_mm = abs_distance;
1553
1554 return is_jump;
1555 }
1556
1557 static void
tp_detect_thumb_while_moving(struct tp_dispatch * tp)1558 tp_detect_thumb_while_moving(struct tp_dispatch *tp)
1559 {
1560 struct tp_touch *t;
1561 struct tp_touch *first = NULL,
1562 *second = NULL;
1563 struct device_coords distance;
1564 struct phys_coords mm;
1565
1566 tp_for_each_touch(tp, t) {
1567 if (t->state == TOUCH_NONE ||
1568 t->state == TOUCH_HOVERING)
1569 continue;
1570
1571 if (t->state != TOUCH_BEGIN)
1572 first = t;
1573 else
1574 second = t;
1575
1576 if (first && second)
1577 break;
1578 }
1579
1580 assert(first);
1581 assert(second);
1582
1583 if (tp->scroll.method == LIBINPUT_CONFIG_SCROLL_2FG) {
1584 /* If the second finger comes down next to the other one, we
1585 * assume this is a scroll motion.
1586 */
1587 distance.x = abs(first->point.x - second->point.x);
1588 distance.y = abs(first->point.y - second->point.y);
1589 mm = evdev_device_unit_delta_to_mm(tp->device, &distance);
1590
1591 if (mm.x <= 25 && mm.y <= 15)
1592 return;
1593 }
1594
1595 /* Finger are too far apart or 2fg scrolling is disabled, mark
1596 * second finger as thumb */
1597 evdev_log_debug(tp->device,
1598 "touch %d is speed-based thumb\n",
1599 second->index);
1600 second->thumb.state = THUMB_STATE_YES;
1601 }
1602
1603 /**
1604 * Rewrite the motion history so that previous points' timestamps are the
1605 * current point's timestamp minus whatever MSC_TIMESTAMP gives us.
1606 *
1607 * This must be called before tp_motion_history_push()
1608 *
1609 * @param t The touch point
1610 * @param jumping_interval The large time interval in µs
1611 * @param normal_interval Normal hw interval in µs
1612 * @param time Current time in µs
1613 */
1614 static inline void
tp_motion_history_fix_last(struct tp_dispatch * tp,struct tp_touch * t,unsigned int jumping_interval,unsigned int normal_interval,uint64_t time)1615 tp_motion_history_fix_last(struct tp_dispatch *tp,
1616 struct tp_touch *t,
1617 unsigned int jumping_interval,
1618 unsigned int normal_interval,
1619 uint64_t time)
1620 {
1621 if (t->state != TOUCH_UPDATE)
1622 return;
1623
1624 /* We know the coordinates are correct because the touchpad should
1625 * get that bit right. But the timestamps we got from the kernel are
1626 * messed up, so we go back in the history and fix them.
1627 *
1628 * This way the next delta is huge but it's over a large time, so
1629 * the pointer accel code should do the right thing.
1630 */
1631 for (int i = 0; i < (int)t->history.count; i++) {
1632 struct tp_history_point *p;
1633
1634 p = tp_motion_history_offset(t, i);
1635 p->time = time - jumping_interval - normal_interval * i;
1636 }
1637 }
1638
1639 static void
tp_process_msc_timestamp(struct tp_dispatch * tp,uint64_t time)1640 tp_process_msc_timestamp(struct tp_dispatch *tp, uint64_t time)
1641 {
1642 struct msc_timestamp *m = &tp->quirks.msc_timestamp;
1643
1644 /* Pointer jump detection based on MSC_TIMESTAMP.
1645
1646 MSC_TIMESTAMP gets reset after a kernel timeout (1s) and on some
1647 devices (Dell XPS) the i2c controller sleeps after a timeout. On
1648 wakeup, some events are swallowed, triggering a cursor jump. The
1649 event sequence after a sleep is always:
1650
1651 initial finger down:
1652 ABS_X/Y x/y
1653 MSC_TIMESTAMP 0
1654 SYN_REPORT +2500ms
1655 second event:
1656 ABS_X/Y x+n/y+n # normal movement
1657 MSC_TIMESTAMP 7300 # the hw interval
1658 SYN_REPORT +2ms
1659 third event:
1660 ABS_X/Y x+lots/y+lots # pointer jump!
1661 MSC_TIMESTAMP 123456 # well above the hw interval
1662 SYN_REPORT +2ms
1663 fourth event:
1664 ABS_X/Y x+lots+n/y+lots+n # all normal again
1665 MSC_TIMESTAMP 123456 + 7300
1666 SYN_REPORT +8ms
1667
1668 Our approach is to detect the 0 timestamp, check the interval on
1669 the next event and then calculate the movement for one fictious
1670 event instead, swallowing all other movements. So if the time
1671 delta is equivalent to 10 events and the movement is x, we
1672 instead pretend there was movement of x/10.
1673 */
1674 if (m->now == 0) {
1675 m->state = JUMP_STATE_EXPECT_FIRST;
1676 m->interval = 0;
1677 return;
1678 }
1679
1680 switch(m->state) {
1681 case JUMP_STATE_EXPECT_FIRST:
1682 if (m->now > ms2us(20)) {
1683 m->state = JUMP_STATE_IGNORE;
1684 } else {
1685 m->state = JUMP_STATE_EXPECT_DELAY;
1686 m->interval = m->now;
1687 }
1688 break;
1689 case JUMP_STATE_EXPECT_DELAY:
1690 if (m->now > m->interval * 2) {
1691 uint32_t tdelta; /* µs */
1692 struct tp_touch *t;
1693
1694 /* The current time is > 2 times the interval so we
1695 * have a jump. Fix the motion history */
1696 tdelta = m->now - m->interval;
1697
1698 tp_for_each_touch(tp, t) {
1699 tp_motion_history_fix_last(tp,
1700 t,
1701 tdelta,
1702 m->interval,
1703 time);
1704 }
1705 m->state = JUMP_STATE_IGNORE;
1706
1707 /* We need to restart the acceleration filter to forget its history.
1708 * The current point becomes the first point in the history there
1709 * (including timestamp) and that accelerates correctly.
1710 * This has a potential to be incorrect but since we only ever see
1711 * those jumps over the first three events it doesn't matter.
1712 */
1713 filter_restart(tp->device->pointer.filter, tp, time - tdelta);
1714 }
1715 break;
1716 case JUMP_STATE_IGNORE:
1717 break;
1718 }
1719 }
1720
1721 static void
tp_pre_process_state(struct tp_dispatch * tp,uint64_t time)1722 tp_pre_process_state(struct tp_dispatch *tp, uint64_t time)
1723 {
1724 struct tp_touch *t;
1725
1726 if (tp->queued & TOUCHPAD_EVENT_TIMESTAMP)
1727 tp_process_msc_timestamp(tp, time);
1728
1729 tp_process_fake_touches(tp, time);
1730 tp_unhover_touches(tp, time);
1731
1732 tp_for_each_touch(tp, t) {
1733 if (t->state == TOUCH_MAYBE_END)
1734 tp_end_touch(tp, t, time);
1735
1736 /* Ignore motion when pressure/touch size fell below the
1737 * threshold, thus ending the touch */
1738 if (t->state == TOUCH_END && t->history.count > 0)
1739 t->point = tp_motion_history_offset(t, 0)->point;
1740 }
1741
1742 }
1743
1744 static void
tp_process_state(struct tp_dispatch * tp,uint64_t time)1745 tp_process_state(struct tp_dispatch *tp, uint64_t time)
1746 {
1747 struct tp_touch *t;
1748 bool restart_filter = false;
1749 bool want_motion_reset;
1750 bool have_new_touch = false;
1751 unsigned int speed_exceeded_count = 0;
1752
1753 tp_position_fake_touches(tp);
1754
1755 want_motion_reset = tp_need_motion_history_reset(tp);
1756
1757 tp_for_each_touch(tp, t) {
1758 if (t->state == TOUCH_NONE)
1759 continue;
1760
1761 if (want_motion_reset) {
1762 tp_motion_history_reset(t);
1763 t->quirks.reset_motion_history = true;
1764 } else if (t->quirks.reset_motion_history) {
1765 tp_motion_history_reset(t);
1766 t->quirks.reset_motion_history = false;
1767 }
1768
1769 if (!t->dirty) {
1770 /* A non-dirty touch must be below the speed limit */
1771 if (t->speed.exceeded_count > 0)
1772 t->speed.exceeded_count--;
1773
1774 speed_exceeded_count = max(speed_exceeded_count,
1775 t->speed.exceeded_count);
1776 continue;
1777 }
1778
1779 if (tp_detect_jumps(tp, t, time)) {
1780 if (!tp->semi_mt)
1781 evdev_log_bug_kernel(tp->device,
1782 "Touch jump detected and discarded.\n"
1783 "See %stouchpad-jumping-cursors.html for details\n",
1784 HTTP_DOC_LINK);
1785 tp_motion_history_reset(t);
1786 }
1787
1788 tp_thumb_detect(tp, t, time);
1789 tp_palm_detect(tp, t, time);
1790 tp_detect_wobbling(tp, t, time);
1791 tp_motion_hysteresis(tp, t);
1792 tp_motion_history_push(t);
1793
1794 /* Touch speed handling: if we'are above the threshold,
1795 * count each event that we're over the threshold up to 10
1796 * events. Count down when we are below the speed.
1797 *
1798 * Take the touch with the highest speed excess, if it is
1799 * above a certain threshold (5, see below), assume a
1800 * dropped finger is a thumb.
1801 *
1802 * Yes, this relies on the touchpad to keep sending us
1803 * events even if the finger doesn't move, otherwise we
1804 * never count down. Let's see how far we get with that.
1805 */
1806 if (t->speed.last_speed > THUMB_IGNORE_SPEED_THRESHOLD) {
1807 if (t->speed.exceeded_count < 10)
1808 t->speed.exceeded_count++;
1809 } else if (t->speed.exceeded_count > 0) {
1810 t->speed.exceeded_count--;
1811 }
1812
1813 speed_exceeded_count = max(speed_exceeded_count,
1814 t->speed.exceeded_count);
1815
1816 tp_calculate_motion_speed(tp, t);
1817
1818 tp_unpin_finger(tp, t);
1819
1820 if (t->state == TOUCH_BEGIN) {
1821 have_new_touch = true;
1822 restart_filter = true;
1823 }
1824 }
1825
1826 /* If we have one touch that exceeds the speed and we get a new
1827 * touch down while doing that, the second touch is a thumb */
1828 if (have_new_touch &&
1829 tp->nfingers_down == 2 &&
1830 speed_exceeded_count > 5)
1831 tp_detect_thumb_while_moving(tp);
1832
1833 if (restart_filter)
1834 filter_restart(tp->device->pointer.filter, tp, time);
1835
1836 tp_button_handle_state(tp, time);
1837 tp_edge_scroll_handle_state(tp, time);
1838
1839 /*
1840 * We have a physical button down event on a clickpad. To avoid
1841 * spurious pointer moves by the clicking finger we pin all fingers.
1842 * We unpin fingers when they move more then a certain threshold to
1843 * to allow drag and drop.
1844 */
1845 if ((tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) &&
1846 tp->buttons.is_clickpad)
1847 tp_pin_fingers(tp);
1848
1849 tp_gesture_handle_state(tp, time);
1850 }
1851
1852 static void
tp_post_process_state(struct tp_dispatch * tp,uint64_t time)1853 tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
1854 {
1855 struct tp_touch *t;
1856
1857 tp_for_each_touch(tp, t) {
1858
1859 if (!t->dirty)
1860 continue;
1861
1862 if (t->state == TOUCH_END) {
1863 if (t->has_ended)
1864 t->state = TOUCH_NONE;
1865 else
1866 t->state = TOUCH_HOVERING;
1867 } else if (t->state == TOUCH_BEGIN) {
1868 t->state = TOUCH_UPDATE;
1869 }
1870
1871 t->dirty = false;
1872 }
1873
1874 tp->old_nfingers_down = tp->nfingers_down;
1875 tp->buttons.old_state = tp->buttons.state;
1876
1877 tp->queued = TOUCHPAD_EVENT_NONE;
1878
1879 tp_tap_post_process_state(tp);
1880 }
1881
1882 static void
tp_post_events(struct tp_dispatch * tp,uint64_t time)1883 tp_post_events(struct tp_dispatch *tp, uint64_t time)
1884 {
1885 int filter_motion = 0;
1886
1887 /* Only post (top) button events while suspended */
1888 if (tp->device->is_suspended) {
1889 tp_post_button_events(tp, time);
1890 return;
1891 }
1892
1893 filter_motion |= tp_tap_handle_state(tp, time);
1894 filter_motion |= tp_post_button_events(tp, time);
1895
1896 if (filter_motion ||
1897 tp->palm.trackpoint_active ||
1898 tp->dwt.keyboard_active) {
1899 tp_edge_scroll_stop_events(tp, time);
1900 tp_gesture_cancel(tp, time);
1901 return;
1902 }
1903
1904 if (tp_edge_scroll_post_events(tp, time) != 0)
1905 return;
1906
1907 tp_gesture_post_events(tp, time);
1908 }
1909
1910 static void
tp_handle_state(struct tp_dispatch * tp,uint64_t time)1911 tp_handle_state(struct tp_dispatch *tp,
1912 uint64_t time)
1913 {
1914 tp_pre_process_state(tp, time);
1915 tp_process_state(tp, time);
1916 tp_post_events(tp, time);
1917 tp_post_process_state(tp, time);
1918
1919 tp_clickpad_middlebutton_apply_config(tp->device);
1920 }
1921
1922 static inline void
tp_debug_touch_state(struct tp_dispatch * tp,struct evdev_device * device)1923 tp_debug_touch_state(struct tp_dispatch *tp,
1924 struct evdev_device *device)
1925 {
1926 char buf[1024] = {0};
1927 struct tp_touch *t;
1928 size_t i = 0;
1929
1930 tp_for_each_touch(tp, t) {
1931 if (i >= tp->nfingers_down)
1932 break;
1933 sprintf(&buf[strlen(buf)],
1934 "slot %zd: %04d/%04d p%03d %s |",
1935 i++,
1936 t->point.x,
1937 t->point.y,
1938 t->pressure,
1939 tp_touch_active(tp, t) ? "" : "inactive");
1940 }
1941 if (buf[0] != '\0')
1942 evdev_log_debug(device, "touch state: %s\n", buf);
1943 }
1944
1945 static void
tp_interface_process(struct evdev_dispatch * dispatch,struct evdev_device * device,struct input_event * e,uint64_t time)1946 tp_interface_process(struct evdev_dispatch *dispatch,
1947 struct evdev_device *device,
1948 struct input_event *e,
1949 uint64_t time)
1950 {
1951 struct tp_dispatch *tp = tp_dispatch(dispatch);
1952
1953 switch (e->type) {
1954 case EV_ABS:
1955 if (tp->has_mt)
1956 tp_process_absolute(tp, e, time);
1957 else
1958 tp_process_absolute_st(tp, e, time);
1959 break;
1960 case EV_KEY:
1961 tp_process_key(tp, e, time);
1962 break;
1963 case EV_MSC:
1964 tp_process_msc(tp, e, time);
1965 break;
1966 case EV_SYN:
1967 tp_handle_state(tp, time);
1968 #if 0
1969 tp_debug_touch_state(tp, device);
1970 #endif
1971 break;
1972 }
1973 }
1974
1975 static void
tp_remove_sendevents(struct tp_dispatch * tp)1976 tp_remove_sendevents(struct tp_dispatch *tp)
1977 {
1978 struct evdev_paired_keyboard *kbd;
1979
1980 libinput_timer_cancel(&tp->palm.trackpoint_timer);
1981 libinput_timer_cancel(&tp->dwt.keyboard_timer);
1982
1983 if (tp->buttons.trackpoint &&
1984 tp->palm.monitor_trackpoint)
1985 libinput_device_remove_event_listener(
1986 &tp->palm.trackpoint_listener);
1987
1988 list_for_each(kbd, &tp->dwt.paired_keyboard_list, link) {
1989 libinput_device_remove_event_listener(&kbd->listener);
1990 }
1991
1992 if (tp->lid_switch.lid_switch)
1993 libinput_device_remove_event_listener(
1994 &tp->lid_switch.listener);
1995
1996 if (tp->tablet_mode_switch.tablet_mode_switch)
1997 libinput_device_remove_event_listener(
1998 &tp->tablet_mode_switch.listener);
1999 }
2000
2001 static void
tp_interface_remove(struct evdev_dispatch * dispatch)2002 tp_interface_remove(struct evdev_dispatch *dispatch)
2003 {
2004 struct tp_dispatch *tp = tp_dispatch(dispatch);
2005
2006 libinput_timer_cancel(&tp->arbitration.arbitration_timer);
2007
2008 tp_remove_tap(tp);
2009 tp_remove_buttons(tp);
2010 tp_remove_sendevents(tp);
2011 tp_remove_edge_scroll(tp);
2012 tp_remove_gesture(tp);
2013 }
2014
2015 static void
tp_interface_destroy(struct evdev_dispatch * dispatch)2016 tp_interface_destroy(struct evdev_dispatch *dispatch)
2017 {
2018 struct tp_dispatch *tp = tp_dispatch(dispatch);
2019
2020 libinput_timer_destroy(&tp->arbitration.arbitration_timer);
2021 libinput_timer_destroy(&tp->palm.trackpoint_timer);
2022 libinput_timer_destroy(&tp->dwt.keyboard_timer);
2023 libinput_timer_destroy(&tp->tap.timer);
2024 libinput_timer_destroy(&tp->gesture.finger_count_switch_timer);
2025 free(tp->touches);
2026 free(tp);
2027 }
2028
2029 static void
tp_release_fake_touches(struct tp_dispatch * tp)2030 tp_release_fake_touches(struct tp_dispatch *tp)
2031 {
2032 tp->fake_touches = 0;
2033 }
2034
2035 static void
tp_clear_state(struct tp_dispatch * tp)2036 tp_clear_state(struct tp_dispatch *tp)
2037 {
2038 uint64_t now = libinput_now(tp_libinput_context(tp));
2039 struct tp_touch *t;
2040
2041 /* Unroll the touchpad state.
2042 * Release buttons first. If tp is a clickpad, the button event
2043 * must come before the touch up. If it isn't, the order doesn't
2044 * matter anyway
2045 *
2046 * Then cancel all timeouts on the taps, triggering the last set
2047 * of events.
2048 *
2049 * Then lift all touches so the touchpad is in a neutral state.
2050 *
2051 */
2052 tp_release_all_buttons(tp, now);
2053 tp_release_all_taps(tp, now);
2054
2055 tp_for_each_touch(tp, t) {
2056 tp_end_sequence(tp, t, now);
2057 }
2058 tp_release_fake_touches(tp);
2059
2060 tp_handle_state(tp, now);
2061 }
2062
2063 static void
tp_suspend(struct tp_dispatch * tp,struct evdev_device * device,enum suspend_trigger trigger)2064 tp_suspend(struct tp_dispatch *tp,
2065 struct evdev_device *device,
2066 enum suspend_trigger trigger)
2067 {
2068 if (tp->suspend_reason & trigger)
2069 return;
2070
2071 if (tp->suspend_reason != 0)
2072 goto out;
2073
2074 tp_clear_state(tp);
2075
2076 /* On devices with top softwarebuttons we don't actually suspend the
2077 * device, to keep the "trackpoint" buttons working. tp_post_events()
2078 * will only send events for the trackpoint while suspended.
2079 */
2080 if (tp->buttons.has_topbuttons) {
2081 evdev_notify_suspended_device(device);
2082 /* Enlarge topbutton area while suspended */
2083 tp_init_top_softbuttons(tp, device, 3.0);
2084 } else {
2085 evdev_device_suspend(device);
2086 }
2087
2088 out:
2089 tp->suspend_reason |= trigger;
2090 }
2091
2092 static void
tp_interface_suspend(struct evdev_dispatch * dispatch,struct evdev_device * device)2093 tp_interface_suspend(struct evdev_dispatch *dispatch,
2094 struct evdev_device *device)
2095 {
2096 struct tp_dispatch *tp = tp_dispatch(dispatch);
2097
2098 tp_clear_state(tp);
2099 }
2100
2101 static inline void
tp_sync_touch(struct tp_dispatch * tp,struct evdev_device * device,struct tp_touch * t,int slot)2102 tp_sync_touch(struct tp_dispatch *tp,
2103 struct evdev_device *device,
2104 struct tp_touch *t,
2105 int slot)
2106 {
2107 struct libevdev *evdev = device->evdev;
2108
2109 if (!libevdev_fetch_slot_value(evdev,
2110 slot,
2111 ABS_MT_POSITION_X,
2112 &t->point.x))
2113 t->point.x = libevdev_get_event_value(evdev, EV_ABS, ABS_X);
2114 if (!libevdev_fetch_slot_value(evdev,
2115 slot,
2116 ABS_MT_POSITION_Y,
2117 &t->point.y))
2118 t->point.y = libevdev_get_event_value(evdev, EV_ABS, ABS_Y);
2119
2120 if (!libevdev_fetch_slot_value(evdev,
2121 slot,
2122 ABS_MT_PRESSURE,
2123 &t->pressure))
2124 t->pressure = libevdev_get_event_value(evdev,
2125 EV_ABS,
2126 ABS_PRESSURE);
2127
2128 libevdev_fetch_slot_value(evdev,
2129 slot,
2130 ABS_MT_TOUCH_MAJOR,
2131 &t->major);
2132 libevdev_fetch_slot_value(evdev,
2133 slot,
2134 ABS_MT_TOUCH_MINOR,
2135 &t->minor);
2136 }
2137
2138 static void
tp_sync_slots(struct tp_dispatch * tp,struct evdev_device * device)2139 tp_sync_slots(struct tp_dispatch *tp,
2140 struct evdev_device *device)
2141 {
2142 /* Always sync the first touch so we get ABS_X/Y synced on
2143 * single-touch touchpads */
2144 tp_sync_touch(tp, device, &tp->touches[0], 0);
2145 for (unsigned int i = 1; i < tp->num_slots; i++)
2146 tp_sync_touch(tp, device, &tp->touches[i], i);
2147 }
2148
2149 static void
tp_resume(struct tp_dispatch * tp,struct evdev_device * device,enum suspend_trigger trigger)2150 tp_resume(struct tp_dispatch *tp,
2151 struct evdev_device *device,
2152 enum suspend_trigger trigger)
2153 {
2154 tp->suspend_reason &= ~trigger;
2155 if (tp->suspend_reason != 0)
2156 return;
2157
2158 if (tp->buttons.has_topbuttons) {
2159 /* tap state-machine is offline while suspended, reset state */
2160 tp_clear_state(tp);
2161 /* restore original topbutton area size */
2162 tp_init_top_softbuttons(tp, device, 1.0);
2163 evdev_notify_resumed_device(device);
2164 } else {
2165 evdev_device_resume(device);
2166 }
2167
2168 tp_sync_slots(tp, device);
2169 }
2170
2171 static void
tp_trackpoint_timeout(uint64_t now,void * data)2172 tp_trackpoint_timeout(uint64_t now, void *data)
2173 {
2174 struct tp_dispatch *tp = data;
2175
2176 if (tp->palm.trackpoint_active) {
2177 tp_tap_resume(tp, now);
2178 tp->palm.trackpoint_active = false;
2179 }
2180 tp->palm.trackpoint_event_count = 0;
2181 }
2182
2183 static void
tp_trackpoint_event(uint64_t time,struct libinput_event * event,void * data)2184 tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data)
2185 {
2186 struct tp_dispatch *tp = data;
2187
2188 /* Buttons do not count as trackpad activity, as people may use
2189 the trackpoint buttons in combination with the touchpad. */
2190 if (event->type == LIBINPUT_EVENT_POINTER_BUTTON)
2191 return;
2192
2193 tp->palm.trackpoint_last_event_time = time;
2194 tp->palm.trackpoint_event_count++;
2195
2196
2197 /* Require at least three events before enabling palm detection */
2198 if (tp->palm.trackpoint_event_count < 3) {
2199 libinput_timer_set(&tp->palm.trackpoint_timer,
2200 time + DEFAULT_TRACKPOINT_EVENT_TIMEOUT);
2201 return;
2202 }
2203
2204 if (!tp->palm.trackpoint_active) {
2205 tp_stop_actions(tp, time);
2206 tp->palm.trackpoint_active = true;
2207 }
2208
2209 libinput_timer_set(&tp->palm.trackpoint_timer,
2210 time + DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT);
2211 }
2212
2213 static void
tp_keyboard_timeout(uint64_t now,void * data)2214 tp_keyboard_timeout(uint64_t now, void *data)
2215 {
2216 struct tp_dispatch *tp = data;
2217
2218 if (tp->dwt.dwt_enabled &&
2219 long_any_bit_set(tp->dwt.key_mask,
2220 ARRAY_LENGTH(tp->dwt.key_mask))) {
2221 libinput_timer_set(&tp->dwt.keyboard_timer,
2222 now + DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2);
2223 tp->dwt.keyboard_last_press_time = now;
2224 evdev_log_debug(tp->device, "palm: keyboard timeout refresh\n");
2225 return;
2226 }
2227
2228 tp_tap_resume(tp, now);
2229
2230 tp->dwt.keyboard_active = false;
2231
2232 evdev_log_debug(tp->device, "palm: keyboard timeout\n");
2233 }
2234
2235 static inline bool
tp_key_is_modifier(unsigned int keycode)2236 tp_key_is_modifier(unsigned int keycode)
2237 {
2238 switch (keycode) {
2239 /* Ignore modifiers to be responsive to ctrl-click, alt-tab, etc. */
2240 case KEY_LEFTCTRL:
2241 case KEY_RIGHTCTRL:
2242 case KEY_LEFTALT:
2243 case KEY_RIGHTALT:
2244 case KEY_LEFTSHIFT:
2245 case KEY_RIGHTSHIFT:
2246 case KEY_FN:
2247 case KEY_CAPSLOCK:
2248 case KEY_TAB:
2249 case KEY_COMPOSE:
2250 case KEY_RIGHTMETA:
2251 case KEY_LEFTMETA:
2252 return true;
2253 default:
2254 return false;
2255 }
2256 }
2257
2258 static inline bool
tp_key_ignore_for_dwt(unsigned int keycode)2259 tp_key_ignore_for_dwt(unsigned int keycode)
2260 {
2261 /* Ignore keys not part of the "typewriter set", i.e. F-keys,
2262 * multimedia keys, numpad, etc.
2263 */
2264
2265 if (tp_key_is_modifier(keycode))
2266 return false;
2267
2268 return keycode >= KEY_F1;
2269 }
2270
2271 static void
tp_keyboard_event(uint64_t time,struct libinput_event * event,void * data)2272 tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
2273 {
2274 struct tp_dispatch *tp = data;
2275 struct libinput_event_keyboard *kbdev;
2276 unsigned int timeout;
2277 unsigned int key;
2278 bool is_modifier;
2279
2280 if (event->type != LIBINPUT_EVENT_KEYBOARD_KEY)
2281 return;
2282
2283 kbdev = libinput_event_get_keyboard_event(event);
2284 key = libinput_event_keyboard_get_key(kbdev);
2285
2286 /* Only trigger the timer on key down. */
2287 if (libinput_event_keyboard_get_key_state(kbdev) !=
2288 LIBINPUT_KEY_STATE_PRESSED) {
2289 long_clear_bit(tp->dwt.key_mask, key);
2290 long_clear_bit(tp->dwt.mod_mask, key);
2291 return;
2292 }
2293
2294 if (!tp->dwt.dwt_enabled)
2295 return;
2296
2297 if (tp_key_ignore_for_dwt(key))
2298 return;
2299
2300 /* modifier keys don't trigger disable-while-typing so things like
2301 * ctrl+zoom or ctrl+click are possible */
2302 is_modifier = tp_key_is_modifier(key);
2303 if (is_modifier) {
2304 long_set_bit(tp->dwt.mod_mask, key);
2305 return;
2306 }
2307
2308 if (!tp->dwt.keyboard_active) {
2309 /* This is the first non-modifier key press. Check if the
2310 * modifier mask is set. If any modifier is down we don't
2311 * trigger dwt because it's likely to be combination like
2312 * Ctrl+S or similar */
2313
2314 if (long_any_bit_set(tp->dwt.mod_mask,
2315 ARRAY_LENGTH(tp->dwt.mod_mask)))
2316 return;
2317
2318 tp_stop_actions(tp, time);
2319 tp->dwt.keyboard_active = true;
2320 timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1;
2321 } else {
2322 timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
2323 }
2324
2325 tp->dwt.keyboard_last_press_time = time;
2326 long_set_bit(tp->dwt.key_mask, key);
2327 libinput_timer_set(&tp->dwt.keyboard_timer,
2328 time + timeout);
2329 }
2330
2331 static bool
tp_want_dwt(struct evdev_device * touchpad,struct evdev_device * keyboard)2332 tp_want_dwt(struct evdev_device *touchpad,
2333 struct evdev_device *keyboard)
2334 {
2335 unsigned int vendor_tp = evdev_device_get_id_vendor(touchpad);
2336 unsigned int vendor_kbd = evdev_device_get_id_vendor(keyboard);
2337 unsigned int product_tp = evdev_device_get_id_product(touchpad);
2338 unsigned int product_kbd = evdev_device_get_id_product(keyboard);
2339
2340 /* External touchpads with the same vid/pid as the keyboard are
2341 considered a happy couple */
2342 if (touchpad->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD)
2343 return vendor_tp == vendor_kbd && product_tp == product_kbd;
2344 else if (keyboard->tags & EVDEV_TAG_INTERNAL_KEYBOARD)
2345 return true;
2346
2347 /* keyboard is not tagged as internal keyboard and it's not part of
2348 * a combo */
2349 return false;
2350 }
2351
2352 static void
tp_dwt_pair_keyboard(struct evdev_device * touchpad,struct evdev_device * keyboard)2353 tp_dwt_pair_keyboard(struct evdev_device *touchpad,
2354 struct evdev_device *keyboard)
2355 {
2356 struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
2357 struct evdev_paired_keyboard *kbd;
2358 size_t count = 0;
2359
2360 if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0)
2361 return;
2362
2363 if (!tp_want_dwt(touchpad, keyboard))
2364 return;
2365
2366 list_for_each(kbd, &tp->dwt.paired_keyboard_list, link) {
2367 count++;
2368 if (count > 3) {
2369 evdev_log_info(touchpad,
2370 "too many internal keyboards for dwt\n");
2371 break;
2372 }
2373 }
2374
2375 kbd = zalloc(sizeof(*kbd));
2376 kbd->device = keyboard;
2377 libinput_device_add_event_listener(&keyboard->base,
2378 &kbd->listener,
2379 tp_keyboard_event, tp);
2380 list_insert(&tp->dwt.paired_keyboard_list, &kbd->link);
2381 evdev_log_debug(touchpad,
2382 "palm: dwt activated with %s<->%s\n",
2383 touchpad->devname,
2384 keyboard->devname);
2385 }
2386
2387 static void
tp_pair_trackpoint(struct evdev_device * touchpad,struct evdev_device * trackpoint)2388 tp_pair_trackpoint(struct evdev_device *touchpad,
2389 struct evdev_device *trackpoint)
2390 {
2391 struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
2392 unsigned int bus_tp = libevdev_get_id_bustype(touchpad->evdev),
2393 bus_trp = libevdev_get_id_bustype(trackpoint->evdev);
2394 bool tp_is_internal, trp_is_internal;
2395
2396 if ((trackpoint->tags & EVDEV_TAG_TRACKPOINT) == 0)
2397 return;
2398
2399 tp_is_internal = bus_tp != BUS_USB && bus_tp != BUS_BLUETOOTH;
2400 trp_is_internal = bus_trp != BUS_USB && bus_trp != BUS_BLUETOOTH;
2401
2402 if (tp->buttons.trackpoint == NULL &&
2403 tp_is_internal && trp_is_internal) {
2404 /* Don't send any pending releases to the new trackpoint */
2405 tp->buttons.active_is_topbutton = false;
2406 tp->buttons.trackpoint = trackpoint;
2407 if (tp->palm.monitor_trackpoint)
2408 libinput_device_add_event_listener(&trackpoint->base,
2409 &tp->palm.trackpoint_listener,
2410 tp_trackpoint_event, tp);
2411 }
2412 }
2413
2414 static void
tp_lid_switch_event(uint64_t time,struct libinput_event * event,void * data)2415 tp_lid_switch_event(uint64_t time, struct libinput_event *event, void *data)
2416 {
2417 struct tp_dispatch *tp = data;
2418 struct libinput_event_switch *swev;
2419
2420 if (libinput_event_get_type(event) != LIBINPUT_EVENT_SWITCH_TOGGLE)
2421 return;
2422
2423 swev = libinput_event_get_switch_event(event);
2424 if (libinput_event_switch_get_switch(swev) != LIBINPUT_SWITCH_LID)
2425 return;
2426
2427 switch (libinput_event_switch_get_switch_state(swev)) {
2428 case LIBINPUT_SWITCH_STATE_OFF:
2429 tp_resume(tp, tp->device, SUSPEND_LID);
2430 evdev_log_debug(tp->device, "lid: resume touchpad\n");
2431 break;
2432 case LIBINPUT_SWITCH_STATE_ON:
2433 tp_suspend(tp, tp->device, SUSPEND_LID);
2434 evdev_log_debug(tp->device, "lid: suspending touchpad\n");
2435 break;
2436 }
2437 }
2438
2439 static void
tp_tablet_mode_switch_event(uint64_t time,struct libinput_event * event,void * data)2440 tp_tablet_mode_switch_event(uint64_t time,
2441 struct libinput_event *event,
2442 void *data)
2443 {
2444 struct tp_dispatch *tp = data;
2445 struct libinput_event_switch *swev;
2446
2447 if (libinput_event_get_type(event) != LIBINPUT_EVENT_SWITCH_TOGGLE)
2448 return;
2449
2450 swev = libinput_event_get_switch_event(event);
2451 if (libinput_event_switch_get_switch(swev) !=
2452 LIBINPUT_SWITCH_TABLET_MODE)
2453 return;
2454
2455 switch (libinput_event_switch_get_switch_state(swev)) {
2456 case LIBINPUT_SWITCH_STATE_OFF:
2457 tp_resume(tp, tp->device, SUSPEND_TABLET_MODE);
2458 evdev_log_debug(tp->device, "tablet-mode: resume touchpad\n");
2459 break;
2460 case LIBINPUT_SWITCH_STATE_ON:
2461 tp_suspend(tp, tp->device, SUSPEND_TABLET_MODE);
2462 evdev_log_debug(tp->device, "tablet-mode: suspending touchpad\n");
2463 break;
2464 }
2465 }
2466
2467 static void
tp_pair_lid_switch(struct evdev_device * touchpad,struct evdev_device * lid_switch)2468 tp_pair_lid_switch(struct evdev_device *touchpad,
2469 struct evdev_device *lid_switch)
2470 {
2471 struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
2472
2473 if ((lid_switch->tags & EVDEV_TAG_LID_SWITCH) == 0)
2474 return;
2475
2476 if (touchpad->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD)
2477 return;
2478
2479 if (tp->lid_switch.lid_switch == NULL) {
2480 evdev_log_debug(touchpad,
2481 "lid_switch: activated for %s<->%s\n",
2482 touchpad->devname,
2483 lid_switch->devname);
2484
2485 libinput_device_add_event_listener(&lid_switch->base,
2486 &tp->lid_switch.listener,
2487 tp_lid_switch_event, tp);
2488 tp->lid_switch.lid_switch = lid_switch;
2489 }
2490 }
2491
2492 static void
tp_pair_tablet_mode_switch(struct evdev_device * touchpad,struct evdev_device * tablet_mode_switch)2493 tp_pair_tablet_mode_switch(struct evdev_device *touchpad,
2494 struct evdev_device *tablet_mode_switch)
2495 {
2496 struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
2497
2498 if ((tablet_mode_switch->tags & EVDEV_TAG_TABLET_MODE_SWITCH) == 0)
2499 return;
2500
2501 if (tp->tablet_mode_switch.tablet_mode_switch)
2502 return;
2503
2504 if (touchpad->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD)
2505 return;
2506
2507 if (evdev_device_has_model_quirk(touchpad,
2508 QUIRK_MODEL_TABLET_MODE_NO_SUSPEND))
2509 return;
2510
2511 evdev_log_debug(touchpad,
2512 "tablet_mode_switch: activated for %s<->%s\n",
2513 touchpad->devname,
2514 tablet_mode_switch->devname);
2515
2516 libinput_device_add_event_listener(&tablet_mode_switch->base,
2517 &tp->tablet_mode_switch.listener,
2518 tp_tablet_mode_switch_event, tp);
2519 tp->tablet_mode_switch.tablet_mode_switch = tablet_mode_switch;
2520
2521 if (evdev_device_switch_get_state(tablet_mode_switch,
2522 LIBINPUT_SWITCH_TABLET_MODE)
2523 == LIBINPUT_SWITCH_STATE_ON) {
2524 tp_suspend(tp, touchpad, SUSPEND_TABLET_MODE);
2525 }
2526 }
2527
2528 static void
tp_interface_device_added(struct evdev_device * device,struct evdev_device * added_device)2529 tp_interface_device_added(struct evdev_device *device,
2530 struct evdev_device *added_device)
2531 {
2532 struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
2533
2534 tp_pair_trackpoint(device, added_device);
2535 tp_dwt_pair_keyboard(device, added_device);
2536 tp_pair_lid_switch(device, added_device);
2537 tp_pair_tablet_mode_switch(device, added_device);
2538
2539 if (tp->sendevents.current_mode !=
2540 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
2541 return;
2542
2543 if (added_device->tags & EVDEV_TAG_EXTERNAL_MOUSE)
2544 tp_suspend(tp, device, SUSPEND_EXTERNAL_MOUSE);
2545 }
2546
2547 static void
tp_interface_device_removed(struct evdev_device * device,struct evdev_device * removed_device)2548 tp_interface_device_removed(struct evdev_device *device,
2549 struct evdev_device *removed_device)
2550 {
2551 struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
2552 struct evdev_paired_keyboard *kbd, *tmp;
2553
2554 if (removed_device == tp->buttons.trackpoint) {
2555 /* Clear any pending releases for the trackpoint */
2556 if (tp->buttons.active && tp->buttons.active_is_topbutton) {
2557 tp->buttons.active = 0;
2558 tp->buttons.active_is_topbutton = false;
2559 }
2560 if (tp->palm.monitor_trackpoint)
2561 libinput_device_remove_event_listener(
2562 &tp->palm.trackpoint_listener);
2563 tp->buttons.trackpoint = NULL;
2564 }
2565
2566 list_for_each_safe(kbd, tmp, &tp->dwt.paired_keyboard_list, link) {
2567 if (kbd->device == removed_device) {
2568 evdev_paired_keyboard_destroy(kbd);
2569 tp->dwt.keyboard_active = false;
2570 }
2571 }
2572
2573 if (removed_device == tp->lid_switch.lid_switch) {
2574 libinput_device_remove_event_listener(
2575 &tp->lid_switch.listener);
2576 tp->lid_switch.lid_switch = NULL;
2577 tp_resume(tp, device, SUSPEND_LID);
2578 }
2579
2580 if (removed_device == tp->tablet_mode_switch.tablet_mode_switch) {
2581 libinput_device_remove_event_listener(
2582 &tp->tablet_mode_switch.listener);
2583 tp->tablet_mode_switch.tablet_mode_switch = NULL;
2584 tp_resume(tp, device, SUSPEND_TABLET_MODE);
2585 }
2586
2587 if (tp->sendevents.current_mode ==
2588 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE) {
2589 struct libinput_device *dev;
2590 bool found = false;
2591
2592 list_for_each(dev, &device->base.seat->devices_list, link) {
2593 struct evdev_device *d = evdev_device(dev);
2594 if (d != removed_device &&
2595 (d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
2596 found = true;
2597 break;
2598 }
2599 }
2600 if (!found)
2601 tp_resume(tp, device, SUSPEND_EXTERNAL_MOUSE);
2602 }
2603 }
2604
2605 static inline void
evdev_tag_touchpad_internal(struct evdev_device * device)2606 evdev_tag_touchpad_internal(struct evdev_device *device)
2607 {
2608 device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
2609 device->tags &= ~EVDEV_TAG_EXTERNAL_TOUCHPAD;
2610 }
2611
2612 static inline void
evdev_tag_touchpad_external(struct evdev_device * device)2613 evdev_tag_touchpad_external(struct evdev_device *device)
2614 {
2615 device->tags |= EVDEV_TAG_EXTERNAL_TOUCHPAD;
2616 device->tags &= ~EVDEV_TAG_INTERNAL_TOUCHPAD;
2617 }
2618
2619 static void
evdev_tag_touchpad(struct evdev_device * device,struct udev_device * udev_device)2620 evdev_tag_touchpad(struct evdev_device *device,
2621 struct udev_device *udev_device)
2622 {
2623 int bustype, vendor;
2624 const char *prop;
2625
2626 prop = udev_device_get_property_value(udev_device,
2627 "ID_INPUT_TOUCHPAD_INTEGRATION");
2628 if (prop) {
2629 if (streq(prop, "internal")) {
2630 evdev_tag_touchpad_internal(device);
2631 return;
2632 } else if (streq(prop, "external")) {
2633 evdev_tag_touchpad_external(device);
2634 return;
2635 } else {
2636 evdev_log_info(device,
2637 "tagged with unknown value %s\n",
2638 prop);
2639 }
2640 }
2641
2642 /* simple approach: touchpads on USB or Bluetooth are considered
2643 * external, anything else is internal. Exception is Apple -
2644 * internal touchpads are connected over USB and it doesn't have
2645 * external USB touchpads anyway.
2646 */
2647 bustype = libevdev_get_id_bustype(device->evdev);
2648 vendor = libevdev_get_id_vendor(device->evdev);
2649
2650 switch (bustype) {
2651 case BUS_USB:
2652 if (evdev_device_has_model_quirk(device,
2653 QUIRK_MODEL_APPLE_TOUCHPAD))
2654 evdev_tag_touchpad_internal(device);
2655 break;
2656 case BUS_BLUETOOTH:
2657 evdev_tag_touchpad_external(device);
2658 break;
2659 default:
2660 evdev_tag_touchpad_internal(device);
2661 break;
2662 }
2663
2664 switch (vendor) {
2665 /* Logitech does not have internal touchpads */
2666 case VENDOR_ID_LOGITECH:
2667 evdev_tag_touchpad_external(device);
2668 break;
2669 }
2670
2671 /* Wacom makes touchpads, but not internal ones */
2672 if (device->model_flags & EVDEV_MODEL_WACOM_TOUCHPAD)
2673 evdev_tag_touchpad_external(device);
2674
2675 if ((device->tags &
2676 (EVDEV_TAG_EXTERNAL_TOUCHPAD|EVDEV_TAG_INTERNAL_TOUCHPAD)) == 0) {
2677 evdev_log_bug_libinput(device,
2678 "Internal or external? Please file a bug.\n");
2679 evdev_tag_touchpad_external(device);
2680 }
2681 }
2682
2683 static void
tp_arbitration_timeout(uint64_t now,void * data)2684 tp_arbitration_timeout(uint64_t now, void *data)
2685 {
2686 struct tp_dispatch *tp = data;
2687
2688 if (tp->arbitration.in_arbitration)
2689 tp->arbitration.in_arbitration = false;
2690 }
2691
2692 static void
tp_interface_toggle_touch(struct evdev_dispatch * dispatch,struct evdev_device * device,bool enable,uint64_t time)2693 tp_interface_toggle_touch(struct evdev_dispatch *dispatch,
2694 struct evdev_device *device,
2695 bool enable,
2696 uint64_t time)
2697 {
2698 struct tp_dispatch *tp = tp_dispatch(dispatch);
2699 bool arbitrate = !enable;
2700
2701 if (arbitrate == tp->arbitration.in_arbitration)
2702 return;
2703
2704 if (arbitrate) {
2705 libinput_timer_cancel(&tp->arbitration.arbitration_timer);
2706 tp_clear_state(tp);
2707 tp->arbitration.in_arbitration = true;
2708 } else {
2709 /* if in-kernel arbitration is in use and there is a touch
2710 * and a pen in proximity, lifting the pen out of proximity
2711 * causes a touch begin for the touch. On a hand-lift the
2712 * proximity out precedes the touch up by a few ms, so we
2713 * get what looks like a tap. Fix this by delaying
2714 * arbitration by just a little bit so that any touch in
2715 * event is caught as palm touch. */
2716 libinput_timer_set(&tp->arbitration.arbitration_timer,
2717 time + ms2us(90));
2718 }
2719 }
2720
2721 static struct evdev_dispatch_interface tp_interface = {
2722 .process = tp_interface_process,
2723 .suspend = tp_interface_suspend,
2724 .remove = tp_interface_remove,
2725 .destroy = tp_interface_destroy,
2726 .device_added = tp_interface_device_added,
2727 .device_removed = tp_interface_device_removed,
2728 .device_suspended = tp_interface_device_removed, /* treat as remove */
2729 .device_resumed = tp_interface_device_added, /* treat as add */
2730 .post_added = NULL,
2731 .toggle_touch = tp_interface_toggle_touch,
2732 .get_switch_state = NULL,
2733 };
2734
2735 static void
tp_init_touch(struct tp_dispatch * tp,struct tp_touch * t,unsigned int index)2736 tp_init_touch(struct tp_dispatch *tp,
2737 struct tp_touch *t,
2738 unsigned int index)
2739 {
2740 t->tp = tp;
2741 t->has_ended = true;
2742 t->index = index;
2743 }
2744
2745 static inline void
tp_disable_abs_mt(struct evdev_device * device)2746 tp_disable_abs_mt(struct evdev_device *device)
2747 {
2748 struct libevdev *evdev = device->evdev;
2749 unsigned int code;
2750
2751 for (code = ABS_MT_SLOT; code <= ABS_MAX; code++)
2752 libevdev_disable_event_code(evdev, EV_ABS, code);
2753 }
2754
2755 static bool
tp_init_slots(struct tp_dispatch * tp,struct evdev_device * device)2756 tp_init_slots(struct tp_dispatch *tp,
2757 struct evdev_device *device)
2758 {
2759 const struct input_absinfo *absinfo;
2760 struct map {
2761 unsigned int code;
2762 int ntouches;
2763 } max_touches[] = {
2764 { BTN_TOOL_QUINTTAP, 5 },
2765 { BTN_TOOL_QUADTAP, 4 },
2766 { BTN_TOOL_TRIPLETAP, 3 },
2767 { BTN_TOOL_DOUBLETAP, 2 },
2768 };
2769 struct map *m;
2770 unsigned int i, n_btn_tool_touches = 1;
2771
2772 absinfo = libevdev_get_abs_info(device->evdev, ABS_MT_SLOT);
2773 if (absinfo) {
2774 tp->num_slots = absinfo->maximum + 1;
2775 tp->slot = absinfo->value;
2776 tp->has_mt = true;
2777 } else {
2778 tp->num_slots = 1;
2779 tp->slot = 0;
2780 tp->has_mt = false;
2781 }
2782
2783 tp->semi_mt = libevdev_has_property(device->evdev, INPUT_PROP_SEMI_MT);
2784
2785 /* Semi-mt devices are not reliable for true multitouch data, so we
2786 * simply pretend they're single touch touchpads with BTN_TOOL bits.
2787 * Synaptics:
2788 * Terrible resolution when two fingers are down,
2789 * causing scroll jumps. The single-touch emulation ABS_X/Y is
2790 * accurate but the ABS_MT_POSITION touchpoints report the bounding
2791 * box and that causes jumps. See https://bugzilla.redhat.com/1235175
2792 * Elantech:
2793 * On three-finger taps/clicks, one slot doesn't get a coordinate
2794 * assigned. See https://bugs.freedesktop.org/show_bug.cgi?id=93583
2795 * Alps:
2796 * If three fingers are set down in the same frame, one slot has the
2797 * coordinates 0/0 and may not get updated for several frames.
2798 * See https://bugzilla.redhat.com/show_bug.cgi?id=1295073
2799 *
2800 * The HP Pavilion DM4 touchpad has random jumps in slots, including
2801 * for single-finger movement. See fdo bug 91135
2802 */
2803 if (tp->semi_mt ||
2804 evdev_device_has_model_quirk(tp->device,
2805 QUIRK_MODEL_HP_PAVILION_DM4_TOUCHPAD)) {
2806 tp->num_slots = 1;
2807 tp->slot = 0;
2808 tp->has_mt = false;
2809 }
2810
2811 if (!tp->has_mt)
2812 tp_disable_abs_mt(device);
2813
2814 ARRAY_FOR_EACH(max_touches, m) {
2815 if (libevdev_has_event_code(device->evdev,
2816 EV_KEY,
2817 m->code)) {
2818 n_btn_tool_touches = m->ntouches;
2819 break;
2820 }
2821 }
2822
2823 tp->ntouches = max(tp->num_slots, n_btn_tool_touches);
2824 tp->touches = zalloc(tp->ntouches * sizeof(struct tp_touch));
2825
2826 for (i = 0; i < tp->ntouches; i++)
2827 tp_init_touch(tp, &tp->touches[i], i);
2828
2829 tp_sync_slots(tp, device);
2830
2831 /* Some touchpads don't reset BTN_TOOL_FINGER on touch up and only
2832 * change to/from it when BTN_TOOL_DOUBLETAP is set. This causes us
2833 * to ignore the first touches events until a two-finger gesture is
2834 * performed.
2835 */
2836 if (libevdev_get_event_value(device->evdev, EV_KEY, BTN_TOOL_FINGER))
2837 tp_fake_finger_set(tp, BTN_TOOL_FINGER, 1);
2838
2839 return true;
2840 }
2841
2842 static uint32_t
tp_accel_config_get_profiles(struct libinput_device * libinput_device)2843 tp_accel_config_get_profiles(struct libinput_device *libinput_device)
2844 {
2845 return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
2846 }
2847
2848 static enum libinput_config_status
tp_accel_config_set_profile(struct libinput_device * libinput_device,enum libinput_config_accel_profile profile)2849 tp_accel_config_set_profile(struct libinput_device *libinput_device,
2850 enum libinput_config_accel_profile profile)
2851 {
2852 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
2853 }
2854
2855 static enum libinput_config_accel_profile
tp_accel_config_get_profile(struct libinput_device * libinput_device)2856 tp_accel_config_get_profile(struct libinput_device *libinput_device)
2857 {
2858 return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
2859 }
2860
2861 static enum libinput_config_accel_profile
tp_accel_config_get_default_profile(struct libinput_device * libinput_device)2862 tp_accel_config_get_default_profile(struct libinput_device *libinput_device)
2863 {
2864 return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
2865 }
2866
2867 static bool
tp_init_accel(struct tp_dispatch * tp)2868 tp_init_accel(struct tp_dispatch *tp)
2869 {
2870 struct evdev_device *device = tp->device;
2871 int res_x, res_y;
2872 struct motion_filter *filter;
2873 int dpi = device->dpi;
2874 bool use_v_avg = device->use_velocity_averaging;
2875
2876 res_x = tp->device->abs.absinfo_x->resolution;
2877 res_y = tp->device->abs.absinfo_y->resolution;
2878
2879 /*
2880 * Not all touchpads report the same amount of units/mm (resolution).
2881 * Normalize motion events to the default mouse DPI as base
2882 * (unaccelerated) speed. This also evens out any differences in x
2883 * and y resolution, so that a circle on the
2884 * touchpad does not turn into an elipse on the screen.
2885 */
2886 tp->accel.x_scale_coeff = (DEFAULT_MOUSE_DPI/25.4) / res_x;
2887 tp->accel.y_scale_coeff = (DEFAULT_MOUSE_DPI/25.4) / res_y;
2888 tp->accel.xy_scale_coeff = 1.0 * res_x/res_y;
2889
2890 if (evdev_device_has_model_quirk(device, QUIRK_MODEL_LENOVO_X230) ||
2891 tp->device->model_flags & EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81)
2892 filter = create_pointer_accelerator_filter_lenovo_x230(dpi, use_v_avg);
2893 else if (libevdev_get_id_bustype(device->evdev) == BUS_BLUETOOTH)
2894 filter = create_pointer_accelerator_filter_touchpad(dpi,
2895 ms2us(50),
2896 ms2us(10),
2897 use_v_avg);
2898 else
2899 filter = create_pointer_accelerator_filter_touchpad(dpi, 0, 0, use_v_avg);
2900
2901 if (!filter)
2902 return false;
2903
2904 evdev_device_init_pointer_acceleration(tp->device, filter);
2905
2906 /* we override the profile hooks for accel configuration with hooks
2907 * that don't allow selection of profiles */
2908 device->pointer.config.get_profiles = tp_accel_config_get_profiles;
2909 device->pointer.config.set_profile = tp_accel_config_set_profile;
2910 device->pointer.config.get_profile = tp_accel_config_get_profile;
2911 device->pointer.config.get_default_profile = tp_accel_config_get_default_profile;
2912
2913 return true;
2914 }
2915
2916 static uint32_t
tp_scroll_get_methods(struct tp_dispatch * tp)2917 tp_scroll_get_methods(struct tp_dispatch *tp)
2918 {
2919 uint32_t methods = LIBINPUT_CONFIG_SCROLL_EDGE;
2920
2921 /* Any movement with more than one finger has random cursor
2922 * jumps. Don't allow for 2fg scrolling on this device, see
2923 * fdo bug 91135 */
2924 if (evdev_device_has_model_quirk(tp->device,
2925 QUIRK_MODEL_HP_PAVILION_DM4_TOUCHPAD))
2926 return LIBINPUT_CONFIG_SCROLL_EDGE;
2927
2928 if (tp->ntouches >= 2)
2929 methods |= LIBINPUT_CONFIG_SCROLL_2FG;
2930
2931 return methods;
2932 }
2933
2934 static uint32_t
tp_scroll_config_scroll_method_get_methods(struct libinput_device * device)2935 tp_scroll_config_scroll_method_get_methods(struct libinput_device *device)
2936 {
2937 struct evdev_device *evdev = evdev_device(device);
2938 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
2939
2940 return tp_scroll_get_methods(tp);
2941 }
2942
2943 static enum libinput_config_status
tp_scroll_config_scroll_method_set_method(struct libinput_device * device,enum libinput_config_scroll_method method)2944 tp_scroll_config_scroll_method_set_method(struct libinput_device *device,
2945 enum libinput_config_scroll_method method)
2946 {
2947 struct evdev_device *evdev = evdev_device(device);
2948 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
2949 uint64_t time = libinput_now(tp_libinput_context(tp));
2950
2951 if (method == tp->scroll.method)
2952 return LIBINPUT_CONFIG_STATUS_SUCCESS;
2953
2954 tp_edge_scroll_stop_events(tp, time);
2955 tp_gesture_stop_twofinger_scroll(tp, time);
2956
2957 tp->scroll.method = method;
2958
2959 return LIBINPUT_CONFIG_STATUS_SUCCESS;
2960 }
2961
2962 static enum libinput_config_scroll_method
tp_scroll_config_scroll_method_get_method(struct libinput_device * device)2963 tp_scroll_config_scroll_method_get_method(struct libinput_device *device)
2964 {
2965 struct evdev_device *evdev = evdev_device(device);
2966 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
2967
2968 return tp->scroll.method;
2969 }
2970
2971 static enum libinput_config_scroll_method
tp_scroll_get_default_method(struct tp_dispatch * tp)2972 tp_scroll_get_default_method(struct tp_dispatch *tp)
2973 {
2974 uint32_t methods;
2975 enum libinput_config_scroll_method method;
2976
2977 methods = tp_scroll_get_methods(tp);
2978
2979 if (methods & LIBINPUT_CONFIG_SCROLL_2FG)
2980 method = LIBINPUT_CONFIG_SCROLL_2FG;
2981 else
2982 method = LIBINPUT_CONFIG_SCROLL_EDGE;
2983
2984 if ((methods & method) == 0)
2985 evdev_log_bug_libinput(tp->device,
2986 "invalid default scroll method %d\n",
2987 method);
2988 return method;
2989 }
2990
2991 static enum libinput_config_scroll_method
tp_scroll_config_scroll_method_get_default_method(struct libinput_device * device)2992 tp_scroll_config_scroll_method_get_default_method(struct libinput_device *device)
2993 {
2994 struct evdev_device *evdev = evdev_device(device);
2995 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
2996
2997 return tp_scroll_get_default_method(tp);
2998 }
2999
3000 static void
tp_init_scroll(struct tp_dispatch * tp,struct evdev_device * device)3001 tp_init_scroll(struct tp_dispatch *tp, struct evdev_device *device)
3002 {
3003 tp_edge_scroll_init(tp, device);
3004
3005 evdev_init_natural_scroll(device);
3006
3007 tp->scroll.config_method.get_methods = tp_scroll_config_scroll_method_get_methods;
3008 tp->scroll.config_method.set_method = tp_scroll_config_scroll_method_set_method;
3009 tp->scroll.config_method.get_method = tp_scroll_config_scroll_method_get_method;
3010 tp->scroll.config_method.get_default_method = tp_scroll_config_scroll_method_get_default_method;
3011 tp->scroll.method = tp_scroll_get_default_method(tp);
3012 tp->device->base.config.scroll_method = &tp->scroll.config_method;
3013
3014 /* In mm for touchpads with valid resolution, see tp_init_accel() */
3015 tp->device->scroll.threshold = 0.0;
3016 tp->device->scroll.direction_lock_threshold = 5.0;
3017 }
3018
3019 static int
tp_dwt_config_is_available(struct libinput_device * device)3020 tp_dwt_config_is_available(struct libinput_device *device)
3021 {
3022 return 1;
3023 }
3024
3025 static enum libinput_config_status
tp_dwt_config_set(struct libinput_device * device,enum libinput_config_dwt_state enable)3026 tp_dwt_config_set(struct libinput_device *device,
3027 enum libinput_config_dwt_state enable)
3028 {
3029 struct evdev_device *evdev = evdev_device(device);
3030 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
3031
3032 switch(enable) {
3033 case LIBINPUT_CONFIG_DWT_ENABLED:
3034 case LIBINPUT_CONFIG_DWT_DISABLED:
3035 break;
3036 default:
3037 return LIBINPUT_CONFIG_STATUS_INVALID;
3038 }
3039
3040 tp->dwt.dwt_enabled = (enable == LIBINPUT_CONFIG_DWT_ENABLED);
3041
3042 return LIBINPUT_CONFIG_STATUS_SUCCESS;
3043 }
3044
3045 static enum libinput_config_dwt_state
tp_dwt_config_get(struct libinput_device * device)3046 tp_dwt_config_get(struct libinput_device *device)
3047 {
3048 struct evdev_device *evdev = evdev_device(device);
3049 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
3050
3051 return tp->dwt.dwt_enabled ?
3052 LIBINPUT_CONFIG_DWT_ENABLED :
3053 LIBINPUT_CONFIG_DWT_DISABLED;
3054 }
3055
3056 static bool
tp_dwt_default_enabled(struct tp_dispatch * tp)3057 tp_dwt_default_enabled(struct tp_dispatch *tp)
3058 {
3059 return true;
3060 }
3061
3062 static enum libinput_config_dwt_state
tp_dwt_config_get_default(struct libinput_device * device)3063 tp_dwt_config_get_default(struct libinput_device *device)
3064 {
3065 struct evdev_device *evdev = evdev_device(device);
3066 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
3067
3068 return tp_dwt_default_enabled(tp) ?
3069 LIBINPUT_CONFIG_DWT_ENABLED :
3070 LIBINPUT_CONFIG_DWT_DISABLED;
3071 }
3072
3073 static inline bool
tp_is_tpkb_combo_below(struct evdev_device * device)3074 tp_is_tpkb_combo_below(struct evdev_device *device)
3075 {
3076 struct quirks_context *quirks;
3077 struct quirks *q;
3078 char *prop;
3079 enum tpkbcombo_layout layout = TPKBCOMBO_LAYOUT_UNKNOWN;
3080 int rc = false;
3081
3082 quirks = evdev_libinput_context(device)->quirks;
3083 q = quirks_fetch_for_device(quirks, device->udev_device);
3084 if (!q)
3085 return false;
3086
3087 if (quirks_get_string(q, QUIRK_ATTR_TPKBCOMBO_LAYOUT, &prop)) {
3088 rc = parse_tpkbcombo_layout_poperty(prop, &layout) &&
3089 layout == TPKBCOMBO_LAYOUT_BELOW;
3090 }
3091
3092 quirks_unref(q);
3093
3094 return rc;
3095 }
3096
3097 static inline bool
tp_is_tablet(struct evdev_device * device)3098 tp_is_tablet(struct evdev_device *device)
3099 {
3100 return device->tags & EVDEV_TAG_TABLET_TOUCHPAD;
3101 }
3102
3103 static void
tp_init_dwt(struct tp_dispatch * tp,struct evdev_device * device)3104 tp_init_dwt(struct tp_dispatch *tp,
3105 struct evdev_device *device)
3106 {
3107 if (device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD &&
3108 !tp_is_tpkb_combo_below(device))
3109 return;
3110
3111 tp->dwt.config.is_available = tp_dwt_config_is_available;
3112 tp->dwt.config.set_enabled = tp_dwt_config_set;
3113 tp->dwt.config.get_enabled = tp_dwt_config_get;
3114 tp->dwt.config.get_default_enabled = tp_dwt_config_get_default;
3115 tp->dwt.dwt_enabled = tp_dwt_default_enabled(tp);
3116 device->base.config.dwt = &tp->dwt.config;
3117
3118 return;
3119 }
3120
3121 static inline void
tp_init_palmdetect_edge(struct tp_dispatch * tp,struct evdev_device * device)3122 tp_init_palmdetect_edge(struct tp_dispatch *tp,
3123 struct evdev_device *device)
3124 {
3125 double width, height;
3126 struct phys_coords mm = { 0.0, 0.0 };
3127 struct device_coords edges;
3128
3129 if (device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD &&
3130 !tp_is_tpkb_combo_below(device))
3131 return;
3132
3133 evdev_device_get_size(device, &width, &height);
3134
3135 /* Enable edge palm detection on touchpads >= 70 mm. Anything
3136 smaller probably won't need it, until we find out it does */
3137 if (width < 70.0)
3138 return;
3139
3140 /* palm edges are 8% of the width on each side */
3141 mm.x = min(8, width * 0.08);
3142 edges = evdev_device_mm_to_units(device, &mm);
3143 tp->palm.left_edge = edges.x;
3144
3145 mm.x = width - min(8, width * 0.08);
3146 edges = evdev_device_mm_to_units(device, &mm);
3147 tp->palm.right_edge = edges.x;
3148
3149 if (!tp->buttons.has_topbuttons && height > 55) {
3150 /* top edge is 5% of the height */
3151 mm.y = height * 0.05;
3152 edges = evdev_device_mm_to_units(device, &mm);
3153 tp->palm.upper_edge = edges.y;
3154 }
3155 }
3156
3157 static int
tp_read_palm_pressure_prop(struct tp_dispatch * tp,const struct evdev_device * device)3158 tp_read_palm_pressure_prop(struct tp_dispatch *tp,
3159 const struct evdev_device *device)
3160 {
3161 const int default_palm_threshold = 130;
3162 uint32_t threshold = default_palm_threshold;
3163 struct quirks_context *quirks;
3164 struct quirks *q;
3165
3166 quirks = evdev_libinput_context(device)->quirks;
3167 q = quirks_fetch_for_device(quirks, device->udev_device);
3168 if (!q)
3169 return threshold;
3170
3171 quirks_get_uint32(q, QUIRK_ATTR_PALM_PRESSURE_THRESHOLD, &threshold);
3172 quirks_unref(q);
3173
3174 return threshold;
3175 }
3176
3177 static inline void
tp_init_palmdetect_pressure(struct tp_dispatch * tp,struct evdev_device * device)3178 tp_init_palmdetect_pressure(struct tp_dispatch *tp,
3179 struct evdev_device *device)
3180 {
3181 if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_PRESSURE)) {
3182 tp->palm.use_pressure = false;
3183 return;
3184 }
3185
3186 tp->palm.pressure_threshold = tp_read_palm_pressure_prop(tp, device);
3187 tp->palm.use_pressure = true;
3188
3189 evdev_log_debug(device,
3190 "palm: pressure threshold is %d\n",
3191 tp->palm.pressure_threshold);
3192 }
3193
3194 static inline void
tp_init_palmdetect_size(struct tp_dispatch * tp,struct evdev_device * device)3195 tp_init_palmdetect_size(struct tp_dispatch *tp,
3196 struct evdev_device *device)
3197 {
3198 struct quirks_context *quirks;
3199 struct quirks *q;
3200 uint32_t threshold;
3201
3202 quirks = evdev_libinput_context(device)->quirks;
3203 q = quirks_fetch_for_device(quirks, device->udev_device);
3204 if (!q)
3205 return;
3206
3207 if (quirks_get_uint32(q, QUIRK_ATTR_PALM_SIZE_THRESHOLD, &threshold)) {
3208 if (threshold == 0) {
3209 evdev_log_bug_client(device,
3210 "palm: ignoring invalid threshold %d\n",
3211 threshold);
3212 } else {
3213 tp->palm.use_size = true;
3214 tp->palm.size_threshold = threshold;
3215 }
3216 }
3217 quirks_unref(q);
3218 }
3219
3220 static inline void
tp_init_palmdetect_arbitration(struct tp_dispatch * tp,struct evdev_device * device)3221 tp_init_palmdetect_arbitration(struct tp_dispatch *tp,
3222 struct evdev_device *device)
3223 {
3224 char timer_name[64];
3225
3226 snprintf(timer_name,
3227 sizeof(timer_name),
3228 "%s arbitration",
3229 evdev_device_get_sysname(device));
3230 libinput_timer_init(&tp->arbitration.arbitration_timer,
3231 tp_libinput_context(tp),
3232 timer_name,
3233 tp_arbitration_timeout, tp);
3234 tp->arbitration.in_arbitration = false;
3235 }
3236
3237 static void
tp_init_palmdetect(struct tp_dispatch * tp,struct evdev_device * device)3238 tp_init_palmdetect(struct tp_dispatch *tp,
3239 struct evdev_device *device)
3240 {
3241
3242 tp->palm.right_edge = INT_MAX;
3243 tp->palm.left_edge = INT_MIN;
3244 tp->palm.upper_edge = INT_MIN;
3245
3246 tp_init_palmdetect_arbitration(tp, device);
3247
3248 if (device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD &&
3249 !tp_is_tpkb_combo_below(device) &&
3250 !tp_is_tablet(device))
3251 return;
3252
3253 if (!tp_is_tablet(device))
3254 tp->palm.monitor_trackpoint = true;
3255
3256 if (libevdev_has_event_code(device->evdev,
3257 EV_ABS,
3258 ABS_MT_TOOL_TYPE))
3259 tp->palm.use_mt_tool = true;
3260
3261 if (!tp_is_tablet(device))
3262 tp_init_palmdetect_edge(tp, device);
3263 tp_init_palmdetect_pressure(tp, device);
3264 tp_init_palmdetect_size(tp, device);
3265 }
3266
3267 static void
tp_init_sendevents(struct tp_dispatch * tp,struct evdev_device * device)3268 tp_init_sendevents(struct tp_dispatch *tp,
3269 struct evdev_device *device)
3270 {
3271 char timer_name[64];
3272
3273 snprintf(timer_name,
3274 sizeof(timer_name),
3275 "%s trackpoint",
3276 evdev_device_get_sysname(device));
3277 libinput_timer_init(&tp->palm.trackpoint_timer,
3278 tp_libinput_context(tp),
3279 timer_name,
3280 tp_trackpoint_timeout, tp);
3281
3282 snprintf(timer_name,
3283 sizeof(timer_name),
3284 "%s keyboard",
3285 evdev_device_get_sysname(device));
3286 libinput_timer_init(&tp->dwt.keyboard_timer,
3287 tp_libinput_context(tp),
3288 timer_name,
3289 tp_keyboard_timeout, tp);
3290 }
3291
3292 static void
tp_init_thumb(struct tp_dispatch * tp)3293 tp_init_thumb(struct tp_dispatch *tp)
3294 {
3295 struct evdev_device *device = tp->device;
3296 double w = 0.0, h = 0.0;
3297 struct device_coords edges;
3298 struct phys_coords mm = { 0.0, 0.0 };
3299 uint32_t threshold;
3300 struct quirks_context *quirks;
3301 struct quirks *q;
3302
3303 if (!tp->buttons.is_clickpad)
3304 return;
3305
3306 /* if the touchpad is less than 50mm high, skip thumb detection.
3307 * it's too small to meaningfully interact with a thumb on the
3308 * touchpad */
3309 evdev_device_get_size(device, &w, &h);
3310 if (h < 50)
3311 return;
3312
3313 tp->thumb.detect_thumbs = true;
3314 tp->thumb.use_pressure = false;
3315 tp->thumb.pressure_threshold = INT_MAX;
3316
3317 /* detect thumbs by pressure in the bottom 15mm, detect thumbs by
3318 * lingering in the bottom 8mm */
3319 mm.y = h * 0.85;
3320 edges = evdev_device_mm_to_units(device, &mm);
3321 tp->thumb.upper_thumb_line = edges.y;
3322
3323 mm.y = h * 0.92;
3324 edges = evdev_device_mm_to_units(device, &mm);
3325 tp->thumb.lower_thumb_line = edges.y;
3326
3327 quirks = evdev_libinput_context(device)->quirks;
3328 q = quirks_fetch_for_device(quirks, device->udev_device);
3329
3330 if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_PRESSURE)) {
3331 if (quirks_get_uint32(q,
3332 QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD,
3333 &threshold)) {
3334 tp->thumb.use_pressure = true;
3335 tp->thumb.pressure_threshold = threshold;
3336 }
3337 }
3338
3339 if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_TOUCH_MAJOR)) {
3340 if (quirks_get_uint32(q,
3341 QUIRK_ATTR_THUMB_SIZE_THRESHOLD,
3342 &threshold)) {
3343 tp->thumb.use_size = true;
3344 tp->thumb.size_threshold = threshold;
3345 }
3346 }
3347
3348 quirks_unref(q);
3349
3350 evdev_log_debug(device,
3351 "thumb: enabled thumb detection%s%s\n",
3352 tp->thumb.use_pressure ? " (+pressure)" : "",
3353 tp->thumb.use_size ? " (+size)" : "");
3354 }
3355
3356 static bool
tp_pass_sanity_check(struct tp_dispatch * tp,struct evdev_device * device)3357 tp_pass_sanity_check(struct tp_dispatch *tp,
3358 struct evdev_device *device)
3359 {
3360 struct libevdev *evdev = device->evdev;
3361
3362 if (!libevdev_has_event_code(evdev, EV_ABS, ABS_X))
3363 goto error;
3364
3365 if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOUCH))
3366 goto error;
3367
3368 if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_FINGER))
3369 goto error;
3370
3371 return true;
3372
3373 error:
3374 evdev_log_bug_kernel(device,
3375 "device failed touchpad sanity checks\n");
3376 return false;
3377 }
3378
3379 static void
tp_init_default_resolution(struct tp_dispatch * tp,struct evdev_device * device)3380 tp_init_default_resolution(struct tp_dispatch *tp,
3381 struct evdev_device *device)
3382 {
3383 const int touchpad_width_mm = 69, /* 1 under palm detection */
3384 touchpad_height_mm = 50;
3385 int xres, yres;
3386
3387 if (!device->abs.is_fake_resolution)
3388 return;
3389
3390 /* we only get here if
3391 * - the touchpad provides no resolution
3392 * - the udev hwdb didn't override the resoluion
3393 * - no ATTR_SIZE_HINT is set
3394 *
3395 * The majority of touchpads that triggers all these conditions
3396 * are old ones, so let's assume a small touchpad size and assume
3397 * that.
3398 */
3399 evdev_log_info(device,
3400 "no resolution or size hints, assuming a size of %dx%dmm\n",
3401 touchpad_width_mm,
3402 touchpad_height_mm);
3403
3404 xres = device->abs.dimensions.x/touchpad_width_mm;
3405 yres = device->abs.dimensions.y/touchpad_height_mm;
3406 libevdev_set_abs_resolution(device->evdev, ABS_X, xres);
3407 libevdev_set_abs_resolution(device->evdev, ABS_Y, yres);
3408 libevdev_set_abs_resolution(device->evdev, ABS_MT_POSITION_X, xres);
3409 libevdev_set_abs_resolution(device->evdev, ABS_MT_POSITION_Y, yres);
3410 device->abs.is_fake_resolution = false;
3411 }
3412
3413 static inline void
tp_init_hysteresis(struct tp_dispatch * tp)3414 tp_init_hysteresis(struct tp_dispatch *tp)
3415 {
3416 int xmargin, ymargin;
3417 const struct input_absinfo *ax = tp->device->abs.absinfo_x,
3418 *ay = tp->device->abs.absinfo_y;
3419
3420 if (ax->fuzz)
3421 xmargin = ax->fuzz;
3422 else
3423 xmargin = ax->resolution/4;
3424
3425 if (ay->fuzz)
3426 ymargin = ay->fuzz;
3427 else
3428 ymargin = ay->resolution/4;
3429
3430 tp->hysteresis.margin.x = xmargin;
3431 tp->hysteresis.margin.y = ymargin;
3432 tp->hysteresis.enabled = (ax->fuzz || ay->fuzz);
3433 if (tp->hysteresis.enabled)
3434 evdev_log_debug(tp->device,
3435 "hysteresis enabled. "
3436 "See %stouchpad-jitter.html for details\n",
3437 HTTP_DOC_LINK);
3438 }
3439
3440 static void
tp_init_pressure(struct tp_dispatch * tp,struct evdev_device * device)3441 tp_init_pressure(struct tp_dispatch *tp,
3442 struct evdev_device *device)
3443 {
3444 const struct input_absinfo *abs;
3445 unsigned int code;
3446 struct quirks_context *quirks;
3447 struct quirks *q;
3448 struct quirk_range r;
3449 int hi, lo;
3450
3451 code = tp->has_mt ? ABS_MT_PRESSURE : ABS_PRESSURE;
3452 if (!libevdev_has_event_code(device->evdev, EV_ABS, code)) {
3453 tp->pressure.use_pressure = false;
3454 return;
3455 }
3456
3457 abs = libevdev_get_abs_info(device->evdev, code);
3458 assert(abs);
3459
3460 quirks = evdev_libinput_context(device)->quirks;
3461 q = quirks_fetch_for_device(quirks, device->udev_device);
3462 if (q && quirks_get_range(q, QUIRK_ATTR_PRESSURE_RANGE, &r)) {
3463 hi = r.upper;
3464 lo = r.lower;
3465
3466 if (hi == 0 && lo == 0) {
3467 evdev_log_info(device,
3468 "pressure-based touch detection disabled\n");
3469 goto out;
3470 }
3471 } else {
3472 unsigned int range = abs->maximum - abs->minimum;
3473
3474 /* Approximately the synaptics defaults */
3475 hi = abs->minimum + 0.12 * range;
3476 lo = abs->minimum + 0.10 * range;
3477 }
3478
3479
3480 if (hi > abs->maximum || hi < abs->minimum ||
3481 lo > abs->maximum || lo < abs->minimum) {
3482 evdev_log_bug_libinput(device,
3483 "discarding out-of-bounds pressure range %d:%d\n",
3484 hi, lo);
3485 goto out;
3486 }
3487
3488 tp->pressure.use_pressure = true;
3489 tp->pressure.high = hi;
3490 tp->pressure.low = lo;
3491
3492 evdev_log_debug(device,
3493 "using pressure-based touch detection (%d:%d)\n",
3494 lo,
3495 hi);
3496 out:
3497 quirks_unref(q);
3498 }
3499
3500 static bool
tp_init_touch_size(struct tp_dispatch * tp,struct evdev_device * device)3501 tp_init_touch_size(struct tp_dispatch *tp,
3502 struct evdev_device *device)
3503 {
3504 struct quirks_context *quirks;
3505 struct quirks *q;
3506 struct quirk_range r;
3507 int lo, hi;
3508 int rc = false;
3509
3510 if (!libevdev_has_event_code(device->evdev,
3511 EV_ABS,
3512 ABS_MT_TOUCH_MAJOR)) {
3513 return false;
3514 }
3515
3516 quirks = evdev_libinput_context(device)->quirks;
3517 q = quirks_fetch_for_device(quirks, device->udev_device);
3518 if (q && quirks_get_range(q, QUIRK_ATTR_TOUCH_SIZE_RANGE, &r)) {
3519 hi = r.upper;
3520 lo = r.lower;
3521 } else {
3522 goto out;
3523 }
3524
3525 if (libevdev_get_num_slots(device->evdev) < 5) {
3526 evdev_log_bug_libinput(device,
3527 "Expected 5+ slots for touch size detection\n");
3528 goto out;
3529 }
3530
3531 if (hi == 0 && lo == 0) {
3532 evdev_log_info(device,
3533 "touch size based touch detection disabled\n");
3534 goto out;
3535 }
3536
3537 /* Thresholds apply for both major or minor */
3538 tp->touch_size.low = lo;
3539 tp->touch_size.high = hi;
3540 tp->touch_size.use_touch_size = true;
3541
3542 evdev_log_debug(device,
3543 "using size-based touch detection (%d:%d)\n",
3544 hi, lo);
3545
3546 rc = true;
3547 out:
3548 quirks_unref(q);
3549 return rc;
3550 }
3551
3552 static int
tp_init(struct tp_dispatch * tp,struct evdev_device * device)3553 tp_init(struct tp_dispatch *tp,
3554 struct evdev_device *device)
3555 {
3556 bool use_touch_size = false;
3557
3558 tp->base.dispatch_type = DISPATCH_TOUCHPAD;
3559 tp->base.interface = &tp_interface;
3560 tp->device = device;
3561 list_init(&tp->dwt.paired_keyboard_list);
3562
3563 if (!tp_pass_sanity_check(tp, device))
3564 return false;
3565
3566 tp_init_default_resolution(tp, device);
3567
3568 if (!tp_init_slots(tp, device))
3569 return false;
3570
3571 evdev_device_init_abs_range_warnings(device);
3572 use_touch_size = tp_init_touch_size(tp, device);
3573
3574 if (!use_touch_size)
3575 tp_init_pressure(tp, device);
3576
3577 /* Set the dpi to that of the x axis, because that's what we normalize
3578 to when needed*/
3579 device->dpi = device->abs.absinfo_x->resolution * 25.4;
3580
3581 tp_init_hysteresis(tp);
3582
3583 if (!tp_init_accel(tp))
3584 return false;
3585
3586 tp_init_tap(tp);
3587 tp_init_buttons(tp, device);
3588 tp_init_dwt(tp, device);
3589 tp_init_palmdetect(tp, device);
3590 tp_init_sendevents(tp, device);
3591 tp_init_scroll(tp, device);
3592 tp_init_gesture(tp);
3593 tp_init_thumb(tp);
3594
3595 device->seat_caps |= EVDEV_DEVICE_POINTER;
3596 if (tp->gesture.enabled)
3597 device->seat_caps |= EVDEV_DEVICE_GESTURE;
3598
3599 return true;
3600 }
3601
3602 static uint32_t
tp_sendevents_get_modes(struct libinput_device * device)3603 tp_sendevents_get_modes(struct libinput_device *device)
3604 {
3605 struct evdev_device *evdev = evdev_device(device);
3606 uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
3607
3608 if (evdev->tags & EVDEV_TAG_INTERNAL_TOUCHPAD)
3609 modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
3610
3611 return modes;
3612 }
3613
3614 static void
tp_suspend_conditional(struct tp_dispatch * tp,struct evdev_device * device)3615 tp_suspend_conditional(struct tp_dispatch *tp,
3616 struct evdev_device *device)
3617 {
3618 struct libinput_device *dev;
3619
3620 list_for_each(dev, &device->base.seat->devices_list, link) {
3621 struct evdev_device *d = evdev_device(dev);
3622 if (d->tags & EVDEV_TAG_EXTERNAL_MOUSE) {
3623 tp_suspend(tp, device, SUSPEND_EXTERNAL_MOUSE);
3624 break;
3625 }
3626 }
3627 }
3628
3629 static enum libinput_config_status
tp_sendevents_set_mode(struct libinput_device * device,enum libinput_config_send_events_mode mode)3630 tp_sendevents_set_mode(struct libinput_device *device,
3631 enum libinput_config_send_events_mode mode)
3632 {
3633 struct evdev_device *evdev = evdev_device(device);
3634 struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
3635
3636 /* DISABLED overrides any DISABLED_ON_ */
3637 if ((mode & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED) &&
3638 (mode & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE))
3639 mode &= ~LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
3640
3641 if (mode == tp->sendevents.current_mode)
3642 return LIBINPUT_CONFIG_STATUS_SUCCESS;
3643
3644 switch(mode) {
3645 case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
3646 tp_resume(tp, evdev, SUSPEND_SENDEVENTS);
3647 tp_resume(tp, evdev, SUSPEND_EXTERNAL_MOUSE);
3648 break;
3649 case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
3650 tp_suspend(tp, evdev, SUSPEND_SENDEVENTS);
3651 tp_resume(tp, evdev, SUSPEND_EXTERNAL_MOUSE);
3652 break;
3653 case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
3654 tp_suspend_conditional(tp, evdev);
3655 tp_resume(tp, evdev, SUSPEND_SENDEVENTS);
3656 break;
3657 default:
3658 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
3659 }
3660
3661 tp->sendevents.current_mode = mode;
3662
3663 return LIBINPUT_CONFIG_STATUS_SUCCESS;
3664 }
3665
3666 static enum libinput_config_send_events_mode
tp_sendevents_get_mode(struct libinput_device * device)3667 tp_sendevents_get_mode(struct libinput_device *device)
3668 {
3669 struct evdev_device *evdev = evdev_device(device);
3670 struct tp_dispatch *dispatch = (struct tp_dispatch*)evdev->dispatch;
3671
3672 return dispatch->sendevents.current_mode;
3673 }
3674
3675 static enum libinput_config_send_events_mode
tp_sendevents_get_default_mode(struct libinput_device * device)3676 tp_sendevents_get_default_mode(struct libinput_device *device)
3677 {
3678 return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
3679 }
3680
3681 static void
tp_change_to_left_handed(struct evdev_device * device)3682 tp_change_to_left_handed(struct evdev_device *device)
3683 {
3684 struct tp_dispatch *tp = (struct tp_dispatch *)device->dispatch;
3685
3686 if (device->left_handed.want_enabled == device->left_handed.enabled)
3687 return;
3688
3689 if (tp->buttons.state & 0x3) /* BTN_LEFT|BTN_RIGHT */
3690 return;
3691
3692 /* tapping and clickfinger aren't affected by left-handed config,
3693 * so checking physical buttons is enough */
3694
3695 device->left_handed.enabled = device->left_handed.want_enabled;
3696 }
3697
3698 struct evdev_dispatch *
evdev_mt_touchpad_create(struct evdev_device * device)3699 evdev_mt_touchpad_create(struct evdev_device *device)
3700 {
3701 struct tp_dispatch *tp;
3702 bool want_left_handed = true;
3703
3704 evdev_tag_touchpad(device, device->udev_device);
3705
3706 tp = zalloc(sizeof *tp);
3707
3708 if (!tp_init(tp, device)) {
3709 tp_interface_destroy(&tp->base);
3710 return NULL;
3711 }
3712
3713 device->base.config.sendevents = &tp->sendevents.config;
3714
3715 tp->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
3716 tp->sendevents.config.get_modes = tp_sendevents_get_modes;
3717 tp->sendevents.config.set_mode = tp_sendevents_set_mode;
3718 tp->sendevents.config.get_mode = tp_sendevents_get_mode;
3719 tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode;
3720
3721 if (device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON)
3722 want_left_handed = false;
3723 if (want_left_handed)
3724 evdev_init_left_handed(device, tp_change_to_left_handed);
3725
3726 return &tp->base;
3727 }
3728