/* * * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. * Copyright 1993 by David Dawes * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich * Copyright 1994-2002 by The XFree86 Project, Inc. * Copyright 2002 by Paul Elliott * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the names of copyright holders not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. The copyright holders * make no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * 3 button emulation stuff * based on the emulation method in xf86-input-mouse/dist/src/mouse.c */ #include "inpututils.h" #include "mouseEmu3btn.h" static CARD32 buttonTimer(MouseEmu3btnPtr pEmu3btn); static void Emulate3ButtonsSetEnabled(MouseEmu3btnPtr pEmu3btn, Bool enable); static Bool Emulate3ButtonsSoft(MouseEmu3btnPtr pEmu3btn); static void MouseBlockHandler(void *data, void *waitTime); static void MouseWakeupHandler(void *data, int i); /********************************************************************** * * Emulate3Button support code * **********************************************************************/ /* * Lets create a simple finite-state machine for 3 button emulation: * * We track buttons 1 and 3 (left and right). There are 11 states: * 0 ground - initial state * 1 delayed left - left pressed, waiting for right * 2 delayed right - right pressed, waiting for left * 3 pressed middle - right and left pressed, emulated middle sent * 4 pressed left - left pressed and sent * 5 pressed right - right pressed and sent * 6 released left - left released after emulated middle * 7 released right - right released after emulated middle * 8 repressed left - left pressed after released left * 9 repressed right - right pressed after released right * 10 pressed both - both pressed, not emulating middle */ #define ST_INVALID -1 #define ST_GROUND 0 /* initial state */ #define ST_DELAYED_LEFT 1 /* left pressed and waiting timeout */ #define ST_DELAYED_RIGHT 2 /* right pressed and waiting timeout */ #define ST_PRESSED_MIDDLE 3 /* middle pressed deteremined */ #define ST_PRESSED_LEFT 4 /* left pressed determined */ #define ST_PRESSED_RIGHT 5 /* right pressed determined */ #define ST_RELEASED_LEFT 6 /* left released after pressed both */ #define ST_RELEASED_RIGHT 7 /* right released after pressed both */ #define ST_REPRESSED_LEFT 8 /* left repressed after release */ #define ST_REPRESSED_RIGHT 9 /* right repressed after release */ #define ST_PRESSED_BOTH 10 /* both pressed (not as middle) */ #define NSTATES 11 /* * At each state, we need handlers for the following events * 0: no buttons down * 1: left button down * 2: right button down * 3: both buttons down * 4: emulate3Timeout passed without a button change * Note that button events are not deltas, they are the set of buttons being * pressed now. It's possible (ie, mouse hardware does it) to go from (eg) * left down to right down without anything in between, so all cases must be * handled. * * a handler consists of three values: * 0: action1 * 1: action2 * 2: new emulation state */ struct button_event { int type; /* ButtonNone / ButtonPress / ButtonRelease */ #define ButtonNone 0 int button; #define ButtonLeft Button1 #define ButtonMiddle Button2 #define ButtonRight Button3 }; struct button_action { struct button_event event1; struct button_event event2; int new_state; }; /* The set of buttons being pressed passed from DDX mouse events */ #define BMASK_LEFT 0x01 #define BMASK_MIDDLE 0x02 #define BMASK_RIGHT 0x04 /* Event index values per buttons being pressed */ #define EMU_BUTTONS_NONE 0 #define EMU_BUTTONS_LEFT 1 #define EMU_BUTTONS_RIGHT 2 #define EMU_BUTTONS_BOTH 3 #define NEMU_BUTTONSTATE 4 #define BMASKTOINDEX(bmask) \ ((((bmask) & BMASK_RIGHT) >> 1) | ((bmask) & BMASK_LEFT)) struct button_state { struct button_action buttons[NEMU_BUTTONSTATE]; struct button_action timeout; }; /* * The comment preceeding each section is the current emulation state. * The comments to the right are of the form *