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 <limits.h>
27 #include <math.h>
28 #include <string.h>
29 #include "linux/input.h"
30 
31 #include "util-input-event.h"
32 #include "evdev-mt-touchpad.h"
33 
34 #define DEFAULT_BUTTON_ENTER_TIMEOUT ms2us(100)
35 #define DEFAULT_BUTTON_LEAVE_TIMEOUT ms2us(300)
36 
37 /*****************************************
38  * BEFORE YOU EDIT THIS FILE, look at the state diagram in
39  * doc/touchpad-softbutton-state-machine.svg (generated with
40  * https://www.diagrams.net).
41  * Any changes in this file must be represented in the diagram.
42  *
43  * The state machine only affects the soft button area code.
44  */
45 
46 static inline const char*
button_state_to_str(enum button_state state)47 button_state_to_str(enum button_state state)
48 {
49 	switch(state) {
50 	CASE_RETURN_STRING(BUTTON_STATE_NONE);
51 	CASE_RETURN_STRING(BUTTON_STATE_AREA);
52 	CASE_RETURN_STRING(BUTTON_STATE_BOTTOM);
53 	CASE_RETURN_STRING(BUTTON_STATE_TOP);
54 	CASE_RETURN_STRING(BUTTON_STATE_TOP_NEW);
55 	CASE_RETURN_STRING(BUTTON_STATE_TOP_TO_IGNORE);
56 	CASE_RETURN_STRING(BUTTON_STATE_IGNORE);
57 	}
58 	return NULL;
59 }
60 
61 static inline const char*
button_event_to_str(enum button_event event)62 button_event_to_str(enum button_event event)
63 {
64 	switch(event) {
65 	CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_R);
66 	CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_M);
67 	CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_L);
68 	CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_R);
69 	CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_M);
70 	CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_L);
71 	CASE_RETURN_STRING(BUTTON_EVENT_IN_AREA);
72 	CASE_RETURN_STRING(BUTTON_EVENT_UP);
73 	CASE_RETURN_STRING(BUTTON_EVENT_PRESS);
74 	CASE_RETURN_STRING(BUTTON_EVENT_RELEASE);
75 	CASE_RETURN_STRING(BUTTON_EVENT_TIMEOUT);
76 	}
77 	return NULL;
78 }
79 
80 static inline bool
is_inside_bottom_button_area(const struct tp_dispatch *tp, const struct tp_touch *t)81 is_inside_bottom_button_area(const struct tp_dispatch *tp,
82 			     const struct tp_touch *t)
83 {
84 	return t->point.y >= tp->buttons.bottom_area.top_edge;
85 }
86 
87 static inline bool
is_inside_bottom_right_area(const struct tp_dispatch *tp, const struct tp_touch *t)88 is_inside_bottom_right_area(const struct tp_dispatch *tp,
89 			    const struct tp_touch *t)
90 {
91 	return is_inside_bottom_button_area(tp, t) &&
92 	       t->point.x > tp->buttons.bottom_area.rightbutton_left_edge;
93 }
94 
95 static inline bool
is_inside_bottom_middle_area(const struct tp_dispatch *tp, const struct tp_touch *t)96 is_inside_bottom_middle_area(const struct tp_dispatch *tp,
97 			   const struct tp_touch *t)
98 {
99 	return is_inside_bottom_button_area(tp, t) &&
100 	       !is_inside_bottom_right_area(tp, t) &&
101 	       t->point.x > tp->buttons.bottom_area.middlebutton_left_edge;
102 }
103 
104 static inline bool
is_inside_top_button_area(const struct tp_dispatch *tp, const struct tp_touch *t)105 is_inside_top_button_area(const struct tp_dispatch *tp,
106 			  const struct tp_touch *t)
107 {
108 	return t->point.y <= tp->buttons.top_area.bottom_edge;
109 }
110 
111 static inline bool
is_inside_top_right_area(const struct tp_dispatch *tp, const struct tp_touch *t)112 is_inside_top_right_area(const struct tp_dispatch *tp,
113 			 const struct tp_touch *t)
114 {
115 	return is_inside_top_button_area(tp, t) &&
116 	       t->point.x > tp->buttons.top_area.rightbutton_left_edge;
117 }
118 
119 static inline bool
is_inside_top_middle_area(const struct tp_dispatch *tp, const struct tp_touch *t)120 is_inside_top_middle_area(const struct tp_dispatch *tp,
121 			  const struct tp_touch *t)
122 {
123 	return is_inside_top_button_area(tp, t) &&
124 	       t->point.x >= tp->buttons.top_area.leftbutton_right_edge &&
125 	       t->point.x <= tp->buttons.top_area.rightbutton_left_edge;
126 }
127 
128 static void
tp_button_set_enter_timer(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)129 tp_button_set_enter_timer(struct tp_dispatch *tp,
130 			  struct tp_touch *t,
131 			  uint64_t time)
132 {
133 	libinput_timer_set(&t->button.timer,
134 			   time + DEFAULT_BUTTON_ENTER_TIMEOUT);
135 }
136 
137 static void
tp_button_set_leave_timer(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)138 tp_button_set_leave_timer(struct tp_dispatch *tp,
139 			  struct tp_touch *t,
140 			  uint64_t time)
141 {
142 	libinput_timer_set(&t->button.timer,
143 			   time + DEFAULT_BUTTON_LEAVE_TIMEOUT);
144 }
145 
146 /*
147  * tp_button_set_state, change state and implement on-entry behavior
148  * as described in the state machine diagram.
149  */
150 static void
tp_button_set_state(struct tp_dispatch *tp, struct tp_touch *t, enum button_state new_state, enum button_event event, uint64_t time)151 tp_button_set_state(struct tp_dispatch *tp,
152 		    struct tp_touch *t,
153 		    enum button_state new_state,
154 		    enum button_event event,
155 		    uint64_t time)
156 {
157 	libinput_timer_cancel(&t->button.timer);
158 
159 	t->button.state = new_state;
160 
161 	switch (t->button.state) {
162 	case BUTTON_STATE_NONE:
163 		t->button.current = 0;
164 		break;
165 	case BUTTON_STATE_AREA:
166 		t->button.current = BUTTON_EVENT_IN_AREA;
167 		break;
168 	case BUTTON_STATE_BOTTOM:
169 		t->button.current = event;
170 		break;
171 	case BUTTON_STATE_TOP:
172 		break;
173 	case BUTTON_STATE_TOP_NEW:
174 		t->button.current = event;
175 		tp_button_set_enter_timer(tp, t, time);
176 		break;
177 	case BUTTON_STATE_TOP_TO_IGNORE:
178 		tp_button_set_leave_timer(tp, t, time);
179 		break;
180 	case BUTTON_STATE_IGNORE:
181 		t->button.current = 0;
182 		break;
183 	}
184 }
185 
186 static void
tp_button_none_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)187 tp_button_none_handle_event(struct tp_dispatch *tp,
188 			    struct tp_touch *t,
189 			    enum button_event event,
190 			    uint64_t time)
191 {
192 	switch (event) {
193 	case BUTTON_EVENT_IN_BOTTOM_R:
194 	case BUTTON_EVENT_IN_BOTTOM_M:
195 	case BUTTON_EVENT_IN_BOTTOM_L:
196 		tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event, time);
197 		break;
198 	case BUTTON_EVENT_IN_TOP_R:
199 	case BUTTON_EVENT_IN_TOP_M:
200 	case BUTTON_EVENT_IN_TOP_L:
201 		tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW, event, time);
202 		break;
203 	case BUTTON_EVENT_IN_AREA:
204 		tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
205 		break;
206 	case BUTTON_EVENT_UP:
207 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
208 		break;
209 	case BUTTON_EVENT_PRESS:
210 	case BUTTON_EVENT_RELEASE:
211 	case BUTTON_EVENT_TIMEOUT:
212 		break;
213 	}
214 }
215 
216 static void
tp_button_area_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)217 tp_button_area_handle_event(struct tp_dispatch *tp,
218 			    struct tp_touch *t,
219 			    enum button_event event,
220 			    uint64_t time)
221 {
222 	switch (event) {
223 	case BUTTON_EVENT_IN_BOTTOM_R:
224 	case BUTTON_EVENT_IN_BOTTOM_M:
225 	case BUTTON_EVENT_IN_BOTTOM_L:
226 	case BUTTON_EVENT_IN_TOP_R:
227 	case BUTTON_EVENT_IN_TOP_M:
228 	case BUTTON_EVENT_IN_TOP_L:
229 	case BUTTON_EVENT_IN_AREA:
230 		break;
231 	case BUTTON_EVENT_UP:
232 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
233 		break;
234 	case BUTTON_EVENT_PRESS:
235 	case BUTTON_EVENT_RELEASE:
236 	case BUTTON_EVENT_TIMEOUT:
237 		break;
238 	}
239 }
240 
241 /**
242  * Release any button in the bottom area, provided it started within a
243  * threshold around start_time (i.e. simultaneously with the other touch
244  * that triggered this call).
245  */
246 static inline void
tp_button_release_other_bottom_touches(struct tp_dispatch *tp, uint64_t other_start_time)247 tp_button_release_other_bottom_touches(struct tp_dispatch *tp,
248 				       uint64_t other_start_time)
249 {
250 	struct tp_touch *t;
251 
252 	tp_for_each_touch(tp, t) {
253 		uint64_t tdelta;
254 
255 		if (t->button.state != BUTTON_STATE_BOTTOM ||
256 		    t->button.has_moved)
257 			continue;
258 
259 		if (other_start_time > t->button.initial_time)
260 			tdelta = other_start_time - t->button.initial_time;
261 		else
262 			tdelta = t->button.initial_time - other_start_time;
263 
264 		if (tdelta > ms2us(80))
265 			continue;
266 
267 		t->button.has_moved = true;
268 	}
269 }
270 
271 static void
tp_button_bottom_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)272 tp_button_bottom_handle_event(struct tp_dispatch *tp,
273 			      struct tp_touch *t,
274 			      enum button_event event,
275 			      uint64_t time)
276 {
277 	switch (event) {
278 	case BUTTON_EVENT_IN_BOTTOM_R:
279 	case BUTTON_EVENT_IN_BOTTOM_M:
280 	case BUTTON_EVENT_IN_BOTTOM_L:
281 		if (event != t->button.current)
282 			tp_button_set_state(tp,
283 					    t,
284 					    BUTTON_STATE_BOTTOM,
285 					    event,
286 					    time);
287 		break;
288 	case BUTTON_EVENT_IN_TOP_R:
289 	case BUTTON_EVENT_IN_TOP_M:
290 	case BUTTON_EVENT_IN_TOP_L:
291 	case BUTTON_EVENT_IN_AREA:
292 		tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
293 
294 		/* We just transitioned one finger from BOTTOM to AREA,
295 		 * if there are other fingers in BOTTOM that started
296 		 * simultaneously with this finger, release those fingers
297 		 * because they're part of a gesture.
298 		 */
299 		tp_button_release_other_bottom_touches(tp,
300 						       t->button.initial_time);
301 		break;
302 	case BUTTON_EVENT_UP:
303 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
304 		break;
305 	case BUTTON_EVENT_PRESS:
306 	case BUTTON_EVENT_RELEASE:
307 	case BUTTON_EVENT_TIMEOUT:
308 		break;
309 	}
310 }
311 
312 static void
tp_button_top_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)313 tp_button_top_handle_event(struct tp_dispatch *tp,
314 			   struct tp_touch *t,
315 			   enum button_event event,
316 			   uint64_t time)
317 {
318 	switch (event) {
319 	case BUTTON_EVENT_IN_BOTTOM_R:
320 	case BUTTON_EVENT_IN_BOTTOM_M:
321 	case BUTTON_EVENT_IN_BOTTOM_L:
322 		tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event, time);
323 		break;
324 	case BUTTON_EVENT_IN_TOP_R:
325 	case BUTTON_EVENT_IN_TOP_M:
326 	case BUTTON_EVENT_IN_TOP_L:
327 		if (event != t->button.current)
328 			tp_button_set_state(tp,
329 					    t,
330 					    BUTTON_STATE_TOP_NEW,
331 					    event,
332 					    time);
333 		break;
334 	case BUTTON_EVENT_IN_AREA:
335 		tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event, time);
336 		break;
337 	case BUTTON_EVENT_UP:
338 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
339 		break;
340 	case BUTTON_EVENT_PRESS:
341 	case BUTTON_EVENT_RELEASE:
342 	case BUTTON_EVENT_TIMEOUT:
343 		break;
344 	}
345 }
346 
347 static void
tp_button_top_new_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)348 tp_button_top_new_handle_event(struct tp_dispatch *tp,
349 			       struct tp_touch *t,
350 			       enum button_event event,
351 			       uint64_t time)
352 {
353 	switch(event) {
354 	case BUTTON_EVENT_IN_BOTTOM_R:
355 	case BUTTON_EVENT_IN_BOTTOM_M:
356 	case BUTTON_EVENT_IN_BOTTOM_L:
357 		tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
358 		break;
359 	case BUTTON_EVENT_IN_TOP_R:
360 	case BUTTON_EVENT_IN_TOP_M:
361 	case BUTTON_EVENT_IN_TOP_L:
362 		if (event != t->button.current)
363 			tp_button_set_state(tp,
364 					    t,
365 					    BUTTON_STATE_TOP_NEW,
366 					    event,
367 					    time);
368 		break;
369 	case BUTTON_EVENT_IN_AREA:
370 		tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
371 		break;
372 	case BUTTON_EVENT_UP:
373 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
374 		break;
375 	case BUTTON_EVENT_PRESS:
376 		tp_button_set_state(tp, t, BUTTON_STATE_TOP, event, time);
377 		break;
378 	case BUTTON_EVENT_RELEASE:
379 		break;
380 	case BUTTON_EVENT_TIMEOUT:
381 		tp_button_set_state(tp, t, BUTTON_STATE_TOP, event, time);
382 		break;
383 	}
384 }
385 
386 static void
tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)387 tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
388 				     struct tp_touch *t,
389 				     enum button_event event,
390 				     uint64_t time)
391 {
392 	switch(event) {
393 	case BUTTON_EVENT_IN_TOP_R:
394 	case BUTTON_EVENT_IN_TOP_M:
395 	case BUTTON_EVENT_IN_TOP_L:
396 		if (event == t->button.current)
397 			tp_button_set_state(tp,
398 					    t,
399 					    BUTTON_STATE_TOP,
400 					    event,
401 					    time);
402 		else
403 			tp_button_set_state(tp,
404 					    t,
405 					    BUTTON_STATE_TOP_NEW,
406 					    event,
407 					    time);
408 		break;
409 	case BUTTON_EVENT_IN_BOTTOM_R:
410 	case BUTTON_EVENT_IN_BOTTOM_M:
411 	case BUTTON_EVENT_IN_BOTTOM_L:
412 	case BUTTON_EVENT_IN_AREA:
413 		break;
414 	case BUTTON_EVENT_UP:
415 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
416 		break;
417 	case BUTTON_EVENT_PRESS:
418 	case BUTTON_EVENT_RELEASE:
419 		break;
420 	case BUTTON_EVENT_TIMEOUT:
421 		tp_button_set_state(tp, t, BUTTON_STATE_IGNORE, event, time);
422 		break;
423 	}
424 }
425 
426 static void
tp_button_ignore_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)427 tp_button_ignore_handle_event(struct tp_dispatch *tp,
428 			      struct tp_touch *t,
429 			      enum button_event event,
430 			      uint64_t time)
431 {
432 	switch (event) {
433 	case BUTTON_EVENT_IN_BOTTOM_R:
434 	case BUTTON_EVENT_IN_BOTTOM_M:
435 	case BUTTON_EVENT_IN_BOTTOM_L:
436 	case BUTTON_EVENT_IN_TOP_R:
437 	case BUTTON_EVENT_IN_TOP_M:
438 	case BUTTON_EVENT_IN_TOP_L:
439 	case BUTTON_EVENT_IN_AREA:
440 		break;
441 	case BUTTON_EVENT_UP:
442 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
443 		break;
444 	case BUTTON_EVENT_PRESS:
445 		t->button.current = BUTTON_EVENT_IN_AREA;
446 		break;
447 	case BUTTON_EVENT_RELEASE:
448 		break;
449 	case BUTTON_EVENT_TIMEOUT:
450 		break;
451 	}
452 }
453 
454 static void
tp_button_handle_event(struct tp_dispatch *tp, struct tp_touch *t, enum button_event event, uint64_t time)455 tp_button_handle_event(struct tp_dispatch *tp,
456 		       struct tp_touch *t,
457 		       enum button_event event,
458 		       uint64_t time)
459 {
460 	enum button_state current = t->button.state;
461 
462 	switch(t->button.state) {
463 	case BUTTON_STATE_NONE:
464 		tp_button_none_handle_event(tp, t, event, time);
465 		break;
466 	case BUTTON_STATE_AREA:
467 		tp_button_area_handle_event(tp, t, event, time);
468 		break;
469 	case BUTTON_STATE_BOTTOM:
470 		tp_button_bottom_handle_event(tp, t, event, time);
471 		break;
472 	case BUTTON_STATE_TOP:
473 		tp_button_top_handle_event(tp, t, event, time);
474 		break;
475 	case BUTTON_STATE_TOP_NEW:
476 		tp_button_top_new_handle_event(tp, t, event, time);
477 		break;
478 	case BUTTON_STATE_TOP_TO_IGNORE:
479 		tp_button_top_to_ignore_handle_event(tp, t, event, time);
480 		break;
481 	case BUTTON_STATE_IGNORE:
482 		tp_button_ignore_handle_event(tp, t, event, time);
483 		break;
484 	}
485 
486 	if (current != t->button.state)
487 		evdev_log_debug(tp->device,
488 				"button state: touch %d from %-20s event %-24s to %-20s\n",
489 				t->index,
490 				button_state_to_str(current),
491 				button_event_to_str(event),
492 				button_state_to_str(t->button.state));
493 }
494 
495 static inline void
tp_button_check_for_movement(struct tp_dispatch *tp, struct tp_touch *t)496 tp_button_check_for_movement(struct tp_dispatch *tp, struct tp_touch *t)
497 {
498 	struct device_coords delta;
499 	struct phys_coords mm;
500 	double vector_length;
501 
502 	if (t->button.has_moved)
503 		return;
504 
505 	switch (t->button.state) {
506 	case BUTTON_STATE_NONE:
507 	case BUTTON_STATE_AREA:
508 	case BUTTON_STATE_TOP:
509 	case BUTTON_STATE_TOP_NEW:
510 	case BUTTON_STATE_TOP_TO_IGNORE:
511 	case BUTTON_STATE_IGNORE:
512 		/* No point calculating if we're not going to use it */
513 		return;
514 	case BUTTON_STATE_BOTTOM:
515 		break;
516 	}
517 
518 	delta.x = t->point.x - t->button.initial.x;
519 	delta.y = t->point.y - t->button.initial.y;
520 	mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
521 	vector_length = hypot(mm.x, mm.y);
522 
523 	if (vector_length > 5.0 /* mm */) {
524 		t->button.has_moved = true;
525 
526 		tp_button_release_other_bottom_touches(tp,
527 						       t->button.initial_time);
528 	}
529 }
530 
531 void
tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)532 tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
533 {
534 	struct tp_touch *t;
535 
536 	tp_for_each_touch(tp, t) {
537 		if (t->state == TOUCH_NONE || t->state == TOUCH_HOVERING)
538 			continue;
539 
540 		if (t->state == TOUCH_BEGIN) {
541 			t->button.initial = t->point;
542 			t->button.initial_time = time;
543 			t->button.has_moved = false;
544 		}
545 
546 		if (t->state == TOUCH_END) {
547 			tp_button_handle_event(tp, t, BUTTON_EVENT_UP, time);
548 		} else if (t->dirty) {
549 			enum button_event event;
550 
551 			if (is_inside_bottom_button_area(tp, t)) {
552 				if (is_inside_bottom_right_area(tp, t))
553 					event = BUTTON_EVENT_IN_BOTTOM_R;
554 				else if (is_inside_bottom_middle_area(tp, t))
555 					event = BUTTON_EVENT_IN_BOTTOM_M;
556 				else
557 					event = BUTTON_EVENT_IN_BOTTOM_L;
558 
559 				/* In the bottom area we check for movement
560 				 * within the area. Top area - meh */
561 				tp_button_check_for_movement(tp, t);
562 			} else if (is_inside_top_button_area(tp, t)) {
563 				if (is_inside_top_right_area(tp, t))
564 					event = BUTTON_EVENT_IN_TOP_R;
565 				else if (is_inside_top_middle_area(tp, t))
566 					event = BUTTON_EVENT_IN_TOP_M;
567 				else
568 					event = BUTTON_EVENT_IN_TOP_L;
569 			} else {
570 				event = BUTTON_EVENT_IN_AREA;
571 			}
572 
573 			tp_button_handle_event(tp, t, event, time);
574 		}
575 		if (tp->queued & TOUCHPAD_EVENT_BUTTON_RELEASE)
576 			tp_button_handle_event(tp, t, BUTTON_EVENT_RELEASE, time);
577 		if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
578 			tp_button_handle_event(tp, t, BUTTON_EVENT_PRESS, time);
579 	}
580 }
581 
582 static void
tp_button_handle_timeout(uint64_t now, void *data)583 tp_button_handle_timeout(uint64_t now, void *data)
584 {
585 	struct tp_touch *t = data;
586 
587 	tp_button_handle_event(t->tp, t, BUTTON_EVENT_TIMEOUT, now);
588 }
589 
590 void
tp_process_button(struct tp_dispatch *tp, const struct input_event *e, uint64_t time)591 tp_process_button(struct tp_dispatch *tp,
592 		  const struct input_event *e,
593 		  uint64_t time)
594 {
595 	uint32_t mask = bit(e->code - BTN_LEFT);
596 
597 	/* Ignore other buttons on clickpads */
598 	if (tp->buttons.is_clickpad && e->code != BTN_LEFT) {
599 		evdev_log_bug_kernel(tp->device,
600 				     "received %s button event on a clickpad\n",
601 				     libevdev_event_code_get_name(EV_KEY, e->code));
602 		return;
603 	}
604 
605 	if (e->value) {
606 		tp->buttons.state |= mask;
607 		tp->queued |= TOUCHPAD_EVENT_BUTTON_PRESS;
608 	} else {
609 		tp->buttons.state &= ~mask;
610 		tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
611 	}
612 }
613 
614 void
tp_release_all_buttons(struct tp_dispatch *tp, uint64_t time)615 tp_release_all_buttons(struct tp_dispatch *tp,
616 		       uint64_t time)
617 {
618 	if (tp->buttons.state) {
619 		tp->buttons.state = 0;
620 		tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
621 	}
622 }
623 
624 static void
tp_init_softbuttons(struct tp_dispatch *tp, struct evdev_device *device)625 tp_init_softbuttons(struct tp_dispatch *tp,
626 		    struct evdev_device *device)
627 {
628 	double width, height;
629 	struct device_coords edges;
630 	int mb_le, mb_re; /* middle button left/right edge */
631 	struct phys_coords mm = { 0.0, 0.0 };
632 
633 	evdev_device_get_size(device, &width, &height);
634 
635 	/* button height: 10mm or 15% or the touchpad height,
636 	   whichever is smaller */
637 	if (height * 0.15 > 10)
638 		mm.y = height - 10;
639 	else
640 		mm.y = height * 0.85;
641 
642 	mm.x = width * 0.5;
643 	edges = evdev_device_mm_to_units(device, &mm);
644 	tp->buttons.bottom_area.top_edge = edges.y;
645 	tp->buttons.bottom_area.rightbutton_left_edge = edges.x;
646 
647 	tp->buttons.bottom_area.middlebutton_left_edge = INT_MAX;
648 
649 	/* if middlebutton emulation is enabled, don't init a software area */
650 	if (device->middlebutton.want_enabled)
651 		return;
652 
653 	/* The middle button is 25% of the touchpad and centered. Many
654 	 * touchpads don't have markings for the middle button at all so we
655 	 * need to make it big enough to reliably hit it but not too big so
656 	 * it takes away all the space.
657 	 *
658 	 * On touchpads with visible markings we reduce the size of the
659 	 * middle button since users have a visual guide.
660 	 */
661 	if (evdev_device_has_model_quirk(device,
662 					 QUIRK_MODEL_TOUCHPAD_VISIBLE_MARKER)) {
663 		mm.x = width/2 - 5; /* 10mm wide */
664 		edges = evdev_device_mm_to_units(device, &mm);
665 		mb_le = edges.x;
666 
667 		mm.x = width/2 + 5; /* 10mm wide */
668 		edges = evdev_device_mm_to_units(device, &mm);
669 		mb_re = edges.x;
670 	} else {
671 		mm.x = width * 0.375;
672 		edges = evdev_device_mm_to_units(device, &mm);
673 		mb_le = edges.x;
674 
675 		mm.x = width * 0.625;
676 		edges = evdev_device_mm_to_units(device, &mm);
677 		mb_re = edges.x;
678 	}
679 
680 	tp->buttons.bottom_area.middlebutton_left_edge = mb_le;
681 	tp->buttons.bottom_area.rightbutton_left_edge = mb_re;
682 }
683 
684 void
tp_init_top_softbuttons(struct tp_dispatch *tp, struct evdev_device *device, double topbutton_size_mult)685 tp_init_top_softbuttons(struct tp_dispatch *tp,
686 			struct evdev_device *device,
687 			double topbutton_size_mult)
688 {
689 	struct device_coords edges;
690 
691 	if (tp->buttons.has_topbuttons) {
692 		/* T440s has the top button line 5mm from the top, event
693 		   analysis has shown events to start down to ~10mm from the
694 		   top - which maps to 15%.  We allow the caller to enlarge the
695 		   area using a multiplier for the touchpad disabled case. */
696 		double topsize_mm = 10 * topbutton_size_mult;
697 		struct phys_coords mm;
698 		double width, height;
699 
700 		evdev_device_get_size(device, &width, &height);
701 
702 		mm.x = width * 0.60;
703 		mm.y = topsize_mm;
704 		edges = evdev_device_mm_to_units(device, &mm);
705 		tp->buttons.top_area.bottom_edge = edges.y;
706 		tp->buttons.top_area.rightbutton_left_edge = edges.x;
707 
708 		mm.x = width * 0.40;
709 		edges = evdev_device_mm_to_units(device, &mm);
710 		tp->buttons.top_area.leftbutton_right_edge = edges.x;
711 	} else {
712 		tp->buttons.top_area.bottom_edge = INT_MIN;
713 	}
714 }
715 
716 static inline uint32_t
tp_button_config_click_get_methods(struct libinput_device *device)717 tp_button_config_click_get_methods(struct libinput_device *device)
718 {
719 	struct evdev_device *evdev = evdev_device(device);
720 	struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
721 	uint32_t methods = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
722 
723 	if (tp->buttons.is_clickpad) {
724 		methods |= LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
725 		if (tp->has_mt)
726 			methods |= LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
727 	}
728 
729 	if (evdev->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON)
730 		methods |= LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
731 
732 	return methods;
733 }
734 
735 static void
tp_switch_click_method(struct tp_dispatch *tp)736 tp_switch_click_method(struct tp_dispatch *tp)
737 {
738 	/*
739 	 * All we need to do when switching click methods is to change the
740 	 * bottom_area.top_edge so that when in clickfinger mode the bottom
741 	 * touchpad area is not dead wrt finger movement starting there.
742 	 *
743 	 * We do not need to take any state into account, fingers which are
744 	 * already down will simply keep the state / area they have assigned
745 	 * until they are released, and the post_button_events path is state
746 	 * agnostic.
747 	 */
748 
749 	switch (tp->buttons.click_method) {
750 	case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS:
751 		tp_init_softbuttons(tp, tp->device);
752 		break;
753 	case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER:
754 	case LIBINPUT_CONFIG_CLICK_METHOD_NONE:
755 		tp->buttons.bottom_area.top_edge = INT_MAX;
756 		break;
757 	}
758 }
759 
760 static enum libinput_config_status
tp_button_config_click_set_method(struct libinput_device *device, enum libinput_config_click_method method)761 tp_button_config_click_set_method(struct libinput_device *device,
762 				  enum libinput_config_click_method method)
763 {
764 	struct evdev_device *evdev = evdev_device(device);
765 	struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
766 
767 	tp->buttons.click_method = method;
768 	tp_switch_click_method(tp);
769 
770 	return LIBINPUT_CONFIG_STATUS_SUCCESS;
771 }
772 
773 static enum libinput_config_click_method
tp_button_config_click_get_method(struct libinput_device *device)774 tp_button_config_click_get_method(struct libinput_device *device)
775 {
776 	struct evdev_device *evdev = evdev_device(device);
777 	struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
778 
779 	return tp->buttons.click_method;
780 }
781 
782 static enum libinput_config_click_method
tp_click_get_default_method(struct tp_dispatch *tp)783 tp_click_get_default_method(struct tp_dispatch *tp)
784 {
785 	struct evdev_device *device = tp->device;
786 
787 	if (evdev_device_has_model_quirk(device, QUIRK_MODEL_CHROMEBOOK) ||
788 	    evdev_device_has_model_quirk(device, QUIRK_MODEL_SYSTEM76_BONOBO) ||
789 	    evdev_device_has_model_quirk(device, QUIRK_MODEL_SYSTEM76_GALAGO) ||
790 	    evdev_device_has_model_quirk(device, QUIRK_MODEL_SYSTEM76_KUDU) ||
791 	    evdev_device_has_model_quirk(device, QUIRK_MODEL_CLEVO_W740SU) ||
792 	    evdev_device_has_model_quirk(device, QUIRK_MODEL_APPLE_TOUCHPAD_ONEBUTTON))
793 		return LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
794 
795 	if (!tp->buttons.is_clickpad)
796 		return LIBINPUT_CONFIG_CLICK_METHOD_NONE;
797 
798 	if (evdev_device_has_model_quirk(device, QUIRK_MODEL_APPLE_TOUCHPAD))
799 		return LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
800 
801 	return LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
802 }
803 
804 static enum libinput_config_click_method
tp_button_config_click_get_default_method(struct libinput_device *device)805 tp_button_config_click_get_default_method(struct libinput_device *device)
806 {
807 	struct evdev_device *evdev = evdev_device(device);
808 	struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
809 
810 	return tp_click_get_default_method(tp);
811 }
812 
813 void
tp_clickpad_middlebutton_apply_config(struct evdev_device *device)814 tp_clickpad_middlebutton_apply_config(struct evdev_device *device)
815 {
816 	struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
817 
818 	if (!tp->buttons.is_clickpad ||
819 	    tp->buttons.state != 0)
820 		return;
821 
822 	if (device->middlebutton.want_enabled ==
823 	    device->middlebutton.enabled)
824 		return;
825 
826 	device->middlebutton.enabled = device->middlebutton.want_enabled;
827 	if (tp->buttons.click_method ==
828 	    LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS)
829 		tp_init_softbuttons(tp, device);
830 }
831 
832 static int
tp_clickpad_middlebutton_is_available(struct libinput_device *device)833 tp_clickpad_middlebutton_is_available(struct libinput_device *device)
834 {
835 	return evdev_middlebutton_is_available(device);
836 }
837 
838 static enum libinput_config_status
tp_clickpad_middlebutton_set(struct libinput_device *device, enum libinput_config_middle_emulation_state enable)839 tp_clickpad_middlebutton_set(struct libinput_device *device,
840 		     enum libinput_config_middle_emulation_state enable)
841 {
842 	struct evdev_device *evdev = evdev_device(device);
843 
844 	switch (enable) {
845 	case LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED:
846 		evdev->middlebutton.want_enabled = true;
847 		break;
848 	case LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED:
849 		evdev->middlebutton.want_enabled = false;
850 		break;
851 	default:
852 		return LIBINPUT_CONFIG_STATUS_INVALID;
853 	}
854 
855 	tp_clickpad_middlebutton_apply_config(evdev);
856 
857 	return LIBINPUT_CONFIG_STATUS_SUCCESS;
858 }
859 
860 static enum libinput_config_middle_emulation_state
tp_clickpad_middlebutton_get(struct libinput_device *device)861 tp_clickpad_middlebutton_get(struct libinput_device *device)
862 {
863 	return evdev_middlebutton_get(device);
864 }
865 
866 static enum libinput_config_middle_emulation_state
tp_clickpad_middlebutton_get_default(struct libinput_device *device)867 tp_clickpad_middlebutton_get_default(struct libinput_device *device)
868 {
869 	return evdev_middlebutton_get_default(device);
870 }
871 
872 static inline void
tp_init_clickpad_middlebutton_emulation(struct tp_dispatch *tp, struct evdev_device *device)873 tp_init_clickpad_middlebutton_emulation(struct tp_dispatch *tp,
874 					struct evdev_device *device)
875 {
876 	device->middlebutton.enabled_default = false;
877 	device->middlebutton.want_enabled = false;
878 	device->middlebutton.enabled = false;
879 
880 	device->middlebutton.config.available = tp_clickpad_middlebutton_is_available;
881 	device->middlebutton.config.set = tp_clickpad_middlebutton_set;
882 	device->middlebutton.config.get = tp_clickpad_middlebutton_get;
883 	device->middlebutton.config.get_default = tp_clickpad_middlebutton_get_default;
884 	device->base.config.middle_emulation = &device->middlebutton.config;
885 }
886 
887 static inline void
tp_init_middlebutton_emulation(struct tp_dispatch *tp, struct evdev_device *device)888 tp_init_middlebutton_emulation(struct tp_dispatch *tp,
889 			       struct evdev_device *device)
890 {
891 	bool enable_by_default,
892 	     want_config_option;
893 
894 	/* On clickpads we provide the config option but disable by default.
895 	   When enabled, the middle software button disappears */
896 	if (tp->buttons.is_clickpad) {
897 		tp_init_clickpad_middlebutton_emulation(tp, device);
898 		return;
899 	}
900 
901 	/* init middle button emulation on non-clickpads, but only if we
902 	 * don't have a middle button. Exception: ALPS touchpads don't know
903 	 * if they have a middle button, so we always want the option there
904 	 * and enabled by default.
905 	 */
906 	if (!libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE)) {
907 		enable_by_default = true;
908 		want_config_option = false;
909 	} else if (evdev_device_has_model_quirk(device,
910 						QUIRK_MODEL_ALPS_SERIAL_TOUCHPAD)) {
911 		enable_by_default = true;
912 		want_config_option = true;
913 	} else
914 		return;
915 
916 	evdev_init_middlebutton(tp->device,
917 				enable_by_default,
918 				want_config_option);
919 }
920 
921 static bool
tp_guess_clickpad(const struct tp_dispatch *tp, struct evdev_device *device)922 tp_guess_clickpad(const struct tp_dispatch *tp, struct evdev_device *device)
923 {
924 	bool is_clickpad;
925 	bool has_left = libevdev_has_event_code(device->evdev, EV_KEY, BTN_LEFT),
926 	     has_middle = libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE),
927 	     has_right = libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT);
928 
929 	is_clickpad = libevdev_has_property(device->evdev, INPUT_PROP_BUTTONPAD);
930 
931 	/* A non-clickpad without a right button is a clickpad, assume the
932 	 * kernel is wrong.
933 	 * Exceptions here:
934 	 * - The one-button Apple touchpad (discontinued in 2008) has a
935 	 *   single physical button
936 	 * - Wacom touch devices have neither left nor right buttons
937 	 */
938 	if (!is_clickpad && has_left && !has_right &&
939 	    (tp->device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON) == 0) {
940 		evdev_log_bug_kernel(device,
941 				     "missing right button, assuming it is a clickpad.\n");
942 		is_clickpad = true;
943 	}
944 
945 	if (has_middle || has_right) {
946 		if (is_clickpad)
947 			evdev_log_bug_kernel(device,
948 					     "clickpad advertising right button. "
949 					     "See %s/clickpad-with-right-button.html for details\n",
950 					     HTTP_DOC_LINK);
951 	} else if (has_left &
952 		   !is_clickpad &&
953 		   libevdev_get_id_vendor(device->evdev) != VENDOR_ID_APPLE) {
954 			evdev_log_bug_kernel(device,
955 					     "non clickpad without right button?\n");
956 	}
957 
958 	return is_clickpad;
959 }
960 
961 void
tp_init_buttons(struct tp_dispatch *tp, struct evdev_device *device)962 tp_init_buttons(struct tp_dispatch *tp,
963 		struct evdev_device *device)
964 {
965 	struct tp_touch *t;
966 	const struct input_absinfo *absinfo_x, *absinfo_y;
967 	int i;
968 
969 	tp->buttons.is_clickpad = tp_guess_clickpad(tp, device);
970 
971 	tp->buttons.has_topbuttons = libevdev_has_property(device->evdev,
972 						        INPUT_PROP_TOPBUTTONPAD);
973 
974 	absinfo_x = device->abs.absinfo_x;
975 	absinfo_y = device->abs.absinfo_y;
976 
977 	/* pinned-finger motion threshold, see tp_unpin_finger. */
978 	tp->buttons.motion_dist.x_scale_coeff = 1.0/absinfo_x->resolution;
979 	tp->buttons.motion_dist.y_scale_coeff = 1.0/absinfo_y->resolution;
980 
981 	tp->buttons.config_method.get_methods = tp_button_config_click_get_methods;
982 	tp->buttons.config_method.set_method = tp_button_config_click_set_method;
983 	tp->buttons.config_method.get_method = tp_button_config_click_get_method;
984 	tp->buttons.config_method.get_default_method = tp_button_config_click_get_default_method;
985 	tp->device->base.config.click_method = &tp->buttons.config_method;
986 
987 	tp->buttons.click_method = tp_click_get_default_method(tp);
988 	tp_switch_click_method(tp);
989 
990 	tp_init_top_softbuttons(tp, device, 1.0);
991 
992 	tp_init_middlebutton_emulation(tp, device);
993 
994 	i = 0;
995 	tp_for_each_touch(tp, t) {
996 		char timer_name[64];
997 		i++;
998 
999 		snprintf(timer_name,
1000 			 sizeof(timer_name),
1001 			 "%s (%d) button",
1002 			 evdev_device_get_sysname(device),
1003 			 i);
1004 		t->button.state = BUTTON_STATE_NONE;
1005 		libinput_timer_init(&t->button.timer,
1006 				    tp_libinput_context(tp),
1007 				    timer_name,
1008 				    tp_button_handle_timeout, t);
1009 	}
1010 }
1011 
1012 void
tp_remove_buttons(struct tp_dispatch *tp)1013 tp_remove_buttons(struct tp_dispatch *tp)
1014 {
1015 	struct tp_touch *t;
1016 
1017 	tp_for_each_touch(tp, t) {
1018 		libinput_timer_cancel(&t->button.timer);
1019 		libinput_timer_destroy(&t->button.timer);
1020 	}
1021 }
1022 
1023 static int
tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)1024 tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
1025 {
1026 	uint32_t current, old, button;
1027 
1028 	current = tp->buttons.state;
1029 	old = tp->buttons.old_state;
1030 	button = BTN_LEFT;
1031 
1032 	while (current || old) {
1033 		enum libinput_button_state state;
1034 
1035 		if ((current & 0x1) ^ (old & 0x1)) {
1036 			uint32_t b;
1037 
1038 			if (!!(current & 0x1))
1039 				state = LIBINPUT_BUTTON_STATE_PRESSED;
1040 			else
1041 				state = LIBINPUT_BUTTON_STATE_RELEASED;
1042 
1043 			b = evdev_to_left_handed(tp->device, button);
1044 			evdev_pointer_notify_physical_button(tp->device,
1045 							     time,
1046 							     b,
1047 							     state);
1048 		}
1049 
1050 		button++;
1051 		current >>= 1;
1052 		old >>= 1;
1053 	}
1054 
1055 	return 0;
1056 }
1057 
1058 static inline bool
tp_clickfinger_within_distance(struct tp_dispatch *tp, struct tp_touch *t1, struct tp_touch *t2)1059 tp_clickfinger_within_distance(struct tp_dispatch *tp,
1060 			       struct tp_touch *t1,
1061 			       struct tp_touch *t2)
1062 {
1063 	double x, y;
1064 	bool within_distance = false;
1065 	int xres, yres;
1066 	int bottom_threshold;
1067 
1068 	if (!t1 || !t2)
1069 		return 0;
1070 
1071 	if (tp_thumb_ignored(tp, t1) || tp_thumb_ignored(tp, t2))
1072 		return 0;
1073 
1074 	x = abs(t1->point.x - t2->point.x);
1075 	y = abs(t1->point.y - t2->point.y);
1076 
1077 	xres = tp->device->abs.absinfo_x->resolution;
1078 	yres = tp->device->abs.absinfo_y->resolution;
1079 	x /= xres;
1080 	y /= yres;
1081 
1082 	/* maximum horiz spread is 40mm horiz, 30mm vert, anything wider
1083 	 * than that is probably a gesture. */
1084 	if (x > 40 || y > 30)
1085 		goto out;
1086 
1087 	within_distance = true;
1088 
1089 	/* if y spread is <= 20mm, they're definitely together. */
1090 	if (y <= 20)
1091 		goto out;
1092 
1093 	/* if they're vertically spread between 20-40mm, they're not
1094 	 * together if:
1095 	 * - the touchpad's vertical size is >50mm, anything smaller is
1096 	 *   unlikely to have a thumb resting on it
1097 	 * - and one of the touches is in the bottom 20mm of the touchpad
1098 	 *   and the other one isn't
1099 	 */
1100 
1101 	if (tp->device->abs.dimensions.y/yres < 50)
1102 		goto out;
1103 
1104 	bottom_threshold = tp->device->abs.absinfo_y->maximum - 20 * yres;
1105 	if ((t1->point.y > bottom_threshold) !=
1106 		    (t2->point.y > bottom_threshold))
1107 		within_distance = 0;
1108 
1109 out:
1110 	return within_distance;
1111 }
1112 
1113 static uint32_t
tp_clickfinger_set_button(struct tp_dispatch *tp)1114 tp_clickfinger_set_button(struct tp_dispatch *tp)
1115 {
1116 	uint32_t button;
1117 	unsigned int nfingers = 0;
1118 	struct tp_touch *t;
1119 	struct tp_touch *first = NULL,
1120 			*second = NULL;
1121 
1122 	tp_for_each_touch(tp, t) {
1123 		if (t->state != TOUCH_BEGIN && t->state != TOUCH_UPDATE)
1124 			continue;
1125 
1126 		if (tp_thumb_ignored(tp, t))
1127 			continue;
1128 
1129 		if (t->palm.state != PALM_NONE)
1130 			continue;
1131 
1132 		nfingers++;
1133 
1134 		if (!first)
1135 			first = t;
1136 		else if (!second)
1137 			second = t;
1138 	}
1139 
1140 	/* Only check for finger distance when there are 2 fingers on the
1141 	 * touchpad */
1142 	if (nfingers != 2)
1143 		goto out;
1144 
1145 	if (tp_clickfinger_within_distance(tp, first, second))
1146 		nfingers = 2;
1147 	else
1148 		nfingers = 1;
1149 
1150 out:
1151 	switch (nfingers) {
1152 	case 0:
1153 	case 1: button = BTN_LEFT; break;
1154 	case 2: button = BTN_RIGHT; break;
1155 	case 3: button = BTN_MIDDLE; break;
1156 	default:
1157 		button = 0;
1158 		break;
1159 	}
1160 
1161 	return button;
1162 }
1163 
1164 static int
tp_notify_clickpadbutton(struct tp_dispatch *tp, uint64_t time, uint32_t button, uint32_t is_topbutton, enum libinput_button_state state)1165 tp_notify_clickpadbutton(struct tp_dispatch *tp,
1166 			 uint64_t time,
1167 			 uint32_t button,
1168 			 uint32_t is_topbutton,
1169 			 enum libinput_button_state state)
1170 {
1171 	/* If we've a trackpoint, send top buttons through the trackpoint */
1172 	if (tp->buttons.trackpoint) {
1173 		if (is_topbutton) {
1174 			struct evdev_dispatch *dispatch = tp->buttons.trackpoint->dispatch;
1175 			struct input_event event, syn_report;
1176 			int value;
1177 
1178 			value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0;
1179 			event = input_event_init(time, EV_KEY, button, value);
1180 			syn_report = input_event_init(time, EV_SYN, SYN_REPORT, 0);
1181 			dispatch->interface->process(dispatch,
1182 						     tp->buttons.trackpoint,
1183 						     &event,
1184 						     time);
1185 			dispatch->interface->process(dispatch,
1186 						     tp->buttons.trackpoint,
1187 						     &syn_report,
1188 						     time);
1189 			return 1;
1190 		}
1191 		/* Ignore button events not for the trackpoint while suspended */
1192 		if (tp->device->is_suspended)
1193 			return 0;
1194 	}
1195 
1196 	/* A button click always terminates edge scrolling, even if we
1197 	 * don't end up sending a button event. */
1198 	tp_edge_scroll_stop_events(tp, time);
1199 
1200 	/*
1201 	 * If the user has requested clickfinger replace the button chosen
1202 	 * by the softbutton code with one based on the number of fingers.
1203 	 */
1204 	if (tp->buttons.click_method == LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER &&
1205 	    state == LIBINPUT_BUTTON_STATE_PRESSED) {
1206 		button = tp_clickfinger_set_button(tp);
1207 		tp->buttons.active = button;
1208 
1209 		if (!button)
1210 			return 0;
1211 	}
1212 
1213 	evdev_pointer_notify_button(tp->device, time, button, state);
1214 	return 1;
1215 }
1216 
1217 static int
tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, uint64_t time)1218 tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, uint64_t time)
1219 {
1220 	uint32_t current, old, button, is_top;
1221 	enum libinput_button_state state;
1222 	enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
1223 	bool want_left_handed = true;
1224 
1225 	current = tp->buttons.state;
1226 	old = tp->buttons.old_state;
1227 	is_top = 0;
1228 
1229 	if (!tp->buttons.click_pending && current == old)
1230 		return 0;
1231 
1232 	if (current) {
1233 		struct tp_touch *t;
1234 		uint32_t area = 0;
1235 
1236 		if (evdev_device_has_model_quirk(tp->device,
1237 						 QUIRK_MODEL_TOUCHPAD_PHANTOM_CLICKS) &&
1238 		    tp->nactive_slots == 0) {
1239 			/* Some touchpads, notably those on the Dell XPS 15 9500,
1240 			 * are prone to registering touchpad clicks when the
1241 			 * case is sufficiently flexed. Ignore these by
1242 			 * disregarding any clicks that are registered without
1243 			 * touchpad touch. */
1244 			tp->buttons.click_pending = true;
1245 			return 0;
1246 		}
1247 
1248 		tp_for_each_touch(tp, t) {
1249 			switch (t->button.current) {
1250 			case BUTTON_EVENT_IN_AREA:
1251 				area |= AREA;
1252 				break;
1253 			case BUTTON_EVENT_IN_TOP_L:
1254 				is_top = 1;
1255 				_fallthrough_;
1256 			case BUTTON_EVENT_IN_BOTTOM_L:
1257 				area |= LEFT;
1258 				break;
1259 			case BUTTON_EVENT_IN_TOP_M:
1260 				is_top = 1;
1261 				_fallthrough_;
1262 			case BUTTON_EVENT_IN_BOTTOM_M:
1263 				area |= MIDDLE;
1264 				break;
1265 			case BUTTON_EVENT_IN_TOP_R:
1266 				is_top = 1;
1267 				_fallthrough_;
1268 			case BUTTON_EVENT_IN_BOTTOM_R:
1269 				area |= RIGHT;
1270 				break;
1271 			default:
1272 				break;
1273 			}
1274 		}
1275 
1276 		if (area == 0 &&
1277 		    tp->buttons.click_method != LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) {
1278 			/* No touches, wait for a touch before processing */
1279 			tp->buttons.click_pending = true;
1280 			return 0;
1281 		}
1282 
1283 		if ((tp->device->middlebutton.enabled || is_top) &&
1284 		    (area & LEFT) && (area & RIGHT)) {
1285 			button = BTN_MIDDLE;
1286 		} else if (area & MIDDLE) {
1287 			button = BTN_MIDDLE;
1288 		} else if (area & RIGHT) {
1289 			button = BTN_RIGHT;
1290 		} else if (area & LEFT) {
1291 			button = BTN_LEFT;
1292 		} else { /* main or no area (for clickfinger) is always BTN_LEFT */
1293 			button = BTN_LEFT;
1294 			want_left_handed = false;
1295 		}
1296 
1297 		if (is_top)
1298 			want_left_handed = false;
1299 
1300 		if (want_left_handed)
1301 			button = evdev_to_left_handed(tp->device, button);
1302 
1303 		tp->buttons.active = button;
1304 		tp->buttons.active_is_topbutton = is_top;
1305 		state = LIBINPUT_BUTTON_STATE_PRESSED;
1306 	} else {
1307 		button = tp->buttons.active;
1308 		is_top = tp->buttons.active_is_topbutton;
1309 		tp->buttons.active = 0;
1310 		tp->buttons.active_is_topbutton = 0;
1311 		state = LIBINPUT_BUTTON_STATE_RELEASED;
1312 	}
1313 
1314 	tp->buttons.click_pending = false;
1315 
1316 	if (button)
1317 		return tp_notify_clickpadbutton(tp,
1318 						time,
1319 						button,
1320 						is_top,
1321 						state);
1322 	return 0;
1323 }
1324 
1325 int
tp_post_button_events(struct tp_dispatch *tp, uint64_t time)1326 tp_post_button_events(struct tp_dispatch *tp, uint64_t time)
1327 {
1328 	if (tp->buttons.is_clickpad ||
1329 	    tp->device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON)
1330 		return tp_post_clickpadbutton_buttons(tp, time);
1331 	return tp_post_physical_buttons(tp, time);
1332 }
1333 
1334 bool
tp_button_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t)1335 tp_button_touch_active(const struct tp_dispatch *tp,
1336 		       const struct tp_touch *t)
1337 {
1338 	return t->button.state == BUTTON_STATE_AREA || t->button.has_moved;
1339 }
1340 
1341 bool
tp_button_is_inside_softbutton_area(const struct tp_dispatch *tp, const struct tp_touch *t)1342 tp_button_is_inside_softbutton_area(const struct tp_dispatch *tp,
1343 				    const struct tp_touch *t)
1344 {
1345 	return is_inside_top_button_area(tp, t) ||
1346 	       is_inside_bottom_button_area(tp, t);
1347 }
1348