ApplePS2Keyboard.cpp [plain text]
#include <IOKit/assert.h>
#include <IOKit/IOLib.h>
#include <IOKit/hidsystem/IOHIDTypes.h>
#include <IOKit/hidsystem/IOLLEvent.h>
#include "ApplePS2Keyboard.h"
#define super IOHIKeyboard
OSDefineMetaClassAndStructors(ApplePS2Keyboard, IOHIKeyboard);
UInt32 ApplePS2Keyboard::deviceType() { return NX_EVS_DEVICE_TYPE_KEYBOARD; };
UInt32 ApplePS2Keyboard::interfaceID() { return NX_EVS_DEVICE_INTERFACE_ACE; };
UInt32 ApplePS2Keyboard::maxKeyCodes() { return KBV_NUM_KEYCODES; };
bool ApplePS2Keyboard::init(OSDictionary * properties)
{
if (!super::init(properties)) return false;
_device = 0;
_extendCount = 0;
_interruptHandlerInstalled = false;
_ledState = 0;
for (int index = 0; index < KBV_NUNITS; index++) _keyBitVector[index] = 0;
return true;
}
ApplePS2Keyboard * ApplePS2Keyboard::probe(IOService * provider, SInt32 * score)
{
ApplePS2KeyboardDevice * device = (ApplePS2KeyboardDevice *)provider;
PS2Request * request = device->allocateRequest();
bool success;
if (!super::probe(provider, score)) return 0;
request->commands[0].command = kPS2C_WriteDataPort;
request->commands[0].inOrOut = kDP_TestKeyboardEcho;
request->commands[1].command = kPS2C_ReadDataPortAndCompare;
request->commands[1].inOrOut = 0xEE;
request->commandsCount = 2;
device->submitRequestAndBlock(request);
success = (request->commandsCount == 2);
device->freeRequest(request);
return (success) ? this : 0;
}
bool ApplePS2Keyboard::start(IOService * provider)
{
if (!super::start(provider)) return false;
_device = (ApplePS2KeyboardDevice *)provider;
_device->retain();
_device->installInterruptAction(this,
(PS2InterruptAction)&ApplePS2Keyboard::interruptOccurred);
_interruptHandlerInstalled = true;
setLEDs(_ledState);
setCommandByte(kCB_EnableKeyboardIRQ | kCB_TranslateMode,
kCB_DisableKeyboardClock);
setKeyboardEnable(true);
return true;
}
void ApplePS2Keyboard::stop(IOService * provider)
{
assert(_device == provider);
setKeyboardEnable(false);
setCommandByte(kCB_DisableKeyboardClock, kCB_EnableKeyboardIRQ);
if ( _interruptHandlerInstalled ) _device->uninstallInterruptAction();
_interruptHandlerInstalled = false;
_device->release();
_device = 0;
super::stop(provider);
}
void ApplePS2Keyboard::interruptOccurred(UInt8 scanCode) {
if (scanCode == kSC_Acknowledge)
IOLog("%s: Unexpected acknowledge from PS/2 controller.\n", getName());
else if (scanCode == kSC_Resend)
IOLog("%s: Unexpected resend request from PS/2 controller.\n", getName());
else
dispatchKeyboardEventWithScancode(scanCode);
}
bool ApplePS2Keyboard::dispatchKeyboardEventWithScancode(UInt8 scanCode)
{
unsigned int keyCode;
bool goingDown;
AbsoluteTime now;
if (scanCode == kSC_Extend)
{
_extendCount = 1;
return false;
}
if (scanCode == kSC_Pause)
{
_extendCount = 2;
return false;
}
if (_extendCount == 0)
keyCode = scanCode & ~kSC_UpBit;
else
{
_extendCount--;
if (_extendCount) return false;
switch (scanCode & ~kSC_UpBit)
{
case 0x1D: keyCode = 0x60; break; case 0x38: keyCode = 0x61; break; case 0x1C: keyCode = 0x62; break; case 0x35: keyCode = 0x63; break; case 0x48: keyCode = 0x64; break; case 0x50: keyCode = 0x65; break; case 0x4B: keyCode = 0x66; break; case 0x4D: keyCode = 0x67; break; case 0x52: keyCode = 0x68; break; case 0x53: keyCode = 0x69; break; case 0x49: keyCode = 0x6A; break; case 0x51: keyCode = 0x6B; break; case 0x47: keyCode = 0x6C; break; case 0x4F: keyCode = 0x6D; break; case 0x37: keyCode = 0x6E; break; case 0x45: keyCode = 0x6F; break; case 0x5B: keyCode = 0x70; break; case 0x5C: keyCode = 0x71; break; case 0x5D: keyCode = 0x72; break; case 0x2A: default: return false;
}
}
if (keyCode == 0) return false;
goingDown = !(scanCode & kSC_UpBit);
if (goingDown)
{
if (KBV_IS_KEYDOWN(keyCode, _keyBitVector)) return false;
KBV_KEYDOWN(keyCode, _keyBitVector);
}
else
{
KBV_KEYUP(keyCode, _keyBitVector);
}
clock_get_uptime(&now);
dispatchKeyboardEvent(keyCode, goingDown, now);
return true;
}
void ApplePS2Keyboard::setAlphaLockFeedback(bool locked)
{
_ledState = locked ? (_ledState | kLED_CapsLock):(_ledState & ~kLED_CapsLock);
setLEDs(_ledState);
}
void ApplePS2Keyboard::setLEDs(UInt8 ledState)
{
PS2Request * request = _device->allocateRequest();
request->commands[0].command = kPS2C_WriteDataPort;
request->commands[0].inOrOut = kDP_SetKeyboardLEDs;
request->commands[1].command = kPS2C_ReadDataPortAndCompare;
request->commands[1].inOrOut = kSC_Acknowledge;
request->commands[2].command = kPS2C_WriteDataPort;
request->commands[2].inOrOut = ledState;
request->commands[3].command = kPS2C_ReadDataPortAndCompare;
request->commands[3].inOrOut = kSC_Acknowledge;
request->commandsCount = 4;
_device->submitRequest(request); }
void ApplePS2Keyboard::setKeyboardEnable(bool enable)
{
PS2Request * request = _device->allocateRequest();
request->commands[0].command = kPS2C_WriteDataPort;
request->commands[0].inOrOut = (enable)?kDP_Enable:kDP_SetDefaultsAndDisable;
request->commands[1].command = kPS2C_ReadDataPortAndCompare;
request->commands[1].inOrOut = kSC_Acknowledge;
request->commandsCount = 2;
_device->submitRequest(request); }
void ApplePS2Keyboard::setCommandByte(UInt8 setBits, UInt8 clearBits)
{
UInt8 commandByte;
UInt8 commandByteNew;
PS2Request * request = _device->allocateRequest();
do
{
request->commands[0].command = kPS2C_WriteCommandPort;
request->commands[0].inOrOut = kCP_GetCommandByte;
request->commands[1].command = kPS2C_ReadDataPort;
request->commands[1].inOrOut = 0;
request->commandsCount = 2;
_device->submitRequestAndBlock(request);
commandByte = request->commands[1].inOrOut;
commandByteNew = (commandByte | setBits) & (~clearBits);
request->commands[0].command = kPS2C_WriteCommandPort;
request->commands[0].inOrOut = kCP_GetCommandByte;
request->commands[1].command = kPS2C_ReadDataPortAndCompare;
request->commands[1].inOrOut = commandByte;
request->commands[2].command = kPS2C_WriteCommandPort;
request->commands[2].inOrOut = kCP_SetCommandByte;
request->commands[3].command = kPS2C_WriteDataPort;
request->commands[3].inOrOut = commandByteNew;
request->commandsCount = 4;
_device->submitRequestAndBlock(request);
} while (request->commandsCount != 4);
_device->freeRequest(request);
}
const unsigned char * ApplePS2Keyboard::defaultKeymapOfLength(UInt32 * length)
{
#define CTRL(c) ((c)&037)
#define NX_MODIFIERKEY_ALPHALOCK 0
#define NX_MODIFIERKEY_SHIFT 1
#define NX_MODIFIERKEY_CONTROL 2
#define NX_MODIFIERKEY_ALTERNATE 3
#define NX_MODIFIERKEY_COMMAND 4
#define NX_MODIFIERKEY_NUMERICPAD 5
#define NX_MODIFIERKEY_HELP 6
static const unsigned char defaultKeymapForPC[] =
{
0x00, 0x00,
6, 0x01, 0x02, 0x2A, 0x36, 0x02, 0x02, 0x1D, 0x60, 0x03, 0x01, 0x61, 0x04, 0x01, 0x38, 0x05, 0x15, 0x52, 0x53, 0x62, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D,
0x4E, 0x47, 0x48, 0x49, 0x45, 0x63, 0x37, 0x4A,
0x64, 0x65, 0x66, 0x67, 0x06, 0x01, 0x3B,
104, 0xff, (1<<NX_MODIFIERKEY_SHIFT),
NX_ASCIISET, CTRL('['), NX_ASCIISET, '~', (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '1', NX_ASCIISET, '!', NX_SYMBOLSET, 0xad, NX_ASCIISET, 0xa1, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '2', NX_ASCIISET, '@', NX_ASCIISET, CTRL('@'), NX_ASCIISET, CTRL('@'), NX_ASCIISET, 0xb2, NX_ASCIISET, 0xb3, NX_ASCIISET, CTRL('@'), NX_ASCIISET, CTRL('@'), (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '3', NX_ASCIISET, '#', NX_ASCIISET, 0xa3, NX_SYMBOLSET, 0xba, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '4', NX_ASCIISET, '$', NX_ASCIISET, 0xa2, NX_ASCIISET, 0xa8, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '5', NX_ASCIISET, '%', NX_SYMBOLSET, 0xa5, NX_ASCIISET, 0xbd, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '6', NX_ASCIISET, '^', NX_ASCIISET, CTRL('^'), NX_ASCIISET, CTRL('^'), NX_ASCIISET, 0xb6, NX_ASCIISET, 0xc3, NX_ASCIISET, CTRL('^'), NX_ASCIISET, CTRL('^'), (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '7', NX_ASCIISET, '&', NX_ASCIISET, 0xb7, NX_SYMBOLSET, 0xab, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '8', NX_ASCIISET, '*', NX_SYMBOLSET, 0xb0, NX_ASCIISET, 0xb4, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '9', NX_ASCIISET, '(', NX_ASCIISET, 0xac, NX_ASCIISET, 0xab, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '0', NX_ASCIISET, ')', NX_ASCIISET, 0xad, NX_ASCIISET, 0xbb, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '-', NX_ASCIISET, '_', NX_ASCIISET, CTRL('_'), NX_ASCIISET, CTRL('_'), NX_ASCIISET, 0xb1, NX_ASCIISET, 0xd0, NX_ASCIISET, CTRL('_'), NX_ASCIISET, CTRL('_'), (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '=', NX_ASCIISET, '+', NX_SYMBOLSET, 0xb9, NX_SYMBOLSET, 0xb1, (1<<NX_MODIFIERKEY_SHIFT),
NX_ASCIISET, 0x7f, NX_ASCIISET, '\b', (1<<NX_MODIFIERKEY_SHIFT),
NX_ASCIISET, '\t', NX_ASCIISET, CTRL('Y'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'q', NX_ASCIISET, 'Q', NX_ASCIISET, CTRL('Q'), NX_ASCIISET, CTRL('Q'), NX_ASCIISET, 0xfa, NX_ASCIISET, 0xea, NX_ASCIISET, CTRL('Q'), NX_ASCIISET, CTRL('Q'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'w', NX_ASCIISET, 'W', NX_ASCIISET, CTRL('W'), NX_ASCIISET, CTRL('W'), NX_SYMBOLSET, 0xc8, NX_SYMBOLSET, 0xc7, NX_ASCIISET, CTRL('W'), NX_ASCIISET, CTRL('W'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'e', NX_ASCIISET, 'E', NX_ASCIISET, CTRL('E'), NX_ASCIISET, CTRL('E'), NX_ASCIISET, 0xc2, NX_ASCIISET, 0xc5, NX_ASCIISET, CTRL('E'), NX_ASCIISET, CTRL('E'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'r', NX_ASCIISET, 'R', NX_ASCIISET, CTRL('R'), NX_ASCIISET, CTRL('R'), NX_SYMBOLSET, 0xe2, NX_SYMBOLSET, 0xd2, NX_ASCIISET, CTRL('R'), NX_ASCIISET, CTRL('R'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 't', NX_ASCIISET, 'T', NX_ASCIISET, CTRL('T'), NX_ASCIISET, CTRL('T'), NX_SYMBOLSET, 0xe4, NX_SYMBOLSET, 0xd4, NX_ASCIISET, CTRL('T'), NX_ASCIISET, CTRL('T'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'y', NX_ASCIISET, 'Y', NX_ASCIISET, CTRL('Y'), NX_ASCIISET, CTRL('Y'), NX_ASCIISET, 0xa5, NX_SYMBOLSET, 0xdb, NX_ASCIISET, CTRL('Y'), NX_ASCIISET, CTRL('Y'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'u', NX_ASCIISET, 'U', NX_ASCIISET, CTRL('U'), NX_ASCIISET, CTRL('U'), NX_ASCIISET, 0xc8, NX_ASCIISET, 0xcd, NX_ASCIISET, CTRL('U'), NX_ASCIISET, CTRL('U'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'i', NX_ASCIISET, 'I', NX_ASCIISET, '\t', NX_ASCIISET, '\t', NX_ASCIISET, 0xc1, NX_ASCIISET, 0xf5, NX_ASCIISET, '\t', NX_ASCIISET, '\t', (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'o', NX_ASCIISET, 'O', NX_ASCIISET, CTRL('O'), NX_ASCIISET, CTRL('O'), NX_ASCIISET, 0xf9, NX_ASCIISET, 0xe9, NX_ASCIISET, CTRL('O'), NX_ASCIISET, CTRL('O'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'p', NX_ASCIISET, 'P', NX_ASCIISET, CTRL('P'), NX_ASCIISET, CTRL('P'), NX_SYMBOLSET, 0x70, NX_SYMBOLSET, 0x50, NX_ASCIISET, CTRL('P'), NX_ASCIISET, CTRL('P'), (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '[', NX_ASCIISET, '{', NX_ASCIISET, CTRL('['), NX_ASCIISET, CTRL('['), NX_ASCIISET, '`', NX_ASCIISET, 0xaa, NX_ASCIISET, CTRL('['), NX_ASCIISET, CTRL('['), (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, ']', NX_ASCIISET, '}', NX_ASCIISET, CTRL(']'), NX_ASCIISET, CTRL(']'), NX_ASCIISET, '\'', NX_ASCIISET, 0xba, NX_ASCIISET, CTRL(']'), NX_ASCIISET, CTRL(']'), (1<<NX_MODIFIERKEY_COMMAND),
NX_ASCIISET, '\r', NX_ASCIISET, CTRL('C'), 0xff, (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'a', NX_ASCIISET, 'A', NX_ASCIISET, CTRL('A'), NX_ASCIISET, CTRL('A'), NX_ASCIISET, 0xca, NX_ASCIISET, 0xc7, NX_ASCIISET, CTRL('A'), NX_ASCIISET, CTRL('A'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 's', NX_ASCIISET, 'S', NX_ASCIISET, CTRL('S'), NX_ASCIISET, CTRL('S'), NX_ASCIISET, 0xfb, NX_ASCIISET, 0xa7, NX_ASCIISET, CTRL('S'), NX_ASCIISET, CTRL('S'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'd', NX_ASCIISET, 'D', NX_ASCIISET, CTRL('D'), NX_ASCIISET, CTRL('D'), NX_SYMBOLSET, 0x44, NX_SYMBOLSET, 0xb6, NX_ASCIISET, CTRL('D'), NX_ASCIISET, CTRL('D'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'f', NX_ASCIISET, 'F', NX_ASCIISET, CTRL('F'), NX_ASCIISET, CTRL('F'), NX_ASCIISET, 0xa6, NX_SYMBOLSET, 0xac, NX_ASCIISET, CTRL('F'), NX_ASCIISET, CTRL('F'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'g', NX_ASCIISET, 'G', NX_ASCIISET, CTRL('G'), NX_ASCIISET, CTRL('G'), NX_ASCIISET, 0xf1, NX_ASCIISET, 0xe1, NX_ASCIISET, CTRL('G'), NX_ASCIISET, CTRL('G'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'h', NX_ASCIISET, 'H', NX_ASCIISET, '\b', NX_ASCIISET, '\b', NX_ASCIISET, 0xe3, NX_ASCIISET, 0xeb, NX_ASCIISET, CTRL('@'), 0x18, CTRL('@'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'j', NX_ASCIISET, 'J', NX_ASCIISET, '\n', NX_ASCIISET, '\n', NX_ASCIISET, 0xc6, NX_ASCIISET, 0xae, NX_ASCIISET, '\n', NX_ASCIISET, '\n', (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'k', NX_ASCIISET, 'K', NX_ASCIISET, CTRL('K'), NX_ASCIISET, CTRL('K'), NX_ASCIISET, 0xce, NX_ASCIISET, 0xaf, NX_ASCIISET, CTRL('K'), NX_ASCIISET, CTRL('K'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'l', NX_ASCIISET, 'L', NX_ASCIISET, '\f', NX_ASCIISET, '\f', NX_ASCIISET, 0xf8, NX_ASCIISET, 0xe8, NX_ASCIISET, '\f', NX_ASCIISET, '\f', (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, ';', NX_ASCIISET, ':', NX_SYMBOLSET, 0xb2, NX_SYMBOLSET, 0xa2, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '\'', NX_ASCIISET, '"', NX_ASCIISET, 0xa9, NX_SYMBOLSET, 0xae, (1<<NX_MODIFIERKEY_SHIFT),
NX_ASCIISET, '`', NX_ASCIISET, '~', 0xff, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '\\', NX_ASCIISET, '|', NX_ASCIISET, CTRL('\\'), NX_ASCIISET, CTRL('\\'), NX_ASCIISET, 0xe3, NX_ASCIISET, 0xeb, NX_ASCIISET, CTRL('\\'), NX_ASCIISET, CTRL('\\'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'z', NX_ASCIISET, 'Z', NX_ASCIISET, CTRL('Z'), NX_ASCIISET, CTRL('Z'), NX_ASCIISET, 0xcf, NX_SYMBOLSET, 0x57, NX_ASCIISET, CTRL('Z'), NX_ASCIISET, CTRL('Z'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'x', NX_ASCIISET, 'X', NX_ASCIISET, CTRL('X'), NX_ASCIISET, CTRL('X'), NX_SYMBOLSET, 0xb4, NX_SYMBOLSET, 0xce, NX_ASCIISET, CTRL('X'), NX_ASCIISET, CTRL('X'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'c', NX_ASCIISET, 'C', NX_ASCIISET, CTRL('C'), NX_ASCIISET, CTRL('C'), NX_SYMBOLSET, 0xe3, NX_SYMBOLSET, 0xd3, NX_ASCIISET, CTRL('C'), NX_ASCIISET, CTRL('C'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'v', NX_ASCIISET, 'V', NX_ASCIISET, CTRL('V'), NX_ASCIISET, CTRL('V'), NX_SYMBOLSET, 0xd6, NX_SYMBOLSET, 0xe0, NX_ASCIISET, CTRL('V'), NX_ASCIISET, CTRL('V'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'b', NX_ASCIISET, 'B', NX_ASCIISET, CTRL('B'), NX_ASCIISET, CTRL('B'), NX_SYMBOLSET, 0xe5, NX_SYMBOLSET, 0xf2, NX_ASCIISET, CTRL('B'), NX_ASCIISET, CTRL('B'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'n', NX_ASCIISET, 'N', NX_ASCIISET, CTRL('N'), NX_ASCIISET, CTRL('N'), NX_ASCIISET, 0xc4, NX_SYMBOLSET, 0xaf, NX_ASCIISET, CTRL('N'), NX_ASCIISET, CTRL('N'), (1<<NX_MODIFIERKEY_ALPHALOCK)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, 'm', NX_ASCIISET, 'M', NX_ASCIISET, '\r', NX_ASCIISET, '\r', NX_SYMBOLSET, 0x6d, NX_SYMBOLSET, 0xd8, NX_ASCIISET, '\r', NX_ASCIISET, '\r', (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, ',', NX_ASCIISET, '<', NX_ASCIISET, 0xcb, NX_SYMBOLSET, 0xa3, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '.', NX_ASCIISET, '>', NX_ASCIISET, 0xbc, NX_SYMBOLSET, 0xb3, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '/', NX_ASCIISET, '?', NX_SYMBOLSET, 0xb8, NX_ASCIISET, 0xbf, 0xff, 0,
NX_ASCIISET, '*', 0xff, (1<<NX_MODIFIERKEY_CONTROL)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, ' ', NX_ASCIISET, CTRL('@'), NX_ASCIISET, 0x80, NX_ASCIISET, CTRL('@'), 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '`', NX_ASCIISET, '~', NX_ASCIISET, '`', NX_SYMBOLSET, 0xbb, 0xff, 0,
NX_ASCIISET, '7', 0,
NX_ASCIISET, '8', 0,
NX_ASCIISET, '9', 0,
NX_SYMBOLSET, 0x2d, 0,
NX_ASCIISET, '4', 0,
NX_ASCIISET, '5', 0,
NX_ASCIISET, '6', 0,
NX_ASCIISET, '+', 0,
NX_ASCIISET, '1', 0,
NX_ASCIISET, '2', 0,
NX_ASCIISET, '3', 0,
NX_ASCIISET, '0', 0,
NX_ASCIISET, '.', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
NX_ASCIISET, CTRL('C'), (1<<NX_MODIFIERKEY_SHIFT)|(1<<NX_MODIFIERKEY_CONTROL)|
(1<<NX_MODIFIERKEY_ALTERNATE),
NX_ASCIISET, '/', NX_ASCIISET, '\\', NX_ASCIISET, '/', NX_ASCIISET, CTRL('\\'), NX_ASCIISET, '/', NX_ASCIISET, '\\', NX_ASCIISET, CTRL('@'), 0x0a, CTRL('@'), 0,
NX_SYMBOLSET, 0xad, 0,
NX_SYMBOLSET, 0xaf, 0,
NX_SYMBOLSET, 0xac, 0,
NX_SYMBOLSET, 0xae, 0, 9, 0x00, 0x68, 0x01, 0x69, 0x02, 0x6A, 0x03, 0x6B, 0x04, 0x3A, 0x05, 0x3B, 0x06, 0x47, 0x07, 0x48, 0x08, 0x50 };
*length = sizeof(defaultKeymapForPC);
return defaultKeymapForPC;
}