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