diff --git a/hw/darwin/darwinEvents.c b/hw/darwin/darwinEvents.c index 03decd9ae..9d206d04c 100644 --- a/hw/darwin/darwinEvents.c +++ b/hw/darwin/darwinEvents.c @@ -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; diff --git a/hw/darwin/darwinKeyboard.c b/hw/darwin/darwinKeyboard.c index ae842cd85..2f537ca15 100644 --- a/hw/darwin/darwinKeyboard.c +++ b/hw/darwin/darwinKeyboard.c @@ -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.