XQuartz: Made 3-button mouse simulation a little more consistent.

(cherry picked from commit d207b037d2ae213369e5627a17d8831c9bc16ad8)
This commit is contained in:
Jeremy Huddleston 2008-08-14 07:32:37 -07:00
parent f51f77d25e
commit 1770c85374

View File

@ -77,7 +77,7 @@ in this Software without prior written authorization from The Open Group.
/* FIXME: Abstract this better */ /* FIXME: Abstract this better */
void QuartzModeEQInit(void); void QuartzModeEQInit(void);
static int old_flags = 0; // last known modifier state static int modifier_flags = 0; // last known modifier state
#define FD_ADD_MAX 128 #define FD_ADD_MAX 128
static int fd_add[FD_ADD_MAX]; static int fd_add[FD_ADD_MAX];
@ -140,19 +140,19 @@ static inline void darwinEvents_unlock(void) {
/* /*
* DarwinPressModifierMask * DarwinPressModifierMask
* Press or release the given modifier key, specified by its mask. * Press or release the given modifier key, specified by its mask (one of NX_*MASK constants)
*/ */
static void DarwinPressModifierMask( static void DarwinPressModifierMask(int pressed, int mask) {
int pressed, int keycode;
int mask) // one of NX_*MASK constants
{
int key = DarwinModifierNXMaskToNXKey(mask); int key = DarwinModifierNXMaskToNXKey(mask);
if (key != -1) { if (key != -1) {
int keycode = DarwinModifierNXKeyToNXKeycode(key, 0); keycode = DarwinModifierNXKeyToNXKeycode(key, 0);
if (keycode != 0) if (keycode != 0)
DarwinSendKeyboardEvents(pressed, keycode); DarwinSendKeyboardEvents(pressed, keycode);
} }
ErrorF("DarwinPressModifierMask pressed=%s, mask=%d, key=%d, keycode=%d\n", pressed == KeyPress ? "press" : "release", mask, key, keycode);
} }
#ifdef NX_DEVICELCTLKEYMASK #ifdef NX_DEVICELCTLKEYMASK
@ -187,6 +187,8 @@ static void DarwinUpdateModifiers(
int pressed, // KeyPress or KeyRelease int pressed, // KeyPress or KeyRelease
int flags ) // modifier flags that have changed int flags ) // modifier flags that have changed
{ {
fprintf(stderr, "DarwinUpdateModifiers pressed=%s, flags=%x\n", pressed == KeyPress ? "press" : "release", flags);
if (flags & NX_ALPHASHIFTMASK) { if (flags & NX_ALPHASHIFTMASK) {
DarwinPressModifierMask(pressed, NX_ALPHASHIFTMASK); DarwinPressModifierMask(pressed, NX_ALPHASHIFTMASK);
} }
@ -214,45 +216,10 @@ static void DarwinUpdateModifiers(
* are held down during a "context" switch -- otherwise, we would miss the KeyUp. * are held down during a "context" switch -- otherwise, we would miss the KeyUp.
*/ */
static void DarwinReleaseModifiers(void) { static void DarwinReleaseModifiers(void) {
ErrorF("DarwinReleaseModifiers\n");
DarwinUpdateModifiers(KeyRelease, COMMAND_MASK(-1) | CONTROL_MASK(-1) | ALTERNATE_MASK(-1) | SHIFT_MASK(-1)); DarwinUpdateModifiers(KeyRelease, COMMAND_MASK(-1) | CONTROL_MASK(-1) | ALTERNATE_MASK(-1) | SHIFT_MASK(-1));
} }
/*
* DarwinSimulateMouseClick
* Send a mouse click to X when multiple mouse buttons are simulated
* with modifier-clicks, such as command-click for button 2. The dix
* layer is told that the previously pressed modifier key(s) are
* released, the simulated click event is sent. After the mouse button
* is released, the modifier keys are reverted to their actual state,
* which may or may not be pressed at that point. This is usually
* closest to what the user wants. Ie. the user typically wants to
* simulate a button 2 press instead of Command-button 2.
*/
static void DarwinSimulateMouseClick(
int pointer_x,
int pointer_y,
float pressure,
float tilt_x,
float tilt_y,
int whichButton, // mouse button to be pressed
int modifierMask) // modifiers used for the fake click
{
// first fool X into forgetting about the keys
// for some reason, it's not enough to tell X we released the Command key --
// it has to be the *left* Command key.
if (modifierMask & NX_COMMANDMASK) modifierMask |=NX_DEVICELCMDKEYMASK ;
DarwinUpdateModifiers(KeyRelease, modifierMask);
// push the mouse button
DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y,
pressure, tilt_x, tilt_y);
DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y,
pressure, tilt_x, tilt_y);
// restore old modifiers
DarwinUpdateModifiers(KeyPress, modifierMask);
}
/* Generic handler for Xquartz-specifc events. When possible, these should /* Generic handler for Xquartz-specifc events. When possible, these should
be moved into their own individual functions and set as handlers using be moved into their own individual functions and set as handlers using
mieqSetHandler. */ mieqSetHandler. */
@ -475,7 +442,6 @@ static void DarwinPrepareValuators(int *valuators, ScreenPtr screen,
void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y, void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y,
float pressure, float tilt_x, float tilt_y) { float pressure, float tilt_x, float tilt_y) {
static int darwinFakeMouseButtonDown = 0; static int darwinFakeMouseButtonDown = 0;
static int darwinFakeMouseButtonMask = 0;
int i, num_events; int i, num_events;
DeviceIntPtr dev; DeviceIntPtr dev;
ScreenPtr screen; ScreenPtr screen;
@ -499,35 +465,27 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin
return; return;
} }
/* Handle fake click */
if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) { if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) {
// Mimic multi-button mouse with modifier-clicks if(darwinFakeMouseButtonDown != 0) {
// If both sets of modifiers are pressed, /* We're currently "down" with another button, so release it first */
// button 2 is clicked. DarwinSendPointerEvents(ButtonRelease, darwinFakeMouseButtonDown, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
if ((old_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) { darwinFakeMouseButtonDown=0;
DarwinSimulateMouseClick(pointer_x, pointer_y, pressure, }
tilt_x, tilt_y, 2, darwinFakeMouse2Mask); if ((modifier_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) {
ev_button = 2;
darwinFakeMouseButtonDown = 2; darwinFakeMouseButtonDown = 2;
darwinFakeMouseButtonMask = darwinFakeMouse2Mask; } else if ((modifier_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) {
return; ev_button = 3;
} else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) {
DarwinSimulateMouseClick(pointer_x, pointer_y, pressure,
tilt_x, tilt_y, 3, darwinFakeMouse3Mask);
darwinFakeMouseButtonDown = 3; darwinFakeMouseButtonDown = 3;
darwinFakeMouseButtonMask = darwinFakeMouse3Mask;
return;
} }
} }
if (ev_type == ButtonRelease && darwinFakeButtons && darwinFakeMouseButtonDown) { if (ev_type == ButtonRelease && ev_button == 1) {
// If last mousedown was a fake click, don't check for if(darwinFakeMouseButtonDown) {
// mouse modifiers here. The user may have released the ev_button = darwinFakeMouseButtonDown;
// modifiers before the mouse button. darwinFakeMouseButtonDown = 0;
ev_button = darwinFakeMouseButtonDown; }
darwinFakeMouseButtonDown = 0;
// Bring modifiers back up to date
DarwinUpdateModifiers(KeyPress, darwinFakeMouseButtonMask & old_flags);
darwinFakeMouseButtonMask = 0;
return;
} }
DarwinPrepareValuators(valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y); DarwinPrepareValuators(valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
@ -547,7 +505,7 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
return; return;
} }
if (old_flags == 0 && darwinSyncKeymap && darwinKeymapFile == NULL) { if (modifier_flags == 0 && darwinSyncKeymap && darwinKeymapFile == NULL) {
/* See if keymap has changed. */ /* See if keymap has changed. */
static unsigned int last_seed; static unsigned int last_seed;
@ -627,9 +585,9 @@ void DarwinSendScrollEvents(float count_x, float count_y,
/* Send the appropriate KeyPress/KeyRelease events to GetKeyboardEvents to /* Send the appropriate KeyPress/KeyRelease events to GetKeyboardEvents to
reflect changing modifier flags (alt, control, meta, etc) */ reflect changing modifier flags (alt, control, meta, etc) */
void DarwinUpdateModKeys(int flags) { void DarwinUpdateModKeys(int flags) {
DarwinUpdateModifiers(KeyRelease, old_flags & ~flags); DarwinUpdateModifiers(KeyRelease, modifier_flags & ~flags);
DarwinUpdateModifiers(KeyPress, ~old_flags & flags); DarwinUpdateModifiers(KeyPress, ~modifier_flags & flags);
old_flags = flags; modifier_flags = flags;
} }
/* /*