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 <stdint.h> 27 28#include "evdev.h" 29 30#define MIDDLEBUTTON_TIMEOUT ms2us(50) 31 32/***************************************** 33 * BEFORE YOU EDIT THIS FILE, look at the state diagram in 34 * doc/middle-button-emulation-state-machine.svg (generated with 35 * https://www.diagrams.net). 36 * 37 * Any changes in this file must be represented in the diagram. 38 * 39 * Note in regards to the state machine: it only handles left, right and 40 * emulated middle button clicks, all other button events are passed 41 * through. When in the PASSTHROUGH state, all events are passed through 42 * as-is. 43 */ 44 45static inline const char* 46middlebutton_state_to_str(enum evdev_middlebutton_state state) 47{ 48 switch (state) { 49 CASE_RETURN_STRING(MIDDLEBUTTON_IDLE); 50 CASE_RETURN_STRING(MIDDLEBUTTON_LEFT_DOWN); 51 CASE_RETURN_STRING(MIDDLEBUTTON_RIGHT_DOWN); 52 CASE_RETURN_STRING(MIDDLEBUTTON_MIDDLE); 53 CASE_RETURN_STRING(MIDDLEBUTTON_LEFT_UP_PENDING); 54 CASE_RETURN_STRING(MIDDLEBUTTON_RIGHT_UP_PENDING); 55 CASE_RETURN_STRING(MIDDLEBUTTON_PASSTHROUGH); 56 CASE_RETURN_STRING(MIDDLEBUTTON_IGNORE_LR); 57 CASE_RETURN_STRING(MIDDLEBUTTON_IGNORE_L); 58 CASE_RETURN_STRING(MIDDLEBUTTON_IGNORE_R); 59 } 60 61 return NULL; 62} 63 64static inline const char* 65middlebutton_event_to_str(enum evdev_middlebutton_event event) 66{ 67 switch (event) { 68 CASE_RETURN_STRING(MIDDLEBUTTON_EVENT_L_DOWN); 69 CASE_RETURN_STRING(MIDDLEBUTTON_EVENT_R_DOWN); 70 CASE_RETURN_STRING(MIDDLEBUTTON_EVENT_OTHER); 71 CASE_RETURN_STRING(MIDDLEBUTTON_EVENT_L_UP); 72 CASE_RETURN_STRING(MIDDLEBUTTON_EVENT_R_UP); 73 CASE_RETURN_STRING(MIDDLEBUTTON_EVENT_TIMEOUT); 74 CASE_RETURN_STRING(MIDDLEBUTTON_EVENT_ALL_UP); 75 } 76 77 return NULL; 78} 79 80static void 81middlebutton_state_error(struct evdev_device *device, 82 enum evdev_middlebutton_event event) 83{ 84 evdev_log_bug_libinput(device, 85 "Invalid event %s in middle btn state %s\n", 86 middlebutton_event_to_str(event), 87 middlebutton_state_to_str(device->middlebutton.state)); 88} 89 90static void 91middlebutton_timer_set(struct evdev_device *device, uint64_t now) 92{ 93 libinput_timer_set(&device->middlebutton.timer, 94 now + MIDDLEBUTTON_TIMEOUT); 95} 96 97static void 98middlebutton_timer_cancel(struct evdev_device *device) 99{ 100 libinput_timer_cancel(&device->middlebutton.timer); 101} 102 103static inline void 104middlebutton_set_state(struct evdev_device *device, 105 enum evdev_middlebutton_state state, 106 uint64_t now) 107{ 108 switch (state) { 109 case MIDDLEBUTTON_LEFT_DOWN: 110 case MIDDLEBUTTON_RIGHT_DOWN: 111 middlebutton_timer_set(device, now); 112 device->middlebutton.first_event_time = now; 113 break; 114 case MIDDLEBUTTON_IDLE: 115 case MIDDLEBUTTON_MIDDLE: 116 case MIDDLEBUTTON_LEFT_UP_PENDING: 117 case MIDDLEBUTTON_RIGHT_UP_PENDING: 118 case MIDDLEBUTTON_PASSTHROUGH: 119 case MIDDLEBUTTON_IGNORE_LR: 120 case MIDDLEBUTTON_IGNORE_L: 121 case MIDDLEBUTTON_IGNORE_R: 122 middlebutton_timer_cancel(device); 123 break; 124 } 125 126 device->middlebutton.state = state; 127} 128 129static void 130middlebutton_post_event(struct evdev_device *device, 131 uint64_t now, 132 int button, 133 enum libinput_button_state state) 134{ 135 evdev_pointer_notify_button(device, 136 now, 137 button, 138 state); 139} 140 141static int 142evdev_middlebutton_idle_handle_event(struct evdev_device *device, 143 uint64_t time, 144 enum evdev_middlebutton_event event) 145{ 146 switch (event) { 147 case MIDDLEBUTTON_EVENT_L_DOWN: 148 middlebutton_set_state(device, MIDDLEBUTTON_LEFT_DOWN, time); 149 break; 150 case MIDDLEBUTTON_EVENT_R_DOWN: 151 middlebutton_set_state(device, MIDDLEBUTTON_RIGHT_DOWN, time); 152 break; 153 case MIDDLEBUTTON_EVENT_OTHER: 154 return 0; 155 case MIDDLEBUTTON_EVENT_R_UP: 156 case MIDDLEBUTTON_EVENT_L_UP: 157 case MIDDLEBUTTON_EVENT_TIMEOUT: 158 middlebutton_state_error(device, event); 159 break; 160 case MIDDLEBUTTON_EVENT_ALL_UP: 161 break; 162 } 163 164 return 1; 165} 166 167static int 168evdev_middlebutton_ldown_handle_event(struct evdev_device *device, 169 uint64_t time, 170 enum evdev_middlebutton_event event) 171{ 172 switch (event) { 173 case MIDDLEBUTTON_EVENT_L_DOWN: 174 middlebutton_state_error(device, event); 175 break; 176 case MIDDLEBUTTON_EVENT_R_DOWN: 177 middlebutton_post_event(device, time, 178 BTN_MIDDLE, 179 LIBINPUT_BUTTON_STATE_PRESSED); 180 middlebutton_set_state(device, MIDDLEBUTTON_MIDDLE, time); 181 break; 182 case MIDDLEBUTTON_EVENT_OTHER: 183 middlebutton_post_event(device, time, 184 BTN_LEFT, 185 LIBINPUT_BUTTON_STATE_PRESSED); 186 middlebutton_set_state(device, 187 MIDDLEBUTTON_PASSTHROUGH, 188 time); 189 return 0; 190 case MIDDLEBUTTON_EVENT_R_UP: 191 middlebutton_state_error(device, event); 192 break; 193 case MIDDLEBUTTON_EVENT_L_UP: 194 middlebutton_post_event(device, 195 device->middlebutton.first_event_time, 196 BTN_LEFT, 197 LIBINPUT_BUTTON_STATE_PRESSED); 198 middlebutton_post_event(device, time, 199 BTN_LEFT, 200 LIBINPUT_BUTTON_STATE_RELEASED); 201 middlebutton_set_state(device, MIDDLEBUTTON_IDLE, time); 202 break; 203 case MIDDLEBUTTON_EVENT_TIMEOUT: 204 middlebutton_post_event(device, 205 device->middlebutton.first_event_time, 206 BTN_LEFT, 207 LIBINPUT_BUTTON_STATE_PRESSED); 208 middlebutton_set_state(device, 209 MIDDLEBUTTON_PASSTHROUGH, 210 time); 211 break; 212 case MIDDLEBUTTON_EVENT_ALL_UP: 213 middlebutton_state_error(device, event); 214 break; 215 } 216 217 return 1; 218} 219 220static int 221evdev_middlebutton_rdown_handle_event(struct evdev_device *device, 222 uint64_t time, 223 enum evdev_middlebutton_event event) 224{ 225 switch (event) { 226 case MIDDLEBUTTON_EVENT_L_DOWN: 227 middlebutton_post_event(device, time, 228 BTN_MIDDLE, 229 LIBINPUT_BUTTON_STATE_PRESSED); 230 middlebutton_set_state(device, MIDDLEBUTTON_MIDDLE, time); 231 break; 232 case MIDDLEBUTTON_EVENT_R_DOWN: 233 middlebutton_state_error(device, event); 234 break; 235 case MIDDLEBUTTON_EVENT_OTHER: 236 middlebutton_post_event(device, 237 device->middlebutton.first_event_time, 238 BTN_RIGHT, 239 LIBINPUT_BUTTON_STATE_PRESSED); 240 middlebutton_set_state(device, 241 MIDDLEBUTTON_PASSTHROUGH, 242 time); 243 return 0; 244 case MIDDLEBUTTON_EVENT_R_UP: 245 middlebutton_post_event(device, 246 device->middlebutton.first_event_time, 247 BTN_RIGHT, 248 LIBINPUT_BUTTON_STATE_PRESSED); 249 middlebutton_post_event(device, time, 250 BTN_RIGHT, 251 LIBINPUT_BUTTON_STATE_RELEASED); 252 middlebutton_set_state(device, MIDDLEBUTTON_IDLE, time); 253 break; 254 case MIDDLEBUTTON_EVENT_L_UP: 255 middlebutton_state_error(device, event); 256 break; 257 case MIDDLEBUTTON_EVENT_TIMEOUT: 258 middlebutton_post_event(device, 259 device->middlebutton.first_event_time, 260 BTN_RIGHT, 261 LIBINPUT_BUTTON_STATE_PRESSED); 262 middlebutton_set_state(device, 263 MIDDLEBUTTON_PASSTHROUGH, 264 time); 265 break; 266 case MIDDLEBUTTON_EVENT_ALL_UP: 267 middlebutton_state_error(device, event); 268 break; 269 } 270 271 return 1; 272} 273 274static int 275evdev_middlebutton_middle_handle_event(struct evdev_device *device, 276 uint64_t time, 277 enum evdev_middlebutton_event event) 278{ 279 switch (event) { 280 case MIDDLEBUTTON_EVENT_L_DOWN: 281 case MIDDLEBUTTON_EVENT_R_DOWN: 282 middlebutton_state_error(device, event); 283 break; 284 case MIDDLEBUTTON_EVENT_OTHER: 285 middlebutton_post_event(device, time, 286 BTN_MIDDLE, 287 LIBINPUT_BUTTON_STATE_RELEASED); 288 middlebutton_set_state(device, MIDDLEBUTTON_IGNORE_LR, time); 289 return 0; 290 case MIDDLEBUTTON_EVENT_R_UP: 291 middlebutton_post_event(device, time, 292 BTN_MIDDLE, 293 LIBINPUT_BUTTON_STATE_RELEASED); 294 middlebutton_set_state(device, 295 MIDDLEBUTTON_LEFT_UP_PENDING, 296 time); 297 break; 298 case MIDDLEBUTTON_EVENT_L_UP: 299 middlebutton_post_event(device, time, 300 BTN_MIDDLE, 301 LIBINPUT_BUTTON_STATE_RELEASED); 302 middlebutton_set_state(device, 303 MIDDLEBUTTON_RIGHT_UP_PENDING, 304 time); 305 break; 306 case MIDDLEBUTTON_EVENT_TIMEOUT: 307 middlebutton_state_error(device, event); 308 break; 309 case MIDDLEBUTTON_EVENT_ALL_UP: 310 middlebutton_state_error(device, event); 311 break; 312 } 313 314 return 1; 315} 316 317static int 318evdev_middlebutton_lup_pending_handle_event(struct evdev_device *device, 319 uint64_t time, 320 enum evdev_middlebutton_event event) 321{ 322 switch (event) { 323 case MIDDLEBUTTON_EVENT_L_DOWN: 324 middlebutton_state_error(device, event); 325 break; 326 case MIDDLEBUTTON_EVENT_R_DOWN: 327 middlebutton_post_event(device, time, 328 BTN_MIDDLE, 329 LIBINPUT_BUTTON_STATE_PRESSED); 330 middlebutton_set_state(device, MIDDLEBUTTON_MIDDLE, time); 331 break; 332 case MIDDLEBUTTON_EVENT_OTHER: 333 middlebutton_set_state(device, MIDDLEBUTTON_IGNORE_L, time); 334 return 0; 335 case MIDDLEBUTTON_EVENT_R_UP: 336 middlebutton_state_error(device, event); 337 break; 338 case MIDDLEBUTTON_EVENT_L_UP: 339 middlebutton_set_state(device, MIDDLEBUTTON_IDLE, time); 340 break; 341 case MIDDLEBUTTON_EVENT_TIMEOUT: 342 middlebutton_state_error(device, event); 343 break; 344 case MIDDLEBUTTON_EVENT_ALL_UP: 345 middlebutton_state_error(device, event); 346 break; 347 } 348 349 return 1; 350} 351 352static int 353evdev_middlebutton_rup_pending_handle_event(struct evdev_device *device, 354 uint64_t time, 355 enum evdev_middlebutton_event event) 356{ 357 switch (event) { 358 case MIDDLEBUTTON_EVENT_L_DOWN: 359 middlebutton_post_event(device, time, 360 BTN_MIDDLE, 361 LIBINPUT_BUTTON_STATE_PRESSED); 362 middlebutton_set_state(device, MIDDLEBUTTON_MIDDLE, time); 363 break; 364 case MIDDLEBUTTON_EVENT_R_DOWN: 365 middlebutton_state_error(device, event); 366 break; 367 case MIDDLEBUTTON_EVENT_OTHER: 368 middlebutton_set_state(device, MIDDLEBUTTON_IGNORE_R, time); 369 return 0; 370 case MIDDLEBUTTON_EVENT_R_UP: 371 middlebutton_set_state(device, MIDDLEBUTTON_IDLE, time); 372 break; 373 case MIDDLEBUTTON_EVENT_L_UP: 374 middlebutton_state_error(device, event); 375 break; 376 case MIDDLEBUTTON_EVENT_TIMEOUT: 377 middlebutton_state_error(device, event); 378 break; 379 case MIDDLEBUTTON_EVENT_ALL_UP: 380 middlebutton_state_error(device, event); 381 break; 382 } 383 384 return 1; 385} 386 387static int 388evdev_middlebutton_passthrough_handle_event(struct evdev_device *device, 389 uint64_t time, 390 enum evdev_middlebutton_event event) 391{ 392 switch (event) { 393 case MIDDLEBUTTON_EVENT_L_DOWN: 394 case MIDDLEBUTTON_EVENT_R_DOWN: 395 case MIDDLEBUTTON_EVENT_OTHER: 396 case MIDDLEBUTTON_EVENT_R_UP: 397 case MIDDLEBUTTON_EVENT_L_UP: 398 return 0; 399 case MIDDLEBUTTON_EVENT_TIMEOUT: 400 middlebutton_state_error(device, event); 401 break; 402 case MIDDLEBUTTON_EVENT_ALL_UP: 403 middlebutton_set_state(device, MIDDLEBUTTON_IDLE, time); 404 break; 405 } 406 407 return 1; 408} 409 410static int 411evdev_middlebutton_ignore_lr_handle_event(struct evdev_device *device, 412 uint64_t time, 413 enum evdev_middlebutton_event event) 414{ 415 switch (event) { 416 case MIDDLEBUTTON_EVENT_L_DOWN: 417 case MIDDLEBUTTON_EVENT_R_DOWN: 418 middlebutton_state_error(device, event); 419 break; 420 case MIDDLEBUTTON_EVENT_OTHER: 421 return 0; 422 case MIDDLEBUTTON_EVENT_R_UP: 423 middlebutton_set_state(device, MIDDLEBUTTON_IGNORE_L, time); 424 break; 425 case MIDDLEBUTTON_EVENT_L_UP: 426 middlebutton_set_state(device, MIDDLEBUTTON_IGNORE_R, time); 427 break; 428 case MIDDLEBUTTON_EVENT_TIMEOUT: 429 middlebutton_state_error(device, event); 430 break; 431 case MIDDLEBUTTON_EVENT_ALL_UP: 432 middlebutton_state_error(device, event); 433 break; 434 } 435 436 return 1; 437} 438 439static int 440evdev_middlebutton_ignore_l_handle_event(struct evdev_device *device, 441 uint64_t time, 442 enum evdev_middlebutton_event event) 443{ 444 switch (event) { 445 case MIDDLEBUTTON_EVENT_L_DOWN: 446 middlebutton_state_error(device, event); 447 break; 448 case MIDDLEBUTTON_EVENT_R_DOWN: 449 return 0; 450 case MIDDLEBUTTON_EVENT_OTHER: 451 case MIDDLEBUTTON_EVENT_R_UP: 452 return 0; 453 case MIDDLEBUTTON_EVENT_L_UP: 454 middlebutton_set_state(device, 455 MIDDLEBUTTON_PASSTHROUGH, 456 time); 457 break; 458 case MIDDLEBUTTON_EVENT_TIMEOUT: 459 case MIDDLEBUTTON_EVENT_ALL_UP: 460 middlebutton_state_error(device, event); 461 break; 462 } 463 464 return 1; 465} 466static int 467evdev_middlebutton_ignore_r_handle_event(struct evdev_device *device, 468 uint64_t time, 469 enum evdev_middlebutton_event event) 470{ 471 switch (event) { 472 case MIDDLEBUTTON_EVENT_L_DOWN: 473 return 0; 474 case MIDDLEBUTTON_EVENT_R_DOWN: 475 middlebutton_state_error(device, event); 476 break; 477 case MIDDLEBUTTON_EVENT_OTHER: 478 return 0; 479 case MIDDLEBUTTON_EVENT_R_UP: 480 middlebutton_set_state(device, 481 MIDDLEBUTTON_PASSTHROUGH, 482 time); 483 break; 484 case MIDDLEBUTTON_EVENT_L_UP: 485 return 0; 486 case MIDDLEBUTTON_EVENT_TIMEOUT: 487 case MIDDLEBUTTON_EVENT_ALL_UP: 488 break; 489 } 490 491 return 1; 492} 493 494static int 495evdev_middlebutton_handle_event(struct evdev_device *device, 496 uint64_t time, 497 enum evdev_middlebutton_event event) 498{ 499 int rc = 0; 500 enum evdev_middlebutton_state current; 501 502 current = device->middlebutton.state; 503 504 switch (current) { 505 case MIDDLEBUTTON_IDLE: 506 rc = evdev_middlebutton_idle_handle_event(device, time, event); 507 break; 508 case MIDDLEBUTTON_LEFT_DOWN: 509 rc = evdev_middlebutton_ldown_handle_event(device, time, event); 510 break; 511 case MIDDLEBUTTON_RIGHT_DOWN: 512 rc = evdev_middlebutton_rdown_handle_event(device, time, event); 513 break; 514 case MIDDLEBUTTON_MIDDLE: 515 rc = evdev_middlebutton_middle_handle_event(device, time, event); 516 break; 517 case MIDDLEBUTTON_LEFT_UP_PENDING: 518 rc = evdev_middlebutton_lup_pending_handle_event(device, 519 time, 520 event); 521 break; 522 case MIDDLEBUTTON_RIGHT_UP_PENDING: 523 rc = evdev_middlebutton_rup_pending_handle_event(device, 524 time, 525 event); 526 break; 527 case MIDDLEBUTTON_PASSTHROUGH: 528 rc = evdev_middlebutton_passthrough_handle_event(device, 529 time, 530 event); 531 break; 532 case MIDDLEBUTTON_IGNORE_LR: 533 rc = evdev_middlebutton_ignore_lr_handle_event(device, 534 time, 535 event); 536 break; 537 case MIDDLEBUTTON_IGNORE_L: 538 rc = evdev_middlebutton_ignore_l_handle_event(device, 539 time, 540 event); 541 break; 542 case MIDDLEBUTTON_IGNORE_R: 543 rc = evdev_middlebutton_ignore_r_handle_event(device, 544 time, 545 event); 546 break; 547 default: 548 evdev_log_bug_libinput(device, 549 "Invalid middle button state %d\n", 550 current); 551 break; 552 } 553 554 evdev_log_debug(device, 555 "middlebutton state: %s → %s → %s, rc %d\n", 556 middlebutton_state_to_str(current), 557 middlebutton_event_to_str(event), 558 middlebutton_state_to_str(device->middlebutton.state), 559 rc); 560 561 return rc; 562} 563 564static inline void 565evdev_middlebutton_apply_config(struct evdev_device *device) 566{ 567 if (device->middlebutton.want_enabled == 568 device->middlebutton.enabled) 569 return; 570 571 if (device->middlebutton.button_mask != 0) 572 return; 573 574 device->middlebutton.enabled = device->middlebutton.want_enabled; 575} 576 577bool 578evdev_middlebutton_filter_button(struct evdev_device *device, 579 uint64_t time, 580 int button, 581 enum libinput_button_state state) 582{ 583 enum evdev_middlebutton_event event; 584 bool is_press = state == LIBINPUT_BUTTON_STATE_PRESSED; 585 int rc; 586 unsigned int btnbit = (button - BTN_LEFT); 587 uint32_t old_mask = 0; 588 589 if (!device->middlebutton.enabled) 590 return false; 591 592 switch (button) { 593 case BTN_LEFT: 594 if (is_press) 595 event = MIDDLEBUTTON_EVENT_L_DOWN; 596 else 597 event = MIDDLEBUTTON_EVENT_L_UP; 598 break; 599 case BTN_RIGHT: 600 if (is_press) 601 event = MIDDLEBUTTON_EVENT_R_DOWN; 602 else 603 event = MIDDLEBUTTON_EVENT_R_UP; 604 break; 605 606 /* BTN_MIDDLE counts as "other" and resets middle button 607 * emulation */ 608 case BTN_MIDDLE: 609 default: 610 event = MIDDLEBUTTON_EVENT_OTHER; 611 break; 612 } 613 614 if (button < BTN_LEFT || 615 btnbit >= sizeof(device->middlebutton.button_mask) * 8) { 616 evdev_log_bug_libinput(device, 617 "Button mask too small for %s\n", 618 libevdev_event_code_get_name(EV_KEY, 619 button)); 620 return true; 621 } 622 623 rc = evdev_middlebutton_handle_event(device, time, event); 624 625 old_mask = device->middlebutton.button_mask; 626 if (is_press) 627 device->middlebutton.button_mask |= bit(btnbit); 628 else 629 device->middlebutton.button_mask &= ~bit(btnbit); 630 631 if (old_mask != device->middlebutton.button_mask && 632 device->middlebutton.button_mask == 0) { 633 evdev_middlebutton_handle_event(device, 634 time, 635 MIDDLEBUTTON_EVENT_ALL_UP); 636 evdev_middlebutton_apply_config(device); 637 } 638 639 return rc; 640} 641 642static void 643evdev_middlebutton_handle_timeout(uint64_t now, void *data) 644{ 645 struct evdev_device *device = evdev_device(data); 646 647 evdev_middlebutton_handle_event(device, now, MIDDLEBUTTON_EVENT_TIMEOUT); 648} 649 650int 651evdev_middlebutton_is_available(struct libinput_device *device) 652{ 653 return 1; 654} 655 656static enum libinput_config_status 657evdev_middlebutton_set(struct libinput_device *device, 658 enum libinput_config_middle_emulation_state enable) 659{ 660 struct evdev_device *evdev = evdev_device(device); 661 662 switch (enable) { 663 case LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED: 664 evdev->middlebutton.want_enabled = true; 665 break; 666 case LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED: 667 evdev->middlebutton.want_enabled = false; 668 break; 669 default: 670 return LIBINPUT_CONFIG_STATUS_INVALID; 671 } 672 673 evdev_middlebutton_apply_config(evdev); 674 675 return LIBINPUT_CONFIG_STATUS_SUCCESS; 676} 677 678enum libinput_config_middle_emulation_state 679evdev_middlebutton_get(struct libinput_device *device) 680{ 681 struct evdev_device *evdev = evdev_device(device); 682 683 return evdev->middlebutton.want_enabled ? 684 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED : 685 LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; 686} 687 688enum libinput_config_middle_emulation_state 689evdev_middlebutton_get_default(struct libinput_device *device) 690{ 691 struct evdev_device *evdev = evdev_device(device); 692 693 return evdev->middlebutton.enabled_default ? 694 LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED : 695 LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; 696} 697 698void 699evdev_init_middlebutton(struct evdev_device *device, 700 bool enable, 701 bool want_config) 702{ 703 char timer_name[64]; 704 705 snprintf(timer_name, 706 sizeof(timer_name), 707 "%s middlebutton", 708 evdev_device_get_sysname(device)); 709 libinput_timer_init(&device->middlebutton.timer, 710 evdev_libinput_context(device), 711 timer_name, 712 evdev_middlebutton_handle_timeout, 713 device); 714 device->middlebutton.enabled_default = enable; 715 device->middlebutton.want_enabled = enable; 716 device->middlebutton.enabled = enable; 717 718 if (!want_config) 719 return; 720 721 device->middlebutton.config.available = evdev_middlebutton_is_available; 722 device->middlebutton.config.set = evdev_middlebutton_set; 723 device->middlebutton.config.get = evdev_middlebutton_get; 724 device->middlebutton.config.get_default = evdev_middlebutton_get_default; 725 device->base.config.middle_emulation = &device->middlebutton.config; 726} 727