added a bunch of debugging code to help troubleshoot the stuck

modifier key issue; much of it may be taken out later.
Also, hopefully fixed a race condition that may have
prevented ReleaseModifiers from working in some cases.
This commit is contained in:
Ben Byer 2007-11-16 04:37:58 -08:00 committed by Jeremy Huddleston
parent 6577916c44
commit 41eabe5d4c
2 changed files with 177 additions and 29 deletions

View file

@ -121,29 +121,131 @@ static void DarwinPressModifierMask(
#define ALTERNATE_MASK(flags) (NX_ALTERNATEMASK)
#endif /* NX_DEVICELALTKEYMASK */
#define KEYBOARD_MASK (NX_COMMANDMASK | NX_CONTROLMASK | NX_ALTERNATEMASK | NX_SHIFTMASK | \
NX_SECONDARYFNMASK | NX_ALPHASHIFTMASK | NX_NUMERICPADMASK | \
NX_HELPMASK | NX_DEVICELCTLKEYMASK | NX_DEVICELSHIFTKEYMASK | \
NX_DEVICERSHIFTKEYMASK | NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK | \
NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK | NX_DEVICERCTLKEYMASK)
char * decode_event_flags(unsigned int modifiers) {
char buf[1024];
buf[0]='\0';
if (modifiers & NX_DEVICELCTLKEYMASK) strcat(buf, "NX_DEVICELCTLKEYMASK | ");
if (modifiers & NX_DEVICELSHIFTKEYMASK) strcat(buf, "NX_DEVICELSHIFTKEYMASK | ");
if (modifiers & NX_DEVICERSHIFTKEYMASK) strcat(buf, "NX_DEVICERSHIFTKEYMASK | ");
if (modifiers & NX_DEVICELCMDKEYMASK) strcat(buf, "NX_DEVICELCMDKEYMASK | ");
if (modifiers & NX_DEVICERCMDKEYMASK) strcat(buf, "NX_DEVICERCMDKEYMASK | ");
if (modifiers & NX_DEVICELALTKEYMASK) strcat(buf, "NX_DEVICELALTKEYMASK | ");
if (modifiers & NX_DEVICERALTKEYMASK) strcat(buf, "NX_DEVICERALTKEYMASK | ");
if (modifiers & NX_DEVICERCTLKEYMASK) strcat(buf, "NX_DEVICERCTLKEYMASK | ");
if (modifiers & NX_ALPHASHIFTMASK) strcat(buf, "NX_ALPHASHIFTMASK | ");
if (modifiers & NX_SHIFTMASK) strcat(buf, "NX_SHIFTMASK | ");
if (modifiers & NX_CONTROLMASK) strcat(buf, "NX_CONTROLMASK | ");
if (modifiers & NX_ALTERNATEMASK) strcat(buf, "NX_ALTERNATEMASK | ");
if (modifiers & NX_COMMANDMASK) strcat(buf, "NX_COMMANDMASK | ");
if (modifiers & NX_NUMERICPADMASK) strcat(buf, "NX_NUMERICPADMASK | ");
if (modifiers & NX_HELPMASK) strcat(buf, "NX_HELPMASK | ");
if (modifiers & NX_SECONDARYFNMASK) strcat(buf, "NX_SECONDARYFNMASK | ");
if (modifiers & NX_STYLUSPROXIMITYMASK) strcat(buf, "NX_STYLUSPROXIMITYMASK | ");
if (modifiers & NX_NONCOALSESCEDMASK) strcat(buf, "NX_NONCOALSESCEDMASK | ");
if (modifiers & NX_NULLEVENTMASK) strcat(buf, "NX_NULLEVENTMASK | ");
// if (modifiers & NX_LMOUSEDOWNMASK) strcat(buf, "NX_LMOUSEDOWNMASK | ");
// if (modifiers & NX_LMOUSEUPMASK) strcat(buf, "NX_LMOUSEUPMASK | ");
// if (modifiers & NX_RMOUSEDOWNMASK) strcat(buf, "NX_RMOUSEDOWNMASK | ");
// if (modifiers & NX_RMOUSEUPMASK) strcat(buf, "NX_RMOUSEUPMASK | ");
// if (modifiers & NX_OMOUSEDOWNMASK) strcat(buf, "NX_OMOUSEDOWNMASK | ");
// if (modifiers & NX_OMOUSEUPMASK) strcat(buf, "NX_OMOUSEUPMASK | ");
// if (modifiers & NX_MOUSEMOVEDMASK) strcat(buf, "NX_MOUSEMOVEDMASK | ");
// if (modifiers & NX_LMOUSEDRAGGEDMASK) strcat(buf, "NX_LMOUSEDRAGGEDMASK | ");
//if (modifiers & NX_RMOUSEDRAGGEDMASK) strcat(buf, "NX_RMOUSEDRAGGEDMASK | ");
//if (modifiers & NX_OMOUSEDRAGGEDMASK) strcat(buf, "NX_OMOUSEDRAGGEDMASK | ");
//if (modifiers & NX_MOUSEENTEREDMASK) strcat(buf, "NX_MOUSEENTEREDMASK | ");
//if (modifiers & NX_MOUSEEXITEDMASK) strcat(buf, "NX_MOUSEEXITEDMASK | ");
if (modifiers & NX_KEYDOWNMASK) strcat(buf, "NX_KEYDOWNMASK | ");
if (modifiers & NX_KEYUPMASK) strcat(buf, "NX_KEYUPMASK | ");
if (modifiers & NX_FLAGSCHANGEDMASK) strcat(buf, "NX_FLAGSCHANGEDMASK | ");
if (modifiers & NX_KITDEFINEDMASK) strcat(buf, "NX_KITDEFINEDMASK | ");
if (modifiers & NX_SYSDEFINEDMASK) strcat(buf, "NX_SYSDEFINEDMASK | ");
if (modifiers & NX_APPDEFINEDMASK) strcat(buf, "NX_APPDEFINEDMASK | ");
if (strlen(buf) < 5) strcpy(buf, "(empty)");
else buf[strlen(buf)-3]='\0';
return strdup(buf);
}
char * get_keysym_name(int ks) {
switch(ks) {
case XK_Alt_L: return "XK_Alt_L";
case XK_Alt_R: return "XK_Alt_R";
case XK_Meta_L: return "XK_Meta_L";
case XK_Meta_R: return "XK_Meta_R";
case XK_Control_L: return "XK_Control_L";
case XK_Control_R: return "XK_Control_R";
case XK_Shift_L: return "XK_Shift_L";
case XK_Shift_R: return "XK_Shift_R";
case XK_Mode_switch: return "XK_Mode_switch";
case XK_Caps_Lock: return "XK_Caps_Lock";
}
return "???";
}
/*
* DarwinPressModifierMask
* Press or release the given modifier key, specified by its mask.
*/
static void DarwinPressModifierMask(
xEvent *xe, // must already have type, time and mouse location
int mask) // one of NX_*MASK constants
{
int key, keycode;
key = DarwinModifierNXMaskToNXKey(mask);
if (key == -1) {
ErrorF("DarwinPressModifierMask: can't find key for mask %x\n", mask);
return;
}
keycode = DarwinModifierNXKeyToNXKeycode(key, 0);
if (keycode == 0) {
ErrorF("DarwinPressModifierMask: can't find keycode for mask %x\n", mask);
return;
}
DEBUG_LOG("%x: %s %s\n", mask, xe->u.u.type==KeyPress?"pressing":"releasing",
decode_event_flags(mask));
xe->u.u.detail = keycode + MIN_KEYCODE;
(*darwinEventQueue.pKbd->processInputProc)(xe,
(DeviceIntPtr)darwinEventQueue.pKbd, 1);
}
/*
* DarwinUpdateModifiers
* Send events to update the modifier state.
*/
static void DarwinUpdateModifiers(
int pressed, // KeyPress or KeyRelease
int flags ) // modifier flags that have changed
unsigned int flags ) // modifier flags that have changed
{
DEBUG_LOG("DarwinUpdateModifiers(%p, %d, %x)\n", xe, pressed, flags);
xe->u.u.type = pressed;
if (flags & NX_COMMANDMASK) DarwinPressModifierMask(xe, COMMAND_MASK(flags));
if (flags & NX_CONTROLMASK) DarwinPressModifierMask(xe, CONTROL_MASK(flags));
if (flags & NX_ALTERNATEMASK) DarwinPressModifierMask(xe, ALTERNATE_MASK(flags));
if (flags & NX_SHIFTMASK) DarwinPressModifierMask(xe, SHIFT_MASK(flags));
if (flags & NX_SECONDARYFNMASK) DarwinPressModifierMask(xe, NX_SECONDARYFNMASK);
if (flags & NX_ALPHASHIFTMASK) {
// Alpha shift only sees KeyDown when enabled and KeyUp when disabled,
// but X11 wants to see a up/down pair to enable, and again to disable
xe->u.u.type = KeyPress;
DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
xe->u.u.type = KeyRelease;
DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
}
int i;
DEBUG_LOG("DarwinUpdateModifiers(%p, %d, %x, %s)\n", xe, pressed, flags, decode_event_flags(flags));
xe->u.u.type = pressed;
/* If we have "device specific" flags -- meaning, left or right -- then strip out the generic flag */
if (flags & (NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK)) flags &= ~NX_CONTROLMASK;
if (flags & (NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK)) flags &= ~NX_ALTERNATEMASK;
if (flags & (NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK)) flags &= ~NX_COMMANDMASK;
if (flags & (NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK)) flags &= ~NX_SHIFTMASK;
if (flags == NX_ALPHASHIFTMASK) {
// Alpha shift only sees KeyDown when enabled and KeyUp when disabled,
// but X11 wants to see a up/down pair to enable, and again to disable
xe->u.u.type = KeyPress;
DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
xe->u.u.type = KeyRelease;
DarwinPressModifierMask(xe, NX_ALPHASHIFTMASK);
flags &= ~NX_ALPHASHIFTMASK;
}
for(i=0; i < (sizeof(flags)*8); i++)
if (flags & (1 << i)) DarwinPressModifierMask(xe, flags & (1 << i));
}
/*
@ -152,18 +254,16 @@ static void DarwinUpdateModifiers(
* is deactivated (kXDarwinDeactivate) to prevent modifiers from getting stuck if they
* are held down during a "context" switch -- otherwise, we would miss the KeyUp.
*/
static void DarwinReleaseModifiers(void) {
void DarwinReleaseModifiers(void) {
KeySym *map = NULL;
xEvent ke;
int i = 0, j = 0, nevents = 0;
DEBUG_LOG("DarwinReleaseModifiers(%p)\n", darwinKeyc);
if (!darwinKeyc) return;
map = darwinKeyc->curKeySyms.map;
DEBUG_LOG("DarwinReleaseModifiers(%p)\n", &keyInfo.keyMap);
for (i = darwinKeyc->curKeySyms.minKeyCode, map = darwinKeyc->curKeySyms.map;
i < darwinKeyc->curKeySyms.maxKeyCode;
i++, map += darwinKeyc->curKeySyms.mapWidth) {
for (i = MIN_KEYCODE, map =keyInfo.keyMap;
i < MAX_KEYCODE;
i++, map += GLYPHS_PER_KEY) {
if (KeyPressed(i)) {
switch (*map) {
/* Don't release the lock keys */
@ -174,7 +274,7 @@ static void DarwinReleaseModifiers(void) {
case XK_Kana_Lock:
break;
default:
DEBUG_LOG("DarwinReleaseModifiers: releasing key %d\n", i);
DEBUG_LOG("DarwinReleaseModifiers: releasing key %d (%s)\n", i, get_keysym_name(*map));
ke.u.keyButtonPointer.time = GetTimeInMillis();
ke.u.keyButtonPointer.rootX = 0;
ke.u.keyButtonPointer.rootY = 0;

View file

@ -217,10 +217,9 @@ static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl )
// keyclick, bell volume / pitch, autorepead, LED's
}
static darwinKeyboardInfo keyInfo;
darwinKeyboardInfo keyInfo;
static FILE *fref = NULL;
static char *inBuffer = NULL;
KeyClassPtr darwinKeyc = NULL;
//-----------------------------------------------------------------------------
// Data Stream Object
@ -817,7 +816,7 @@ void DarwinKeyboardInit(
assert( darwinParamConnect = NXOpenEventStatus() );
DarwinLoadKeyboardMapping(&keySyms);
// DarwinKeyboardReload(pDev);
/* Initialize the seed, so we don't reload the keymap unnecessarily
(and possibly overwrite xinitrc changes) */
DarwinModeSystemKeymapSeed();
@ -836,7 +835,7 @@ InitModMap(register KeyClassPtr keyc)
CARD8 keysPerModifier[8];
CARD8 mask;
darwinKeyc = keyc;
// darwinKeyc = keyc;
if (keyc->modifierKeyMap != NULL)
xfree (keyc->modifierKeyMap);
@ -888,7 +887,7 @@ DarwinKeyboardReload(DeviceIntPtr pDev)
memmove(pDev->key->modifierMap, keyInfo.modMap, MAP_LENGTH);
InitModMap(pDev->key);
}
} else DEBUG_LOG("SetKeySymsMap=0\n");
SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
SendMappingNotify(MappingModifier, 0, 0, 0);
@ -937,6 +936,32 @@ int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide)
return key;
}
/*
* DarwinModifierNXMaskToNXKeyCode
* Returns 0 if mask is not a known modifier mask.
*/
int DarwinModifierNXMaskToNXKeyCode(int mask)
{
switch (mask) {
case NX_ALPHASHIFTMASK: return XK_Caps_Lock;
case NX_SHIFTMASK: ErrorF("Warning: Received NX_SHIFTMASK, treating as NX_DEVICELSHIFTKEYMASK\n");
case NX_DEVICELSHIFTKEYMASK: return NX_MODIFIERKEY_SHIFT; //XK_Shift_L;
case NX_DEVICERSHIFTKEYMASK: return NX_MODIFIERKEY_RSHIFT; //XK_Shift_R;
case NX_CONTROLMASK: ErrorF("Warning: Received NX_CONTROLMASK, treating as NX_DEVICELCTLKEYMASK\n");
case NX_DEVICELCTLKEYMASK: return XK_Control_L;
case NX_DEVICERCTLKEYMASK: return XK_Control_R;
case NX_ALTERNATEMASK: ErrorF("Warning: Received NX_ALTERNATEMASK, treating as NX_DEVICELALTKEYMASK\n");
case NX_DEVICELALTKEYMASK: return XK_Alt_L;
case NX_DEVICERALTKEYMASK: return XK_Alt_R;
case NX_COMMANDMASK: ErrorF("Warning: Received NX_COMMANDMASK, treating as NX_DEVICELCMDKEYMASK\n");
case NX_DEVICELCMDKEYMASK: return XK_Meta_L;
case NX_DEVICERCMDKEYMASK: return XK_Meta_R;
case NX_NUMERICPADMASK: return XK_Num_Lock;
case NX_HELPMASK: return XK_Help;
case NX_SECONDARYFNMASK: return XK_Control_L; // this seems very wrong, but is what the old code did
}
}
/*
* DarwinModifierNXMaskToNXKey
* Returns -1 if mask is not a known modifier mask.
@ -972,6 +997,29 @@ int DarwinModifierNXMaskToNXKey(int mask)
return -1;
}
char * DarwinModifierNXMaskTostring(int mask)
{
switch (mask) {
case NX_ALPHASHIFTMASK: return "NX_ALPHASHIFTMASK";
case NX_SHIFTMASK: return "NX_SHIFTMASK";
case NX_DEVICELSHIFTKEYMASK: return "NX_DEVICELSHIFTKEYMASK";
case NX_DEVICERSHIFTKEYMASK: return "NX_DEVICERSHIFTKEYMASK";
case NX_CONTROLMASK: return "NX_CONTROLMASK";
case NX_DEVICELCTLKEYMASK: return "NX_DEVICELCTLKEYMASK";
case NX_DEVICERCTLKEYMASK: return "NX_DEVICERCTLKEYMASK";
case NX_ALTERNATEMASK: return "NX_ALTERNATEMASK";
case NX_DEVICELALTKEYMASK: return "NX_DEVICELALTKEYMASK";
case NX_DEVICERALTKEYMASK: return "NX_DEVICERALTKEYMASK";
case NX_COMMANDMASK: return "NX_COMMANDMASK";
case NX_DEVICELCMDKEYMASK: return "NX_DEVICELCMDKEYMASK";
case NX_DEVICERCMDKEYMASK: return "NX_DEVICERCMDKEYMASK";
case NX_NUMERICPADMASK: return "NX_NUMERICPADMASK";
case NX_HELPMASK: return "NX_HELPMASK";
case NX_SECONDARYFNMASK: return "NX_SECONDARYFNMASK";
}
return "unknown mask";
}
/*
* DarwinModifierNXKeyToNXMask
* Returns 0 if key is not a known modifier key.