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