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
46static inline const char*
47button_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
61static inline const char*
62button_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
80static inline bool
81is_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
87static inline bool
88is_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
95static inline bool
96is_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
104static inline bool
105is_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
111static inline bool
112is_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
119static inline bool
120is_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
128static void
129tp_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
137static void
138tp_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 */
150static void
151tp_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
186static void
187tp_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
216static void
217tp_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 */
246static inline void
247tp_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
271static void
272tp_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
312static void
313tp_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
347static void
348tp_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
386static void
387tp_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
426static void
427tp_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
454static void
455tp_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
495static inline void
496tp_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
531void
532tp_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
582static void
583tp_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
590void
591tp_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
614void
615tp_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
624static void
625tp_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
684void
685tp_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
716static inline uint32_t
717tp_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
735static void
736tp_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
760static enum libinput_config_status
761tp_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
773static enum libinput_config_click_method
774tp_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
782static enum libinput_config_click_method
783tp_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
804static enum libinput_config_click_method
805tp_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
813void
814tp_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
832static int
833tp_clickpad_middlebutton_is_available(struct libinput_device *device)
834{
835	return evdev_middlebutton_is_available(device);
836}
837
838static enum libinput_config_status
839tp_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
860static enum libinput_config_middle_emulation_state
861tp_clickpad_middlebutton_get(struct libinput_device *device)
862{
863	return evdev_middlebutton_get(device);
864}
865
866static enum libinput_config_middle_emulation_state
867tp_clickpad_middlebutton_get_default(struct libinput_device *device)
868{
869	return evdev_middlebutton_get_default(device);
870}
871
872static inline void
873tp_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
887static inline void
888tp_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
921static bool
922tp_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
961void
962tp_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
1012void
1013tp_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
1023static int
1024tp_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
1058static inline bool
1059tp_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
1109out:
1110	return within_distance;
1111}
1112
1113static uint32_t
1114tp_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
1150out:
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
1164static int
1165tp_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
1217static int
1218tp_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
1325int
1326tp_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
1334bool
1335tp_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
1341bool
1342tp_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