Home | History | Annotate | Line # | Download | only in x68k
      1 /*
      2  *
      3  * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
      4  * Copyright 1993 by David Dawes <dawes (at) 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 
     38 static CARD32 buttonTimer(MouseEmu3btnPtr pEmu3btn);
     39 static void Emulate3ButtonsSetEnabled(MouseEmu3btnPtr pEmu3btn, Bool enable);
     40 static Bool Emulate3ButtonsSoft(MouseEmu3btnPtr pEmu3btn);
     41 
     42 static void MouseBlockHandler(void *data, void *waitTime);
     43 static 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  */
     99 struct 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 
    108 struct 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 
    129 struct 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  */
    142 static 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 
    574 static CARD32
    575 buttonTimer(MouseEmu3btnPtr pEmu3btn)
    576 {
    577     int type, button, flag;
    578     ValuatorMask mask;
    579     const struct button_action *timeout_action;
    580 
    581     input_lock();
    582 
    583     pEmu3btn->emulate3Pending = FALSE;
    584     timeout_action = &stateTab[pEmu3btn->emulateState].timeout;
    585     if ((type = timeout_action->event1.type) != ButtonNone) {
    586         button = timeout_action->event1.button;
    587         flag = POINTER_RELATIVE;
    588         valuator_mask_zero(&mask);
    589         QueuePointerEvents(pEmu3btn->device, type, button, flag, &mask);
    590         pEmu3btn->emulateState = timeout_action->new_state;
    591     } else {
    592         LogMessageVerbSigSafe(X_WARNING, -1,
    593             "Got unexpected buttonTimer in state %d\n", pEmu3btn->emulateState);
    594     }
    595 
    596     input_unlock();
    597     return 0;
    598 }
    599 
    600 static void
    601 Emulate3ButtonsSetEnabled(MouseEmu3btnPtr pEmu3btn, Bool enable)
    602 {
    603 
    604     if (pEmu3btn->emulate3Buttons == enable)
    605         return;
    606 
    607     pEmu3btn->emulate3Buttons = enable;
    608 
    609     if (enable) {
    610         pEmu3btn->emulateState = ST_GROUND;
    611         pEmu3btn->emulate3Pending = FALSE;
    612         pEmu3btn->emulate3ButtonsSoft = FALSE; /* specifically requested now */
    613 
    614         RegisterBlockAndWakeupHandlers(MouseBlockHandler, MouseWakeupHandler,
    615                                        (void *)pEmu3btn);
    616     } else {
    617         if (pEmu3btn->emulate3Pending)
    618             buttonTimer(pEmu3btn);
    619 
    620         RemoveBlockAndWakeupHandlers(MouseBlockHandler, MouseWakeupHandler,
    621                                      (void *)pEmu3btn);
    622     }
    623 }
    624 
    625 static Bool
    626 Emulate3ButtonsSoft(MouseEmu3btnPtr pEmu3btn)
    627 {
    628 
    629     if (!pEmu3btn->emulate3ButtonsSoft)
    630         return TRUE;
    631 
    632 #if defined(__NetBSD__) && defined(WSCONS_SUPPORT)
    633     /*
    634      * On NetBSD a wsmouse is a multiplexed device. Imagine a notebook
    635      * with two-button mousepad, and an external USB mouse plugged in
    636      * temporarily. After using button 3 on the external mouse and
    637      * unplugging it again, the mousepad will still need to emulate
    638      * 3 buttons.
    639      */
    640     return TRUE;
    641 #else
    642     LogMessageVerbSigSafe(X_INFO, 4,
    643         "mouse: 3rd Button detected: disabling emulate3Button\n");
    644 
    645     Emulate3ButtonsSetEnabled(pEmu3btn, FALSE);
    646 
    647     return FALSE;
    648 #endif
    649 }
    650 
    651 static void
    652 MouseBlockHandler(void *data, void *waitTime)
    653 {
    654     MouseEmu3btnPtr pEmu3btn = data;
    655     int ms;
    656 
    657     if (pEmu3btn->emulate3Pending) {
    658         ms = pEmu3btn->emulate3Expires - GetTimeInMillis();
    659         if (ms <= 0)
    660             ms = 0;
    661         AdjustWaitForDelay(waitTime, ms);
    662     }
    663 }
    664 
    665 static void
    666 MouseWakeupHandler(void *data, int i)
    667 {
    668     MouseEmu3btnPtr pEmu3btn = data;
    669     int ms;
    670 
    671     if (pEmu3btn->emulate3Pending) {
    672         ms = pEmu3btn->emulate3Expires - GetTimeInMillis();
    673         if (ms <= 0)
    674             buttonTimer(pEmu3btn);
    675     }
    676 }
    677 
    678 /*******************************************************************
    679  * function "Emulate3ButtonsEnable"
    680  *
    681  *  purpose:
    682  *   Enable and initialize Emulate3Buttons structures.
    683  *  argument:
    684  *    (MouseEmu3btnPtr)pEmu3btn : Emu3btn private record
    685  *    (DeviceIntPtr)device      : pointer device private record
    686  *    (int)timeout              : timeout to wait another button [ms]
    687  *
    688  *******************************************************************/
    689 void
    690 Emulate3ButtonsEnable(MouseEmu3btnPtr pEmu3btn, DeviceIntPtr device, int timeout)
    691 {
    692 
    693     BUG_RETURN_MSG(device == NULL, "Invalid DeviceIntPtr.\n");
    694 
    695     if (timeout <= 0) {
    696         timeout = EMU3B_DEF_TIMEOUT;
    697     }
    698     pEmu3btn->device = device;
    699     pEmu3btn->emulate3Timeout = timeout;
    700 
    701     Emulate3ButtonsSetEnabled(pEmu3btn, TRUE);
    702 }
    703 
    704 /*******************************************************************
    705  * function "Emulate3ButtonsQueueEvent"
    706  *
    707  *  purpose:
    708  *   Emulate middle button per left/right button events and post events.
    709  *  argument:
    710  *    (MouseEmu3btnPtr)pEmu3btn : Emu3btn private record
    711  *    (int)type                 : event  (ButtonPress / ButtonRelease)
    712  *    (int)buttons              : button (Button1 / Button2 / Button3)
    713  *    (int)bmask                : buttons being pressed (0x1:left / 0x4:right)
    714  *
    715  *******************************************************************/
    716 
    717 void
    718 Emulate3ButtonsQueueEvent(MouseEmu3btnPtr pEmu3btn, int type, int buttons, int bmask)
    719 {
    720     DeviceIntPtr device = pEmu3btn->device;
    721     int emulateButtons;
    722     int button, flag;
    723     ValuatorMask mask;
    724 
    725     BUG_RETURN_MSG(buttons != ButtonLeft && buttons != ButtonRight,
    726       "not left or right button event\n");
    727 
    728     if (pEmu3btn->emulate3ButtonsSoft && pEmu3btn->emulate3Pending)
    729         buttonTimer(pEmu3btn);
    730 
    731     if (pEmu3btn->emulate3Buttons
    732         && ((bmask & BMASK_MIDDLE) == 0 || Emulate3ButtonsSoft(pEmu3btn))) {
    733         const struct button_action *button_action, *timeout_action;
    734 
    735         /* emulate the third button by the other two */
    736 
    737         emulateButtons = BMASKTOINDEX(bmask);
    738         button_action =
    739           &stateTab[pEmu3btn->emulateState].buttons[emulateButtons];
    740 
    741         if ((type = button_action->event1.type) != ButtonNone) {
    742             button = button_action->event1.button;
    743             flag = POINTER_RELATIVE;
    744             valuator_mask_zero(&mask);
    745             QueuePointerEvents(device, type, button, flag, &mask);
    746         }
    747         if ((type = button_action->event2.type) != ButtonNone) {
    748             button = button_action->event2.button;
    749             flag = POINTER_RELATIVE;
    750             valuator_mask_zero(&mask);
    751             QueuePointerEvents(device, type, button, flag, &mask);
    752         }
    753 
    754         pEmu3btn->emulateState = button_action->new_state;
    755 
    756         timeout_action = &stateTab[pEmu3btn->emulateState].timeout;
    757         if (timeout_action->event1.type != ButtonNone) {
    758             pEmu3btn->emulate3Expires =
    759                 GetTimeInMillis() + pEmu3btn->emulate3Timeout;
    760             pEmu3btn->emulate3Pending = TRUE;
    761         } else {
    762             pEmu3btn->emulate3Pending = FALSE;
    763         }
    764     } else {
    765         /* no emulation; post left or right button event as is */
    766         flag = POINTER_RELATIVE;
    767         valuator_mask_zero(&mask);
    768         QueuePointerEvents(device, type, buttons, flag, &mask);
    769     }
    770 }
    771