diff options
Diffstat (limited to 'hw/darwin/darwinKeyboard.c')
-rw-r--r-- | hw/darwin/darwinKeyboard.c | 239 |
1 files changed, 167 insertions, 72 deletions
diff --git a/hw/darwin/darwinKeyboard.c b/hw/darwin/darwinKeyboard.c index 4113bacba..57bf5fa3d 100644 --- a/hw/darwin/darwinKeyboard.c +++ b/hw/darwin/darwinKeyboard.c @@ -2,7 +2,8 @@ // // Keyboard support for the Darwin X Server // -// Copyright (c) 2001-2002 Torrey T. Lyons. All Rights Reserved. +// Copyright (c) 2001-2003 Torrey T. Lyons. All Rights Reserved. +// Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved. // // The code to parse the Darwin keymap is derived from dumpkeymap.c // by Eric Sunshine, which includes the following copyright: @@ -36,7 +37,7 @@ // //============================================================================= -/* $XFree86: xc/programs/Xserver/hw/darwin/darwinKeyboard.c,v 1.17 2002/12/10 00:00:38 torrey Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/darwin/darwinKeyboard.c,v 1.19 2003/11/01 08:13:08 torrey Exp $ */ /* =========================================================================== @@ -59,26 +60,18 @@ // in determining how the X server is interpreting the Darwin keymap. #undef DUMP_DARWIN_KEYMAP +/* Define this to use Alt for Mode_switch. */ +#define ALT_IS_MODE_SWITCH 1 + #include <drivers/event_status_driver.h> #include <IOKit/hidsystem/ev_keymap.h> #include <stdio.h> #include <stdlib.h> +#include <errno.h> #include <sys/stat.h> #include <architecture/byte_order.h> // For the NXSwap* #include "darwin.h" -#include "xfIOKit.h" -#include "quartz/quartzAudio.h" -#include "quartz/quartzShared.h" - -#define XK_TECHNICAL // needed to get XK_Escape -#define XK_PUBLISHING -#include "keysym.h" - -// Each key can generate 4 glyphs. They are, in order: -// unshifted, shifted, modeswitch unshifted, modeswitch shifted -#define GLYPHS_PER_KEY 4 -#define NUM_KEYCODES 248 // NX_NUMKEYCODES might be better -#define MAX_KEYCODE NUM_KEYCODES + MIN_KEYCODE - 1 +#include "darwinKeyboard.h" #define AltMask Mod1Mask #define MetaMask Mod2Mask @@ -224,11 +217,9 @@ static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl ) // keyclick, bell volume / pitch, autorepead, LED's } -static CARD8 modMap[MAP_LENGTH]; -static KeySym map[MAP_LENGTH * GLYPHS_PER_KEY]; -static unsigned char modifierKeycodes[NX_NUMMODIFIERS][2]; -static FILE *fref = NULL; -static char *inBuffer = NULL; +static darwinKeyboardInfo keyInfo; +static FILE *fref = NULL; +static char *inBuffer = NULL; //----------------------------------------------------------------------------- // Data Stream Object @@ -449,34 +440,18 @@ Bool DarwinReadKeymapFile( /* - * DarwinKeyboardInit - * Get the Darwin keyboard map and compute an equivalent - * X keyboard map and modifier map. Set the new keyboard - * device structure. + * DarwinParseNXKeyMapping */ -void DarwinKeyboardInit( - DeviceIntPtr pDev ) +Bool DarwinParseNXKeyMapping( + darwinKeyboardInfo *info) { KeySym *k; int i; short numMods, numKeys, numPadKeys = 0; - KeySymsRec keySyms; + Bool haveKeymap = FALSE; NXKeyMapping keyMap; DataStream *keyMapStream; unsigned char const *numPadStart = 0; - BellProcPtr bellProc; - Bool haveKeymap = FALSE; - - memset( modMap, NoSymbol, sizeof( modMap ) ); - memset( map, 0, sizeof( map ) ); - for (i = 0; i < NX_NUMMODIFIERS; i++) { - modifierKeycodes[i][0] = modifierKeycodes[i][1] = 0; - } - - // Open a shared connection to the HID System. - // Note that the Event Status Driver is really just a wrapper - // for a kIOHIDParamConnectType connection. - assert( darwinParamConnect = NXOpenEventStatus() ); if (darwinKeymapFile) { haveKeymap = DarwinReadKeymapFile(&keyMap); @@ -494,7 +469,7 @@ void DarwinKeyboardInit( keyMap.size = NXKeyMappingLength( darwinParamConnect ); keyMap.mapping = (char*) xalloc( keyMap.size ); if (!NXGetKeyMapping( darwinParamConnect, &keyMap )) { - FatalError("Could not get kernel keymapping! Load keymapping from file instead.\n"); + return FALSE; } } @@ -507,9 +482,7 @@ void DarwinKeyboardInit( ErrorF("Current 16-bit keymapping may not be interpreted correctly.\n"); } - // Compute the modifier map and - // insert X modifier KeySyms into keyboard map. - // Store modifier keycodes in modifierKeycodes. + // Insert X modifier KeySyms into the keyboard map. numMods = get_number(keyMapStream); while (numMods-- > 0) { int left = 1; // first keycode is left @@ -526,40 +499,33 @@ void DarwinKeyboardInit( while (numKeyCodes-- > 0) { const short keyCode = get_number(keyMapStream); if (charCode != NX_MODIFIERKEY_NUMERICPAD) { - modifierKeycodes[charCode][1-left] = keyCode; switch (charCode) { case NX_MODIFIERKEY_ALPHALOCK: - modMap[keyCode + MIN_KEYCODE] = LockMask; - map[keyCode * GLYPHS_PER_KEY] = XK_Caps_Lock; + info->keyMap[keyCode * GLYPHS_PER_KEY] = XK_Caps_Lock; break; case NX_MODIFIERKEY_SHIFT: - modMap[keyCode + MIN_KEYCODE] = ShiftMask; - map[keyCode * GLYPHS_PER_KEY] = + info->keyMap[keyCode * GLYPHS_PER_KEY] = (left ? XK_Shift_L : XK_Shift_R); break; case NX_MODIFIERKEY_CONTROL: - modMap[keyCode + MIN_KEYCODE] = ControlMask; - map[keyCode * GLYPHS_PER_KEY] = + info->keyMap[keyCode * GLYPHS_PER_KEY] = (left ? XK_Control_L : XK_Control_R); break; case NX_MODIFIERKEY_ALTERNATE: - modMap[keyCode + MIN_KEYCODE] = AltMask; - map[keyCode * GLYPHS_PER_KEY] = + info->keyMap[keyCode * GLYPHS_PER_KEY] = (left ? XK_Mode_switch : XK_Alt_R); break; case NX_MODIFIERKEY_COMMAND: - modMap[keyCode + MIN_KEYCODE] = MetaMask; - map[keyCode * GLYPHS_PER_KEY] = + info->keyMap[keyCode * GLYPHS_PER_KEY] = (left ? XK_Meta_L : XK_Meta_R); break; case NX_MODIFIERKEY_SECONDARYFN: - modMap[keyCode + MIN_KEYCODE] = FunctionMask; - map[keyCode * GLYPHS_PER_KEY] = + info->keyMap[keyCode * GLYPHS_PER_KEY] = (left ? XK_Control_L : XK_Control_R); break; case NX_MODIFIERKEY_HELP: // Help is not an X11 modifier; treat as normal key - map[keyCode * GLYPHS_PER_KEY] = XK_Help; + info->keyMap[keyCode * GLYPHS_PER_KEY] = XK_Help; break; } } @@ -567,12 +533,12 @@ void DarwinKeyboardInit( } } - // Convert the Darwin keyboard map to an X keyboard map. + // Convert the Darwin keyboard mapping to an X keyboard map. // A key can have a different character code for each combination of // modifiers. We currently ignore all modifier combinations except // those with Shift, AlphaLock, and Alt. numKeys = get_number(keyMapStream); - for (i = 0, k = map; i < numKeys; i++, k += GLYPHS_PER_KEY) { + for (i = 0, k = info->keyMap; i < numKeys; i++, k += GLYPHS_PER_KEY) { short const charGenMask = get_number(keyMapStream); if (charGenMask != 0xFF) { // is key bound? short numKeyCodes = 1 << bits_set(charGenMask); @@ -656,7 +622,7 @@ void DarwinKeyboardInit( keyMapStream->data = numPadStart; while(numPadKeys-- > 0) { const short keyCode = get_number(keyMapStream); - k = &map[keyCode * GLYPHS_PER_KEY]; + k = &info->keyMap[keyCode * GLYPHS_PER_KEY]; for (i = 0; i < NUM_KEYPAD; i++) { if (*k == normal_to_keypad[i].normalSym) { k[0] = normal_to_keypad[i].keypadSym; @@ -671,7 +637,9 @@ void DarwinKeyboardInit( #ifdef DUMP_DARWIN_KEYMAP ErrorF("Darwin -> X converted keyboard map\n"); - for (i = 0, k = map; i < NX_NUMKEYCODES; i++, k += GLYPHS_PER_KEY) { + for (i = 0, k = info->keyMap; i < NX_NUMKEYCODES; + i++, k += GLYPHS_PER_KEY) + { int j; ErrorF("0x%02x:", i); for (j = 0; j < GLYPHS_PER_KEY; j++) { @@ -685,18 +653,145 @@ void DarwinKeyboardInit( } #endif - keySyms.map = map; + return TRUE; +} + + +/* + * DarwinBuildModifierMaps + * Use the keyMap field of keyboard info structure to populate + * the modMap and modifierKeycodes fields. + */ +static void +DarwinBuildModifierMaps( + darwinKeyboardInfo *info) +{ + int i; + KeySym *k; + int darwinSwapAltMeta = 0; + + memset(info->modMap, NoSymbol, sizeof(info->modMap)); + memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes)); + + for (i = 0; i < NUM_KEYCODES; i++) + { + k = info->keyMap + i * GLYPHS_PER_KEY; + + switch (k[0]) { + case XK_Shift_L: + info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i; + info->modMap[MIN_KEYCODE + i] = ShiftMask; + break; + + case XK_Shift_R: + info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][1] = i; + info->modMap[MIN_KEYCODE + i] = ShiftMask; + break; + + case XK_Control_L: + info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i; + info->modMap[MIN_KEYCODE + i] = ControlMask; + break; + + case XK_Control_R: + info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][1] = i; + info->modMap[MIN_KEYCODE + i] = ControlMask; + break; + + case XK_Caps_Lock: + info->modifierKeycodes[NX_MODIFIERKEY_ALPHALOCK][0] = i; + info->modMap[MIN_KEYCODE + i] = LockMask; + break; + + case XK_Alt_L: + info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i; + info->modMap[MIN_KEYCODE + i] = Mod1Mask; + break; + + case XK_Alt_R: + info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][1] = i; + info->modMap[MIN_KEYCODE + i] = Mod1Mask; + break; + + case XK_Mode_switch: + info->modMap[MIN_KEYCODE + i] = Mod1Mask; + break; + + case XK_Meta_L: + info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i; + info->modMap[MIN_KEYCODE + i] = Mod2Mask; + break; + + case XK_Meta_R: + info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][1] = i; + info->modMap[MIN_KEYCODE + i] = Mod2Mask; + break; + + case XK_Num_Lock: + info->modMap[MIN_KEYCODE + i] = Mod3Mask; + break; + } + + if (darwinSwapAltMeta) + { + switch (k[0]) + { + case XK_Alt_L: + k[0] = XK_Meta_L; + break; + case XK_Alt_R: + k[0] = XK_Meta_R; + break; + case XK_Meta_L: + k[0] = XK_Alt_L; + break; + case XK_Meta_R: + k[0] = XK_Alt_R; + break; + } + } + +#if ALT_IS_MODE_SWITCH + if (k[0] == XK_Alt_L || k[0] == XK_Alt_R) + k[0] = XK_Mode_switch; +#endif + } +} + + +/* + * DarwinKeyboardInit + * Get the Darwin keyboard map and compute an equivalent + * X keyboard map and modifier map. Set the new keyboard + * device structure. + */ +void DarwinKeyboardInit( + DeviceIntPtr pDev ) +{ + KeySymsRec keySyms; + + memset( keyInfo.keyMap, 0, sizeof( keyInfo.keyMap ) ); + + // Open a shared connection to the HID System. + // Note that the Event Status Driver is really just a wrapper + // for a kIOHIDParamConnectType connection. + assert( darwinParamConnect = NXOpenEventStatus() ); + + if (!DarwinParseNXKeyMapping(&keyInfo)) { + if (!DarwinModeReadSystemKeymap(&keyInfo)) { + FatalError("Could not build a valid keymap."); + } + } + + DarwinBuildModifierMaps(&keyInfo); + + keySyms.map = keyInfo.keyMap; keySyms.mapWidth = GLYPHS_PER_KEY; keySyms.minKeyCode = MIN_KEYCODE; keySyms.maxKeyCode = MAX_KEYCODE; - if (quartz) - bellProc = QuartzBell; - else - bellProc = XFIOKitBell; - - assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms, modMap, - bellProc, + assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms, + keyInfo.modMap, DarwinModeBell, DarwinChangeKeyboardControl )); } @@ -718,7 +813,7 @@ void DarwinKeyboardInit( */ int DarwinModifierNXKeyToNXKeycode(int key, int side) { - return modifierKeycodes[key][side]; + return keyInfo.modifierKeycodes[key][side]; } /* @@ -734,7 +829,7 @@ int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) // search modifierKeycodes for this keycode+side for (key = 0; key < NX_NUMMODIFIERS; key++) { for (side = 0; side <= 1; side++) { - if (modifierKeycodes[key][side] == keycode) break; + if (keyInfo.modifierKeycodes[key][side] == keycode) break; } } if (key == NX_NUMMODIFIERS) return -1; |