2 * Copyright © 2014 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 #include "linux/input.h"
30 #include "evdev-mt-touchpad.h"
32 #define DEFAULT_BUTTON_MOTION_THRESHOLD 0.02 /* 2% of size */
33 #define DEFAULT_BUTTON_ENTER_TIMEOUT 100 /* ms */
34 #define DEFAULT_BUTTON_LEAVE_TIMEOUT 300 /* ms */
36 /*****************************************
37 * BEFORE YOU EDIT THIS FILE, look at the state diagram in
38 * doc/touchpad-softbutton-state-machine.svg, or online at
39 * https://drive.google.com/file/d/0B1NwWmji69nocUs1cVJTbkdwMFk/edit?usp=sharing
40 * (it's a http://draw.io diagram)
42 * Any changes in this file must be represented in the diagram.
44 * The state machine only affects the soft button area code.
47 #define CASE_RETURN_STRING(a) case a: return #a;
49 static inline const char*
50 button_state_to_str(enum button_state state) {
52 CASE_RETURN_STRING(BUTTON_STATE_NONE);
53 CASE_RETURN_STRING(BUTTON_STATE_AREA);
54 CASE_RETURN_STRING(BUTTON_STATE_BOTTOM);
55 CASE_RETURN_STRING(BUTTON_STATE_BOTTOM_NEW);
56 CASE_RETURN_STRING(BUTTON_STATE_BOTTOM_TO_AREA);
57 CASE_RETURN_STRING(BUTTON_STATE_TOP);
58 CASE_RETURN_STRING(BUTTON_STATE_TOP_NEW);
59 CASE_RETURN_STRING(BUTTON_STATE_TOP_TO_IGNORE);
60 CASE_RETURN_STRING(BUTTON_STATE_IGNORE);
65 static inline const char*
66 button_event_to_str(enum button_event event) {
68 CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_R);
69 CASE_RETURN_STRING(BUTTON_EVENT_IN_BOTTOM_L);
70 CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_R);
71 CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_M);
72 CASE_RETURN_STRING(BUTTON_EVENT_IN_TOP_L);
73 CASE_RETURN_STRING(BUTTON_EVENT_IN_AREA);
74 CASE_RETURN_STRING(BUTTON_EVENT_UP);
75 CASE_RETURN_STRING(BUTTON_EVENT_PRESS);
76 CASE_RETURN_STRING(BUTTON_EVENT_RELEASE);
77 CASE_RETURN_STRING(BUTTON_EVENT_TIMEOUT);
83 is_inside_bottom_button_area(struct tp_dispatch *tp, struct tp_touch *t)
85 return t->y >= tp->buttons.bottom_area.top_edge;
89 is_inside_bottom_right_area(struct tp_dispatch *tp, struct tp_touch *t)
91 return is_inside_bottom_button_area(tp, t) &&
92 t->x > tp->buttons.bottom_area.rightbutton_left_edge;
96 is_inside_bottom_left_area(struct tp_dispatch *tp, struct tp_touch *t)
98 return is_inside_bottom_button_area(tp, t) &&
99 !is_inside_bottom_right_area(tp, t);
103 is_inside_top_button_area(struct tp_dispatch *tp, struct tp_touch *t)
105 return t->y <= tp->buttons.top_area.bottom_edge;
109 is_inside_top_right_area(struct tp_dispatch *tp, struct tp_touch *t)
111 return is_inside_top_button_area(tp, t) &&
112 t->x > tp->buttons.top_area.rightbutton_left_edge;
116 is_inside_top_left_area(struct tp_dispatch *tp, struct tp_touch *t)
118 return is_inside_top_button_area(tp, t) &&
119 t->x < tp->buttons.top_area.leftbutton_right_edge;
123 is_inside_top_middle_area(struct tp_dispatch *tp, struct tp_touch *t)
125 return is_inside_top_button_area(tp, t) &&
126 t->x >= tp->buttons.top_area.leftbutton_right_edge &&
127 t->x <= tp->buttons.top_area.rightbutton_left_edge;
131 tp_button_set_enter_timer(struct tp_dispatch *tp, struct tp_touch *t)
133 libinput_timer_set(&t->button.timer,
134 t->millis + DEFAULT_BUTTON_ENTER_TIMEOUT);
138 tp_button_set_leave_timer(struct tp_dispatch *tp, struct tp_touch *t)
140 libinput_timer_set(&t->button.timer,
141 t->millis + DEFAULT_BUTTON_LEAVE_TIMEOUT);
145 * tp_button_set_state, change state and implement on-entry behavior
146 * as described in the state machine diagram.
149 tp_button_set_state(struct tp_dispatch *tp, struct tp_touch *t,
150 enum button_state new_state, enum button_event event)
152 libinput_timer_cancel(&t->button.timer);
154 t->button.state = new_state;
155 switch (t->button.state) {
156 case BUTTON_STATE_NONE:
159 case BUTTON_STATE_AREA:
160 t->button.curr = BUTTON_EVENT_IN_AREA;
161 tp_set_pointer(tp, t);
163 case BUTTON_STATE_BOTTOM:
165 case BUTTON_STATE_BOTTOM_NEW:
166 t->button.curr = event;
167 tp_button_set_enter_timer(tp, t);
169 case BUTTON_STATE_BOTTOM_TO_AREA:
170 tp_button_set_leave_timer(tp, t);
172 case BUTTON_STATE_TOP:
174 case BUTTON_STATE_TOP_NEW:
175 t->button.curr = event;
176 tp_button_set_enter_timer(tp, t);
178 case BUTTON_STATE_TOP_TO_IGNORE:
179 tp_button_set_leave_timer(tp, t);
181 case BUTTON_STATE_IGNORE:
188 tp_button_none_handle_event(struct tp_dispatch *tp,
190 enum button_event event)
193 case BUTTON_EVENT_IN_BOTTOM_R:
194 case BUTTON_EVENT_IN_BOTTOM_L:
195 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW, event);
197 case BUTTON_EVENT_IN_TOP_R:
198 case BUTTON_EVENT_IN_TOP_M:
199 case BUTTON_EVENT_IN_TOP_L:
200 tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW, event);
202 case BUTTON_EVENT_IN_AREA:
203 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
205 case BUTTON_EVENT_UP:
206 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
208 case BUTTON_EVENT_PRESS:
209 case BUTTON_EVENT_RELEASE:
210 case BUTTON_EVENT_TIMEOUT:
216 tp_button_area_handle_event(struct tp_dispatch *tp,
218 enum button_event event)
221 case BUTTON_EVENT_IN_BOTTOM_R:
222 case BUTTON_EVENT_IN_BOTTOM_L:
223 case BUTTON_EVENT_IN_TOP_R:
224 case BUTTON_EVENT_IN_TOP_M:
225 case BUTTON_EVENT_IN_TOP_L:
226 case BUTTON_EVENT_IN_AREA:
228 case BUTTON_EVENT_UP:
229 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
231 case BUTTON_EVENT_PRESS:
232 case BUTTON_EVENT_RELEASE:
233 case BUTTON_EVENT_TIMEOUT:
239 tp_button_bottom_handle_event(struct tp_dispatch *tp,
241 enum button_event event)
244 case BUTTON_EVENT_IN_BOTTOM_R:
245 case BUTTON_EVENT_IN_BOTTOM_L:
246 if (event != t->button.curr)
247 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
250 case BUTTON_EVENT_IN_TOP_R:
251 case BUTTON_EVENT_IN_TOP_M:
252 case BUTTON_EVENT_IN_TOP_L:
253 case BUTTON_EVENT_IN_AREA:
254 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_TO_AREA, event);
256 case BUTTON_EVENT_UP:
257 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
259 case BUTTON_EVENT_PRESS:
260 case BUTTON_EVENT_RELEASE:
261 case BUTTON_EVENT_TIMEOUT:
267 tp_button_bottom_new_handle_event(struct tp_dispatch *tp,
269 enum button_event event)
272 case BUTTON_EVENT_IN_BOTTOM_R:
273 case BUTTON_EVENT_IN_BOTTOM_L:
274 if (event != t->button.curr)
275 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
278 case BUTTON_EVENT_IN_TOP_R:
279 case BUTTON_EVENT_IN_TOP_M:
280 case BUTTON_EVENT_IN_TOP_L:
281 case BUTTON_EVENT_IN_AREA:
282 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
284 case BUTTON_EVENT_UP:
285 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
287 case BUTTON_EVENT_PRESS:
288 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event);
290 case BUTTON_EVENT_RELEASE:
292 case BUTTON_EVENT_TIMEOUT:
293 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event);
299 tp_button_bottom_to_area_handle_event(struct tp_dispatch *tp,
301 enum button_event event)
304 case BUTTON_EVENT_IN_BOTTOM_R:
305 case BUTTON_EVENT_IN_BOTTOM_L:
306 if (event == t->button.curr)
307 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM,
310 tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM_NEW,
313 case BUTTON_EVENT_IN_TOP_R:
314 case BUTTON_EVENT_IN_TOP_M:
315 case BUTTON_EVENT_IN_TOP_L:
316 case BUTTON_EVENT_IN_AREA:
318 case BUTTON_EVENT_UP:
319 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
321 case BUTTON_EVENT_PRESS:
322 case BUTTON_EVENT_RELEASE:
324 case BUTTON_EVENT_TIMEOUT:
325 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
331 tp_button_top_handle_event(struct tp_dispatch *tp,
333 enum button_event event)
336 case BUTTON_EVENT_IN_BOTTOM_R:
337 case BUTTON_EVENT_IN_BOTTOM_L:
338 tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event);
340 case BUTTON_EVENT_IN_TOP_R:
341 case BUTTON_EVENT_IN_TOP_M:
342 case BUTTON_EVENT_IN_TOP_L:
343 if (event != t->button.curr)
344 tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW,
347 case BUTTON_EVENT_IN_AREA:
348 tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event);
350 case BUTTON_EVENT_UP:
351 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
353 case BUTTON_EVENT_PRESS:
354 case BUTTON_EVENT_RELEASE:
355 case BUTTON_EVENT_TIMEOUT:
361 tp_button_top_new_handle_event(struct tp_dispatch *tp,
363 enum button_event event)
366 case BUTTON_EVENT_IN_BOTTOM_R:
367 case BUTTON_EVENT_IN_BOTTOM_L:
368 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
370 case BUTTON_EVENT_IN_TOP_R:
371 case BUTTON_EVENT_IN_TOP_M:
372 case BUTTON_EVENT_IN_TOP_L:
373 if (event != t->button.curr)
374 tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW,
377 case BUTTON_EVENT_IN_AREA:
378 tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
380 case BUTTON_EVENT_UP:
381 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
383 case BUTTON_EVENT_PRESS:
384 tp_button_set_state(tp, t, BUTTON_STATE_TOP, event);
386 case BUTTON_EVENT_RELEASE:
388 case BUTTON_EVENT_TIMEOUT:
389 tp_button_set_state(tp, t, BUTTON_STATE_TOP, event);
395 tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
397 enum button_event event)
400 case BUTTON_EVENT_IN_TOP_R:
401 case BUTTON_EVENT_IN_TOP_M:
402 case BUTTON_EVENT_IN_TOP_L:
403 if (event == t->button.curr)
404 tp_button_set_state(tp, t, BUTTON_STATE_TOP,
407 tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW,
410 case BUTTON_EVENT_IN_BOTTOM_R:
411 case BUTTON_EVENT_IN_BOTTOM_L:
412 case BUTTON_EVENT_IN_AREA:
414 case BUTTON_EVENT_UP:
415 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
417 case BUTTON_EVENT_PRESS:
418 case BUTTON_EVENT_RELEASE:
420 case BUTTON_EVENT_TIMEOUT:
421 tp_button_set_state(tp, t, BUTTON_STATE_IGNORE, event);
427 tp_button_ignore_handle_event(struct tp_dispatch *tp,
429 enum button_event event)
432 case BUTTON_EVENT_IN_BOTTOM_R:
433 case BUTTON_EVENT_IN_BOTTOM_L:
434 case BUTTON_EVENT_IN_TOP_R:
435 case BUTTON_EVENT_IN_TOP_M:
436 case BUTTON_EVENT_IN_TOP_L:
437 case BUTTON_EVENT_IN_AREA:
439 case BUTTON_EVENT_UP:
440 tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
442 case BUTTON_EVENT_PRESS:
443 case BUTTON_EVENT_RELEASE:
444 case BUTTON_EVENT_TIMEOUT:
450 tp_button_handle_event(struct tp_dispatch *tp,
452 enum button_event event,
455 struct libinput *libinput = tp->device->base.seat->libinput;
456 enum button_state current = t->button.state;
458 switch(t->button.state) {
459 case BUTTON_STATE_NONE:
460 tp_button_none_handle_event(tp, t, event);
462 case BUTTON_STATE_AREA:
463 tp_button_area_handle_event(tp, t, event);
465 case BUTTON_STATE_BOTTOM:
466 tp_button_bottom_handle_event(tp, t, event);
468 case BUTTON_STATE_BOTTOM_NEW:
469 tp_button_bottom_new_handle_event(tp, t, event);
471 case BUTTON_STATE_BOTTOM_TO_AREA:
472 tp_button_bottom_to_area_handle_event(tp, t, event);
474 case BUTTON_STATE_TOP:
475 tp_button_top_handle_event(tp, t, event);
477 case BUTTON_STATE_TOP_NEW:
478 tp_button_top_new_handle_event(tp, t, event);
480 case BUTTON_STATE_TOP_TO_IGNORE:
481 tp_button_top_to_ignore_handle_event(tp, t, event);
483 case BUTTON_STATE_IGNORE:
484 tp_button_ignore_handle_event(tp, t, event);
488 if (current != t->button.state)
490 "button state: from %s, event %s to %s\n",
491 button_state_to_str(current),
492 button_event_to_str(event),
493 button_state_to_str(t->button.state));
497 tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
501 tp_for_each_touch(tp, t) {
502 if (t->state == TOUCH_NONE)
505 if (t->state == TOUCH_END) {
506 tp_button_handle_event(tp, t, BUTTON_EVENT_UP, time);
507 } else if (t->dirty) {
508 if (is_inside_bottom_right_area(tp, t))
509 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_R, time);
510 else if (is_inside_bottom_left_area(tp, t))
511 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_BOTTOM_L, time);
512 else if (is_inside_top_right_area(tp, t))
513 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_TOP_R, time);
514 else if (is_inside_top_middle_area(tp, t))
515 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_TOP_M, time);
516 else if (is_inside_top_left_area(tp, t))
517 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_TOP_L, time);
519 tp_button_handle_event(tp, t, BUTTON_EVENT_IN_AREA, time);
521 if (tp->queued & TOUCHPAD_EVENT_BUTTON_RELEASE)
522 tp_button_handle_event(tp, t, BUTTON_EVENT_RELEASE, time);
523 if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS)
524 tp_button_handle_event(tp, t, BUTTON_EVENT_PRESS, time);
531 tp_button_handle_timeout(uint64_t now, void *data)
533 struct tp_touch *t = data;
535 tp_button_handle_event(t->tp, t, BUTTON_EVENT_TIMEOUT, now);
539 tp_process_button(struct tp_dispatch *tp,
540 const struct input_event *e,
543 struct libinput *libinput = tp->device->base.seat->libinput;
544 uint32_t mask = 1 << (e->code - BTN_LEFT);
546 /* Ignore other buttons on clickpads */
547 if (tp->buttons.is_clickpad && e->code != BTN_LEFT) {
548 log_bug_kernel(libinput,
549 "received %s button event on a clickpad\n",
550 libevdev_event_code_get_name(EV_KEY, e->code));
555 tp->buttons.state |= mask;
556 tp->queued |= TOUCHPAD_EVENT_BUTTON_PRESS;
558 tp->buttons.state &= ~mask;
559 tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
566 tp_init_buttons(struct tp_dispatch *tp,
567 struct evdev_device *device)
569 struct libinput *libinput = tp->device->base.seat->libinput;
573 const struct input_absinfo *absinfo_x, *absinfo_y;
575 tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
576 INPUT_PROP_BUTTONPAD);
577 tp->buttons.has_topbuttons = libevdev_has_property(device->evdev,
578 INPUT_PROP_TOPBUTTONPAD);
580 if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE) ||
581 libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT)) {
582 if (tp->buttons.is_clickpad)
583 log_bug_kernel(libinput,
584 "%s: clickpad advertising right button\n",
587 if (!tp->buttons.is_clickpad)
588 log_bug_kernel(libinput,
589 "%s: non clickpad without right button?\n",
593 absinfo_x = device->abs.absinfo_x;
594 absinfo_y = device->abs.absinfo_y;
596 width = abs(absinfo_x->maximum - absinfo_x->minimum);
597 height = abs(absinfo_y->maximum - absinfo_y->minimum);
598 diagonal = sqrt(width*width + height*height);
600 tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
602 if (libevdev_get_id_vendor(device->evdev) == 0x5ac) /* Apple */
603 tp->buttons.use_clickfinger = true;
605 if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) {
606 int xoffset = absinfo_x->minimum,
607 yoffset = absinfo_y->minimum;
608 int yres = absinfo_y->resolution;
610 /* button height: 10mm or 15% of the touchpad height,
611 whichever is smaller */
612 if (yres > 1 && (height * 0.15/yres) > 10) {
613 tp->buttons.bottom_area.top_edge =
614 absinfo_y->maximum - 10 * yres;
616 tp->buttons.bottom_area.top_edge = height * .85 + yoffset;
619 tp->buttons.bottom_area.rightbutton_left_edge = width/2 + xoffset;
621 if (tp->buttons.has_topbuttons) {
622 /* T440s has the top button line 5mm from the top,
623 make the buttons 6mm high */
625 tp->buttons.top_area.bottom_edge =
628 tp->buttons.top_area.bottom_edge = height * .08 + yoffset;
630 tp->buttons.top_area.rightbutton_left_edge = width * .58 + xoffset;
631 tp->buttons.top_area.leftbutton_right_edge = width * .42 + xoffset;
633 tp->buttons.top_area.bottom_edge = INT_MIN;
636 tp->buttons.bottom_area.top_edge = INT_MAX;
637 tp->buttons.top_area.bottom_edge = INT_MIN;
640 tp_for_each_touch(tp, t) {
641 t->button.state = BUTTON_STATE_NONE;
642 libinput_timer_init(&t->button.timer,
643 tp->device->base.seat->libinput,
644 tp_button_handle_timeout, t);
651 tp_destroy_buttons(struct tp_dispatch *tp)
655 tp_for_each_touch(tp, t)
656 libinput_timer_cancel(&t->button.timer);
660 tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint64_t time)
662 uint32_t current, old, button;
663 enum libinput_button_state state;
665 current = tp->buttons.state;
666 old = tp->buttons.old_state;
672 switch (tp->nfingers_down) {
673 case 1: button = BTN_LEFT; break;
674 case 2: button = BTN_RIGHT; break;
675 case 3: button = BTN_MIDDLE; break;
679 tp->buttons.active = button;
680 state = LIBINPUT_BUTTON_STATE_PRESSED;
682 button = tp->buttons.active;
683 tp->buttons.active = 0;
684 state = LIBINPUT_BUTTON_STATE_RELEASED;
688 pointer_notify_button(&tp->device->base,
696 tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
698 uint32_t current, old, button;
700 current = tp->buttons.state;
701 old = tp->buttons.old_state;
704 while (current || old) {
705 enum libinput_button_state state;
707 if ((current & 0x1) ^ (old & 0x1)) {
708 if (!!(current & 0x1))
709 state = LIBINPUT_BUTTON_STATE_PRESSED;
711 state = LIBINPUT_BUTTON_STATE_RELEASED;
713 pointer_notify_button(&tp->device->base,
728 tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
730 uint32_t current, old, button;
731 enum libinput_button_state state;
732 enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
734 current = tp->buttons.state;
735 old = tp->buttons.old_state;
738 if (!tp->buttons.click_pending && current == old)
744 tp_for_each_touch(tp, t) {
745 switch (t->button.curr) {
746 case BUTTON_EVENT_IN_AREA:
749 case BUTTON_EVENT_IN_BOTTOM_L:
750 case BUTTON_EVENT_IN_TOP_L:
753 case BUTTON_EVENT_IN_TOP_M:
756 case BUTTON_EVENT_IN_BOTTOM_R:
757 case BUTTON_EVENT_IN_TOP_R:
766 /* No touches, wait for a touch before processing */
767 tp->buttons.click_pending = true;
771 if ((button & MIDDLE) || ((button & LEFT) && (button & RIGHT)))
773 else if (button & RIGHT)
778 tp->buttons.active = button;
779 state = LIBINPUT_BUTTON_STATE_PRESSED;
781 button = tp->buttons.active;
782 tp->buttons.active = 0;
783 state = LIBINPUT_BUTTON_STATE_RELEASED;
786 tp->buttons.click_pending = false;
789 pointer_notify_button(&tp->device->base,
797 tp_post_button_events(struct tp_dispatch *tp, uint64_t time)
799 if (tp->buttons.is_clickpad) {
800 if (tp->buttons.use_clickfinger)
801 return tp_post_clickfinger_buttons(tp, time);
803 return tp_post_softbutton_buttons(tp, time);
806 return tp_post_physical_buttons(tp, time);
810 tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
812 return t->button.state == BUTTON_STATE_AREA;