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