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