mouseEmu3btn.c revision e8a9312a
1/* 2 * 3 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 4 * Copyright 1993 by David Dawes <dawes@xfree86.org> 5 * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich 6 * Copyright 1994-2002 by The XFree86 Project, Inc. 7 * Copyright 2002 by Paul Elliott 8 * 9 * Permission to use, copy, modify, distribute, and sell this software and its 10 * documentation for any purpose is hereby granted without fee, provided that 11 * the above copyright notice appear in all copies and that both that 12 * copyright notice and this permission notice appear in supporting 13 * documentation, and that the names of copyright holders not be 14 * used in advertising or publicity pertaining to distribution of the 15 * software without specific, written prior permission. The copyright holders 16 * make no representations about the suitability of this 17 * software for any purpose. It is provided "as is" without express or 18 * implied warranty. 19 * 20 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 21 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 24 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 25 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 26 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 27 * 28 */ 29 30/* 31 * 3 button emulation stuff 32 * based on the emulation method in xf86-input-mouse/dist/src/mouse.c 33 */ 34 35#include "inpututils.h" 36#include "mouseEmu3btn.h" 37 38static CARD32 buttonTimer(MouseEmu3btnPtr pEmu3btn); 39static void Emulate3ButtonsSetEnabled(MouseEmu3btnPtr pEmu3btn, Bool enable); 40static Bool Emulate3ButtonsSoft(MouseEmu3btnPtr pEmu3btn); 41 42static void MouseBlockHandler(void *data, void *waitTime); 43static void MouseWakeupHandler(void *data, int i); 44 45/********************************************************************** 46 * 47 * Emulate3Button support code 48 * 49 **********************************************************************/ 50 51 52/* 53 * Lets create a simple finite-state machine for 3 button emulation: 54 * 55 * We track buttons 1 and 3 (left and right). There are 11 states: 56 * 0 ground - initial state 57 * 1 delayed left - left pressed, waiting for right 58 * 2 delayed right - right pressed, waiting for left 59 * 3 pressed middle - right and left pressed, emulated middle sent 60 * 4 pressed left - left pressed and sent 61 * 5 pressed right - right pressed and sent 62 * 6 released left - left released after emulated middle 63 * 7 released right - right released after emulated middle 64 * 8 repressed left - left pressed after released left 65 * 9 repressed right - right pressed after released right 66 * 10 pressed both - both pressed, not emulating middle 67 */ 68#define ST_INVALID -1 69#define ST_GROUND 0 /* initial state */ 70#define ST_DELAYED_LEFT 1 /* left pressed and waiting timeout */ 71#define ST_DELAYED_RIGHT 2 /* right pressed and waiting timeout */ 72#define ST_PRESSED_MIDDLE 3 /* middle pressed deteremined */ 73#define ST_PRESSED_LEFT 4 /* left pressed determined */ 74#define ST_PRESSED_RIGHT 5 /* right pressed determined */ 75#define ST_RELEASED_LEFT 6 /* left released after pressed both */ 76#define ST_RELEASED_RIGHT 7 /* right released after pressed both */ 77#define ST_REPRESSED_LEFT 8 /* left repressed after release */ 78#define ST_REPRESSED_RIGHT 9 /* right repressed after release */ 79#define ST_PRESSED_BOTH 10 /* both pressed (not as middle) */ 80#define NSTATES 11 81 82/* 83 * At each state, we need handlers for the following events 84 * 0: no buttons down 85 * 1: left button down 86 * 2: right button down 87 * 3: both buttons down 88 * 4: emulate3Timeout passed without a button change 89 * Note that button events are not deltas, they are the set of buttons being 90 * pressed now. It's possible (ie, mouse hardware does it) to go from (eg) 91 * left down to right down without anything in between, so all cases must be 92 * handled. 93 * 94 * a handler consists of three values: 95 * 0: action1 96 * 1: action2 97 * 2: new emulation state 98 */ 99struct button_event { 100 int type; /* ButtonNone / ButtonPress / ButtonRelease */ 101#define ButtonNone 0 102 int button; 103#define ButtonLeft Button1 104#define ButtonMiddle Button2 105#define ButtonRight Button3 106}; 107 108struct button_action { 109 struct button_event event1; 110 struct button_event event2; 111 int new_state; 112}; 113 114/* The set of buttons being pressed passed from DDX mouse events */ 115#define BMASK_LEFT 0x01 116#define BMASK_MIDDLE 0x02 117#define BMASK_RIGHT 0x04 118 119/* Event index values per buttons being pressed */ 120#define EMU_BUTTONS_NONE 0 121#define EMU_BUTTONS_LEFT 1 122#define EMU_BUTTONS_RIGHT 2 123#define EMU_BUTTONS_BOTH 3 124#define NEMU_BUTTONSTATE 4 125 126#define BMASKTOINDEX(bmask) \ 127 ((((bmask) & BMASK_RIGHT) >> 1) | ((bmask) & BMASK_LEFT)) 128 129struct button_state { 130 struct button_action buttons[NEMU_BUTTONSTATE]; 131 struct button_action timeout; 132}; 133 134/* 135 * The comment preceeding each section is the current emulation state. 136 * The comments to the right are of the form 137 * <button state> (<events>) -> <new emulation state> 138 * which should be read as 139 * If the buttons are in <button state>, generate <events> then go to 140 * <new emulation state>. 141 */ 142static const struct button_state stateTab[NSTATES] = { 143 144 /* 0 ground - initial state */ 145 [ST_GROUND] = { 146 147 .buttons[EMU_BUTTONS_NONE] = { 148 /* nothing -> ground (no change) */ 149 .event1 = { ButtonNone, 0 }, 150 .event2 = { ButtonNone, 0 }, 151 .new_state = ST_GROUND, 152 }, 153 154 .buttons[EMU_BUTTONS_LEFT] = { 155 /* left -> delayed left */ 156 .event1 = { ButtonNone, 0 }, 157 .event2 = { ButtonNone, 0 }, 158 .new_state = ST_DELAYED_LEFT, 159 }, 160 161 .buttons[EMU_BUTTONS_RIGHT] = { 162 /* right -> delayed right */ 163 .event1 = { ButtonNone, 0 }, 164 .event2 = { ButtonNone, 0 }, 165 .new_state = ST_DELAYED_RIGHT, 166 }, 167 168 .buttons[EMU_BUTTONS_BOTH] = { 169 /* left & right (middle press) -> pressed middle */ 170 .event1 = { ButtonPress, ButtonMiddle }, 171 .event2 = { ButtonNone, 0 }, 172 .new_state = ST_PRESSED_MIDDLE, 173 }, 174 175 .timeout = { 176 /* timeout N/A */ 177 .event1 = { ButtonNone, 0 }, 178 .event2 = { ButtonNone, 0 }, 179 .new_state = ST_INVALID, 180 }, 181 }, 182 183 /* 1 delayed left - left pressed, waiting for right */ 184 [ST_DELAYED_LEFT] = { 185 186 .buttons[EMU_BUTTONS_NONE] = { 187 /* nothing (left event) -> ground */ 188 .event1 = { ButtonPress, ButtonLeft }, 189 .event2 = { ButtonRelease, ButtonLeft }, 190 .new_state = ST_GROUND, 191 }, 192 193 .buttons[EMU_BUTTONS_LEFT] = { 194 /* left -> delayed left (no change) */ 195 .event1 = { ButtonNone, 0 }, 196 .event2 = { ButtonNone, 0 }, 197 .new_state = ST_DELAYED_LEFT, 198 }, 199 200 .buttons[EMU_BUTTONS_RIGHT] = { 201 /* right (left event) -> delayed right */ 202 .event1 = { ButtonPress, ButtonLeft }, 203 .event2 = { ButtonRelease, ButtonLeft }, 204 .new_state = ST_DELAYED_RIGHT, 205 }, 206 207 .buttons[EMU_BUTTONS_BOTH] = { 208 /* left & right (middle press) -> pressed middle */ 209 .event1 = { ButtonPress, ButtonMiddle }, 210 .event2 = { ButtonNone, 0 }, 211 .new_state = ST_PRESSED_MIDDLE, 212 }, 213 214 .timeout = { 215 /* timeout (left press) -> pressed left */ 216 .event1 = { ButtonPress, ButtonLeft }, 217 .event2 = { ButtonNone, 0 }, 218 .new_state = ST_PRESSED_LEFT, 219 }, 220 }, 221 222 /* 2 delayed right - right pressed, waiting for left */ 223 [ST_DELAYED_RIGHT] = { 224 225 .buttons[EMU_BUTTONS_NONE] = { 226 /* nothing (right event) -> ground */ 227 .event1 = { ButtonPress, ButtonRight }, 228 .event2 = { ButtonRelease, ButtonRight }, 229 .new_state = ST_GROUND, 230 }, 231 232 .buttons[EMU_BUTTONS_LEFT] = { 233 /* left (right event) -> delayed left */ 234 .event1 = { ButtonPress, ButtonRight }, 235 .event2 = { ButtonRelease, ButtonRight }, 236 .new_state = ST_DELAYED_LEFT, 237 }, 238 239 .buttons[EMU_BUTTONS_RIGHT] = { 240 /* right -> delayed right (no change) */ 241 .event1 = { ButtonNone, 0 }, 242 .event2 = { ButtonNone, 0 }, 243 .new_state = ST_DELAYED_RIGHT, 244 }, 245 246 .buttons[EMU_BUTTONS_BOTH] = { 247 /* left & right (middle press) -> pressed middle */ 248 .event1 = { ButtonPress, ButtonMiddle }, 249 .event2 = { ButtonNone, 0 }, 250 .new_state = ST_PRESSED_MIDDLE, 251 }, 252 253 .timeout = { 254 /* timeout (right press) -> pressed right */ 255 .event1 = { ButtonPress, ButtonRight }, 256 .event2 = { ButtonNone, 0 }, 257 .new_state = ST_PRESSED_RIGHT, 258 }, 259 }, 260 261 /* 3 pressed middle - right and left pressed, emulated middle sent */ 262 [ST_PRESSED_MIDDLE] = { 263 264 .buttons[EMU_BUTTONS_NONE] = { 265 /* nothing (middle release) -> ground */ 266 .event1 = { ButtonRelease, ButtonMiddle }, 267 .event2 = { ButtonNone, 0 }, 268 .new_state = ST_GROUND, 269 }, 270 271 .buttons[EMU_BUTTONS_LEFT] = { 272 /* left -> released right */ 273 .event1 = { ButtonNone, 0 }, 274 .event2 = { ButtonNone, 0 }, 275 .new_state = ST_RELEASED_RIGHT, 276 }, 277 278 .buttons[EMU_BUTTONS_RIGHT] = { 279 /* right -> released left */ 280 .event1 = { ButtonNone, 0 }, 281 .event2 = { ButtonNone, 0 }, 282 .new_state = ST_RELEASED_LEFT, 283 }, 284 285 .buttons[EMU_BUTTONS_BOTH] = { 286 /* left & right -> pressed middle (no change) */ 287 .event1 = { ButtonNone, 0 }, 288 .event2 = { ButtonNone, 0 }, 289 .new_state = ST_PRESSED_MIDDLE, 290 }, 291 292 .timeout = { 293 /* timeout N/A */ 294 .event1 = { ButtonNone, 0 }, 295 .event2 = { ButtonNone, 0 }, 296 .new_state = ST_INVALID, 297 }, 298 }, 299 300 /* 4 pressed left - left pressed and sent */ 301 [ST_PRESSED_LEFT] = { 302 303 .buttons[EMU_BUTTONS_NONE] = { 304 /* nothing (left release) -> ground */ 305 .event1 = { ButtonRelease, ButtonLeft }, 306 .event2 = { ButtonNone, 0 }, 307 .new_state = ST_GROUND, 308 }, 309 310 .buttons[EMU_BUTTONS_LEFT] = { 311 /* left -> pressed left (no change) */ 312 .event1 = { ButtonNone, 0 }, 313 .event2 = { ButtonNone, 0 }, 314 .new_state = ST_PRESSED_LEFT, 315 }, 316 317 .buttons[EMU_BUTTONS_RIGHT] = { 318 /* right (left release) -> delayed right */ 319 .event1 = { ButtonRelease, ButtonLeft }, 320 .event2 = { ButtonNone, 0 }, 321 .new_state = ST_DELAYED_RIGHT, 322 }, 323 324 .buttons[EMU_BUTTONS_BOTH] = { 325 /* left & right (right press) -> pressed both */ 326 .event1 = { ButtonPress, ButtonRight }, 327 .event2 = { ButtonNone, 0 }, 328 .new_state = ST_PRESSED_BOTH, 329 }, 330 331 .timeout = { 332 /* timeout N/A */ 333 .event1 = { ButtonNone, 0 }, 334 .event2 = { ButtonNone, 0 }, 335 .new_state = ST_INVALID, 336 }, 337 }, 338 339 /* 5 pressed right - right pressed and sent */ 340 [ST_PRESSED_RIGHT] = { 341 342 .buttons[EMU_BUTTONS_NONE] = { 343 /* nothing (right release) -> ground */ 344 .event1 = { ButtonRelease, ButtonRight }, 345 .event2 = { ButtonNone, 0 }, 346 .new_state = ST_GROUND, 347 }, 348 349 .buttons[EMU_BUTTONS_LEFT] = { 350 /* left (right release) -> delayed left */ 351 .event1 = { ButtonRelease, ButtonRight }, 352 .event2 = { ButtonNone, 0 }, 353 .new_state = ST_DELAYED_LEFT, 354 }, 355 356 .buttons[EMU_BUTTONS_RIGHT] = { 357 /* right -> pressed right (no change) */ 358 .event1 = { ButtonNone, 0 }, 359 .event2 = { ButtonNone, 0 }, 360 .new_state = ST_PRESSED_RIGHT, 361 }, 362 363 .buttons[EMU_BUTTONS_BOTH] = { 364 /* left & right (left press) -> pressed both */ 365 .event1 = { ButtonPress, ButtonLeft }, 366 .event2 = { ButtonNone, 0 }, 367 .new_state = ST_PRESSED_BOTH, 368 }, 369 370 .timeout = { 371 /* timeout N/A */ 372 .event1 = { ButtonNone, 0 }, 373 .event2 = { ButtonNone, 0 }, 374 .new_state = ST_INVALID, 375 }, 376 }, 377 378 /* 6 released left - left released after emulated middle */ 379 [ST_RELEASED_LEFT] = { 380 381 .buttons[EMU_BUTTONS_NONE] = { 382 /* nothing (middle release) -> ground */ 383 .event1 = { ButtonRelease, ButtonMiddle }, 384 .event2 = { ButtonNone, 0 }, 385 .new_state = ST_GROUND, 386 }, 387 388 .buttons[EMU_BUTTONS_LEFT] = { 389 /* left (middle release) -> delayed left */ 390 .event1 = { ButtonRelease, ButtonMiddle }, 391 .event2 = { ButtonNone, 0 }, 392 .new_state = ST_DELAYED_LEFT, 393 }, 394 395 .buttons[EMU_BUTTONS_RIGHT] = { 396 /* right -> released left (no change) */ 397 .event1 = { ButtonNone, 0 }, 398 .event2 = { ButtonNone, 0 }, 399 .new_state = ST_RELEASED_LEFT, 400 }, 401 402 .buttons[EMU_BUTTONS_BOTH] = { 403 /* left & right (left press) -> repressed left */ 404 .event1 = { ButtonPress, ButtonLeft }, 405 .event2 = { ButtonNone, 0 }, 406 .new_state = ST_REPRESSED_LEFT, 407 }, 408 409 .timeout = { 410 /* timeout N/A */ 411 .event1 = { ButtonNone, 0 }, 412 .event2 = { ButtonNone, 0 }, 413 .new_state = ST_INVALID, 414 }, 415 }, 416 417 /* 7 released right - right released after emulated middle */ 418 [ST_RELEASED_RIGHT] = { 419 420 .buttons[EMU_BUTTONS_NONE] = { 421 /* nothing (middle release) -> ground */ 422 .event1 = { ButtonRelease, ButtonMiddle }, 423 .event2 = { ButtonNone, 0 }, 424 .new_state = ST_GROUND, 425 }, 426 427 .buttons[EMU_BUTTONS_LEFT] = { 428 /* left -> released right (no change) */ 429 .event1 = { ButtonNone, 0 }, 430 .event2 = { ButtonNone, 0 }, 431 .new_state = ST_RELEASED_RIGHT, 432 }, 433 434 .buttons[EMU_BUTTONS_RIGHT] = { 435 /* right (middle release) -> delayed right */ 436 .event1 = { ButtonRelease, ButtonMiddle }, 437 .event2 = { ButtonNone, 0 }, 438 .new_state = ST_DELAYED_RIGHT, 439 }, 440 441 .buttons[EMU_BUTTONS_BOTH] = { 442 /* left & right (right press) -> repressed right */ 443 .event1 = { ButtonPress, ButtonRight }, 444 .event2 = { ButtonNone, 0 }, 445 .new_state = ST_REPRESSED_RIGHT, 446 }, 447 448 .timeout = { 449 /* timeout N/A */ 450 .event1 = { ButtonNone, 0 }, 451 .event2 = { ButtonNone, 0 }, 452 .new_state = ST_INVALID, 453 }, 454 }, 455 456 /* 8 repressed left - left pressed after released left */ 457 [ST_REPRESSED_LEFT] = { 458 459 .buttons[EMU_BUTTONS_NONE] = { 460 /* nothing (middle release, left release) -> ground */ 461 .event1 = { ButtonRelease, ButtonMiddle }, 462 .event2 = { ButtonRelease, ButtonLeft }, 463 .new_state = ST_GROUND, 464 }, 465 466 .buttons[EMU_BUTTONS_LEFT] = { 467 /* left (middle release) -> pressed left */ 468 .event1 = { ButtonRelease, ButtonMiddle }, 469 .event2 = { ButtonNone, 0 }, 470 .new_state = ST_PRESSED_LEFT, 471 }, 472 473 .buttons[EMU_BUTTONS_RIGHT] = { 474 /* right (left release) -> released left */ 475 .event1 = { ButtonRelease, ButtonLeft }, 476 .event2 = { ButtonNone, 0 }, 477 .new_state = ST_RELEASED_LEFT, 478 }, 479 480 .buttons[EMU_BUTTONS_BOTH] = { 481 /* left & right -> repressed left (no change) */ 482 .event1 = { ButtonNone, 0 }, 483 .event2 = { ButtonNone, 0 }, 484 .new_state = ST_REPRESSED_LEFT, 485 }, 486 487 .timeout = { 488 /* timeout N/A */ 489 .event1 = { ButtonNone, 0 }, 490 .event2 = { ButtonNone, 0 }, 491 .new_state = ST_INVALID, 492 }, 493 }, 494 495 /* 9 repressed right - right pressed after released right */ 496 [ST_REPRESSED_RIGHT] = { 497 498 .buttons[EMU_BUTTONS_NONE] = { 499 /* nothing (middle release, right release) -> ground */ 500 .event1 = { ButtonRelease, ButtonMiddle }, 501 .event2 = { ButtonRelease, ButtonRight }, 502 .new_state = ST_GROUND, 503 }, 504 505 .buttons[EMU_BUTTONS_LEFT] = { 506 /* left (right release) -> released right */ 507 .event1 = { ButtonRelease, ButtonRight }, 508 .event2 = { ButtonNone, 0 }, 509 .new_state = ST_RELEASED_RIGHT, 510 }, 511 512 .buttons[EMU_BUTTONS_RIGHT] = { 513 /* right (middle release) -> pressed right */ 514 .event1 = { ButtonRelease, ButtonMiddle }, 515 .event2 = { ButtonNone, 0 }, 516 .new_state = ST_PRESSED_RIGHT, 517 }, 518 519 .buttons[EMU_BUTTONS_BOTH] = { 520 /* left & right -> repressed right (no change) */ 521 .event1 = { ButtonNone, 0 }, 522 .event2 = { ButtonNone, 0 }, 523 .new_state = ST_REPRESSED_RIGHT, 524 }, 525 526 .timeout = { 527 /* timeout N/A */ 528 .event1 = { ButtonNone, 0 }, 529 .event2 = { ButtonNone, 0 }, 530 .new_state = ST_INVALID, 531 }, 532 }, 533 534 /* 10 pressed both - both pressed, not emulating middle */ 535 [ST_PRESSED_BOTH] = { 536 537 .buttons[EMU_BUTTONS_NONE] = { 538 /* nothing (left release, right release) -> ground */ 539 .event1 = { ButtonRelease, ButtonLeft }, 540 .event2 = { ButtonRelease, ButtonRight }, 541 .new_state = ST_GROUND, 542 }, 543 544 .buttons[EMU_BUTTONS_LEFT] = { 545 /* left (right release) -> pressed left */ 546 .event1 = { ButtonRelease, ButtonRight }, 547 .event2 = { ButtonNone, 0 }, 548 .new_state = ST_PRESSED_LEFT, 549 }, 550 551 .buttons[EMU_BUTTONS_RIGHT] = { 552 /* right (left release) -> pressed right */ 553 .event1 = { ButtonRelease, ButtonLeft }, 554 .event2 = { ButtonNone, 0 }, 555 .new_state = ST_PRESSED_RIGHT, 556 }, 557 558 .buttons[EMU_BUTTONS_BOTH] = { 559 /* left & right -> pressed both (no change) */ 560 .event1 = { ButtonNone, 0 }, 561 .event2 = { ButtonNone, 0 }, 562 .new_state = ST_PRESSED_BOTH, 563 }, 564 565 .timeout = { 566 /* timeout N/A */ 567 .event1 = { ButtonNone, 0 }, 568 .event2 = { ButtonNone, 0 }, 569 .new_state = ST_INVALID, 570 }, 571 }, 572}; 573 574static CARD32 575buttonTimer(MouseEmu3btnPtr pEmu3btn) 576{ 577 sigset_t sigmask; 578 int type, button, flag; 579 ValuatorMask mask; 580 const struct button_action *timeout_action; 581 582 (void)sigemptyset(&sigmask); 583 (void)sigaddset(&sigmask, SIGIO); 584 (void)sigprocmask(SIG_BLOCK, &sigmask, NULL); 585 586 pEmu3btn->emulate3Pending = FALSE; 587 timeout_action = &stateTab[pEmu3btn->emulateState].timeout; 588 if ((type = timeout_action->event1.type) != ButtonNone) { 589 button = timeout_action->event1.button; 590 flag = POINTER_RELATIVE; 591 valuator_mask_zero(&mask); 592 QueuePointerEvents(pEmu3btn->device, type, button, flag, &mask); 593 pEmu3btn->emulateState = timeout_action->new_state; 594 } else { 595 LogMessageVerbSigSafe(X_WARNING, -1, 596 "Got unexpected buttonTimer in state %d\n", pEmu3btn->emulateState); 597 } 598 599 (void)sigprocmask(SIG_UNBLOCK, &sigmask, NULL); 600 return 0; 601} 602 603static void 604Emulate3ButtonsSetEnabled(MouseEmu3btnPtr pEmu3btn, Bool enable) 605{ 606 607 if (pEmu3btn->emulate3Buttons == enable) 608 return; 609 610 pEmu3btn->emulate3Buttons = enable; 611 612 if (enable) { 613 pEmu3btn->emulateState = ST_GROUND; 614 pEmu3btn->emulate3Pending = FALSE; 615 pEmu3btn->emulate3ButtonsSoft = FALSE; /* specifically requested now */ 616 617 RegisterBlockAndWakeupHandlers(MouseBlockHandler, MouseWakeupHandler, 618 (void *)pEmu3btn); 619 } else { 620 if (pEmu3btn->emulate3Pending) 621 buttonTimer(pEmu3btn); 622 623 RemoveBlockAndWakeupHandlers(MouseBlockHandler, MouseWakeupHandler, 624 (void *)pEmu3btn); 625 } 626} 627 628static Bool 629Emulate3ButtonsSoft(MouseEmu3btnPtr pEmu3btn) 630{ 631 632 if (!pEmu3btn->emulate3ButtonsSoft) 633 return TRUE; 634 635#if defined(__NetBSD__) && defined(WSCONS_SUPPORT) 636 /* 637 * On NetBSD a wsmouse is a multiplexed device. Imagine a notebook 638 * with two-button mousepad, and an external USB mouse plugged in 639 * temporarily. After using button 3 on the external mouse and 640 * unplugging it again, the mousepad will still need to emulate 641 * 3 buttons. 642 */ 643 return TRUE; 644#else 645 LogMessageVerbSigSafe(X_INFO, 4, 646 "mouse: 3rd Button detected: disabling emulate3Button\n"); 647 648 Emulate3ButtonsSetEnabled(pEmu3btn, FALSE); 649 650 return FALSE; 651#endif 652} 653 654static void 655MouseBlockHandler(void *data, void *waitTime) 656{ 657 MouseEmu3btnPtr pEmu3btn = data; 658 int ms; 659 660 if (pEmu3btn->emulate3Pending) { 661 ms = pEmu3btn->emulate3Expires - GetTimeInMillis(); 662 if (ms <= 0) 663 ms = 0; 664 AdjustWaitForDelay(waitTime, ms); 665 } 666} 667 668static void 669MouseWakeupHandler(void *data, int i) 670{ 671 MouseEmu3btnPtr pEmu3btn = data; 672 int ms; 673 674 if (pEmu3btn->emulate3Pending) { 675 ms = pEmu3btn->emulate3Expires - GetTimeInMillis(); 676 if (ms <= 0) 677 buttonTimer(pEmu3btn); 678 } 679} 680 681/******************************************************************* 682 * function "Emulate3ButtonsEnable" 683 * 684 * purpose: 685 * Enable and initialize Emulate3Buttons structures. 686 * argument: 687 * (MouseEmu3btnPtr)pEmu3btn : Emu3btn private record 688 * (DeviceIntPtr)device : pointer device private record 689 * (int)timeout : timeout to wait another button [ms] 690 * 691 *******************************************************************/ 692void 693Emulate3ButtonsEnable(MouseEmu3btnPtr pEmu3btn, DeviceIntPtr device, int timeout) 694{ 695 696 BUG_RETURN_MSG(device == NULL, "Invalid DeviceIntPtr.\n"); 697 698 if (timeout <= 0) { 699 timeout = EMU3B_DEF_TIMEOUT; 700 } 701 pEmu3btn->device = device; 702 pEmu3btn->emulate3Timeout = timeout; 703 704 Emulate3ButtonsSetEnabled(pEmu3btn, TRUE); 705} 706 707/******************************************************************* 708 * function "Emulate3ButtonsQueueEvent" 709 * 710 * purpose: 711 * Emulate middle button per left/right button events and post events. 712 * argument: 713 * (MouseEmu3btnPtr)pEmu3btn : Emu3btn private record 714 * (int)type : event (ButtonPress / ButtonRelease) 715 * (int)buttons : button (Button1 / Button2 / Button3) 716 * (int)bmask : buttons being pressed (0x1:left / 0x4:right) 717 * 718 *******************************************************************/ 719 720void 721Emulate3ButtonsQueueEvent(MouseEmu3btnPtr pEmu3btn, int type, int buttons, int bmask) 722{ 723 DeviceIntPtr device = pEmu3btn->device; 724 int emulateButtons; 725 int button, flag; 726 ValuatorMask mask; 727 728 BUG_RETURN_MSG(buttons != ButtonLeft && buttons != ButtonRight, 729 "not left or right button event\n"); 730 731 if (pEmu3btn->emulate3ButtonsSoft && pEmu3btn->emulate3Pending) 732 buttonTimer(pEmu3btn); 733 734 if (pEmu3btn->emulate3Buttons 735 && ((bmask & BMASK_MIDDLE) == 0 || Emulate3ButtonsSoft(pEmu3btn))) { 736 const struct button_action *button_action, *timeout_action; 737 738 /* emulate the third button by the other two */ 739 740 emulateButtons = BMASKTOINDEX(bmask); 741 button_action = 742 &stateTab[pEmu3btn->emulateState].buttons[emulateButtons]; 743 744 if ((type = button_action->event1.type) != ButtonNone) { 745 button = button_action->event1.button; 746 flag = POINTER_RELATIVE; 747 valuator_mask_zero(&mask); 748 QueuePointerEvents(device, type, button, flag, &mask); 749 } 750 if ((type = button_action->event2.type) != ButtonNone) { 751 button = button_action->event2.button; 752 flag = POINTER_RELATIVE; 753 valuator_mask_zero(&mask); 754 QueuePointerEvents(device, type, button, flag, &mask); 755 } 756 757 pEmu3btn->emulateState = button_action->new_state; 758 759 timeout_action = &stateTab[pEmu3btn->emulateState].timeout; 760 if (timeout_action->event1.type != ButtonNone) { 761 pEmu3btn->emulate3Expires = 762 GetTimeInMillis() + pEmu3btn->emulate3Timeout; 763 pEmu3btn->emulate3Pending = TRUE; 764 } else { 765 pEmu3btn->emulate3Pending = FALSE; 766 } 767 } else { 768 /* no emulation; post left or right button event as is */ 769 flag = POINTER_RELATIVE; 770 valuator_mask_zero(&mask); 771 QueuePointerEvents(device, type, buttons, flag, &mask); 772 } 773} 774