AppleADBKeyboard.cpp [plain text]
#include "AppleADBKeyboard.h"
#include <IOKit/hidsystem/IOHIDTypes.h>
#include <IOKit/IOLib.h>
#include <IOKit/IODeviceTreeSupport.h>
#define super IOHIKeyboard
#ifndef kIOHIDFKeyModeKey
#define kIOHIDFKeyModeKey "HIDFKeyMode"
#endif
enum {
kCapsLockState_CapsLockEngaged = 0x01,
kCapsLockState_CapsLockGoingDown = 0x02,
kCapsLockState_PowerEngaged = 0x04,
kCapsLockState_PowerCapsMapped = 0x08
};
OSDefineMetaClassAndStructors(AppleADBKeyboard,IOHIKeyboard)
#define RB_HALT 0x08
extern "C" {
void Debugger( const char * );
void boot(int paniced, int howto, char * command);
}
static void AppleADBKeyboardReboot( thread_call_param_t arg, thread_call_param_t );
static void new_kbd_data ( IOService * us, UInt8 adbCommand, IOByteCount length, UInt8 * data );
static void asyncSetLEDFunc ( thread_call_param_t, thread_call_param_t );
#if 0 //The following table is in Info.plist now
static unsigned char kmapConvert[] =
{
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x3B,0x37,0x38,0x39,0x3A,0x7B,0x7C,0x7D,0x7E,0x3F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x3C,0x3D,0x3E,0x36,0x7F,
00,00
};
#endif
void AppleADBKeyboard::stop( IOService * provider )
{
if (adbDevice)
{
IORegistryEntry * us;
us = this;
adbDevice->releaseFromClient(us);
adbDevice = 0;
}
super::stop(provider);
}
void AppleADBKeyboard::free( void )
{
if (_keybrdLock)
{
IOLockFree(_keybrdLock);
_keybrdLock = NULL;
}
if ( _packetLock )
{
IOLockFree( _packetLock );
_packetLock = NULL;
}
if (adbDevice)
{
IORegistryEntry * us;
us = this;
adbDevice->releaseFromClient(us);
adbDevice = 0;
}
if ( ledThreadCall )
{
thread_call_free ( ledThreadCall );
ledThreadCall = 0;
}
if ( rebootThreadCall )
{
thread_call_free ( rebootThreadCall );
rebootThreadCall = 0;
}
super::free();
}
bool AppleADBKeyboard::start ( IOService * theNub )
{
OSString * data;
const char * pTable;
OSNumber *enable_fwd_delete;
_keybrdLock = IOLockAlloc();
_packetLock = IOLockAlloc();
_fn_key_invoked_power = false; enable_fwd_delete = OSDynamicCast( OSNumber, getProperty("PowerBook fn Foward Delete"));
if (enable_fwd_delete)
{
_enable_fwd_delete = (bool) enable_fwd_delete->unsigned32BitValue();
}
if ( _packetLock )
IOLockLock( _packetLock );
adbDevice = (IOADBDevice *)theNub;
if( !adbDevice->seizeForClient(this, new_kbd_data) ) {
IOLog("%s: Seize failed\n", getName());
if ( _packetLock )
IOLockUnlock( _packetLock );
return false;
}
_oneshotCAPSLOCK = ((getLEDStatus() & ADBKS_LED_CAPSLOCK) != 0);
if ( _packetLock )
IOLockUnlock( _packetLock );
data = OSDynamicCast( OSString, getProperty( "ADBVirtualKeys" ));
if (data)
{
pTable = data->getCStringNoCopy();
if (data->getLength() < (5 * 0x7f)) {
IOLog("AppleADBKeyboard: too few virtual keys found in Info.plist");
for (int i=0; i<128; i++)
{
_virtualmap[i] = i; }
}
else {
for (int i=0; i< 128; i++) {
_virtualmap[i] = strtol(pTable, NULL, 16); pTable += 5; }
}
}
else
{
return false;
}
_sticky_fn_ON = _stickymodeON = false;
data = OSDynamicCast( OSString, getProperty( "fnVirtualKeys" )); if (data)
{
pTable = data->getCStringNoCopy();
if (data->getLength() < (5 * 0x7f)) {
IOLog("AppleADBKeyboard: too few sticky fn keys found in Info.plist");
for (int i=0; i<128; i++)
{
_fnvirtualmap[i] = i; }
}
else
{
for (int i=0; i< 128; i++)
{
_fnvirtualmap[i] = strtol(pTable, NULL, 16); pTable += 5; }
}
}
else
{
IOLog("AppleADBKeyboard: no fn keymap found in Info.plist");
memcpy(_fnvirtualmap, _virtualmap, 128);
}
_get_last_keydown = OSSymbol::withCString("get_last_keydown");
_get_handler_id = OSSymbol::withCString("get_handler_id");
_get_device_flags = OSSymbol::withCString("get_device_flags");
turnLEDon = ADBKS_LED_CAPSLOCK | ADBKS_LED_NUMLOCK | ADBKS_LED_SCROLLLOCK; setAlphaLockFeedback(false);
setNumLockFeedback(false);
clock_interval_to_absolutetime_interval( 4, kSecondScale, &rebootTime);
clock_interval_to_absolutetime_interval( 1, kSecondScale, &debuggerTime);
_hasDualModeFunctionKeys = false;
updateFKeyMap();
getFKeyMode(); if (_hasDualModeFunctionKeys)
{
setFKeyMode( 0 ); }
ledThreadCall = thread_call_allocate ( asyncSetLEDFunc, (thread_call_param_t) this);
rebootThreadCall = thread_call_allocate ( AppleADBKeyboardReboot, (thread_call_param_t) RB_HALT);
return super::start(theNub);
}
bool AppleADBKeyboard::open(IOService * client,
IOOptionBits options,
KeyboardEventAction keAction,
KeyboardSpecialEventAction kseAction,
UpdateEventFlagsAction uefAction)
{
if (!super::open(client, options, keAction, kseAction, uefAction))
return false;
if (_oneshotCAPSLOCK)
{
if ( _packetLock )
IOLockLock( _packetLock );
_oneshotCAPSLOCK = false;
if (adbDevice && adbDevice->handlerID() > 0xc0) {
AbsoluteTime locktime;
clock_get_uptime(&locktime);
super::dispatchKeyboardEvent(ADBK_CAPSLOCK, true, locktime);
super::dispatchKeyboardEvent(ADBK_CAPSLOCK, false, locktime);
_capsLockState |= ( kCapsLockState_CapsLockEngaged | kCapsLockState_PowerCapsMapped );
_capsLockState &= ~kCapsLockState_CapsLockGoingDown;
}
if ( _packetLock )
IOLockUnlock( _packetLock );
}
return true;
}
void
AppleADBKeyboard::setFKeyMode(UInt8 mode)
{
UInt16 value;
IOByteCount length = sizeof( UInt16);
if (_hasDualModeFunctionKeys && adbDevice)
{
value = mode;
adbDevice->writeRegister(1, (UInt8 *)&value, &length);
setProperty(kIOHIDFKeyModeKey, mode, sizeof(UInt32));
}
}
SInt8
AppleADBKeyboard::getFKeyMode(void)
{
UInt8 adbdata[8], isFnPrimary = 0;
IOByteCount length = 8;
OSDictionary * FKeyModeParamDict;
SInt32 dictData = -1;
OSNumber * datan;
if (!adbDevice)
return -1;
FKeyModeParamDict = OSDictionary::withCapacity(4);
bzero(adbdata, 8);
adbDevice->readRegister(1, adbdata, &length);
_hasDualModeFunctionKeys = false;
if (adbdata[0]) {
_hasDualModeFunctionKeys = true;
if (adbdata[1] & 0x0001)
isFnPrimary = 1;
setProperty(kIOHIDFKeyModeKey, isFnPrimary, sizeof(UInt32));
dictData = isFnPrimary;
}
datan = OSNumber::withNumber((unsigned long long) dictData, 32 ); if( datan) {
FKeyModeParamDict->setObject( kIOHIDFKeyModeKey, datan);
datan->release();
}
if (_keyboardEventTarget)
{
((IOHIDSystem *)_keyboardEventTarget)->setParamProperties(FKeyModeParamDict);
}
FKeyModeParamDict->release();
if (_hasDualModeFunctionKeys)
return isFnPrimary;
else
return -1;
}
void
AppleADBKeyboard::updateFKeyMap()
{
IORegistryEntry *devicetreeRegEntry;
typedef char keystrtype[4];
unsigned long buttonkeyvalue; unsigned char fkeyindex; keystrtype mapentry[] =
{
{"F0"}, {"F1"}, {"F2"}, {"F3"}, {"F4"}, {"F5"}, {"F6"},
{"F7"}, {"F8"}, {"F9"}, {"F10"}, {"F11"}, {"F12"},
};
devicetreeRegEntry = fromPath("mac-io/via-pmu/adb/keyboard", gIODTPlane);
if(devicetreeRegEntry != NULL) {
if (OSDynamicCast(OSData, devicetreeRegEntry->getProperty("AAPL,has-embedded-fn-keys"))) {
for (fkeyindex = 1; fkeyindex <= 12; fkeyindex++)
{
OSData *tmpData = OSDynamicCast(OSData, devicetreeRegEntry->getProperty(mapentry[fkeyindex]));
if(tmpData != NULL) {
memcpy(&buttonkeyvalue, (UInt8 *)tmpData->getBytesNoCopy(), sizeof(buttonkeyvalue));
setButtonTransTableEntry(fkeyindex, buttonkeyvalue);
}
}
}
devicetreeRegEntry->release(); }
}
void
AppleADBKeyboard::setButtonTransTableEntry(unsigned char fkeynum, unsigned char transvalue)
{
if (!adbDevice)
return;
UInt8 oBuffer[3]; oBuffer[0] = 1; oBuffer[1] = fkeynum; oBuffer[2] = transvalue; IOByteCount oLength = sizeof(oBuffer);
adbDevice->writeRegister(0, oBuffer, &oLength); }
UInt32 AppleADBKeyboard::interfaceID ( void )
{
return NX_EVS_DEVICE_INTERFACE_ADB;
}
UInt32 AppleADBKeyboard::deviceType ( void )
{
UInt32 id; IORegistryEntry *regEntry;
OSData *data = 0;
UInt32 *dataptr;
OSNumber *xml_handlerID;
if (!adbDevice)
return 2;
xml_handlerID = OSDynamicCast( OSNumber, getProperty("alt_handler_id"));
if (xml_handlerID)
{
id = xml_handlerID->unsigned32BitValue();
}
else
{
id = adbDevice->handlerID();
}
if (id == 18) {
_virtualmap[0x32] = 0x35; _fnvirtualmap[0x32] = 0x35;
}
if ((id == 2) || (id == 3)) {
adbDevice->setHandlerID(3);
id = 2; }
else
if (id == 5) {
adbDevice->setHandlerID(3);
id = 5;
}
if ((id == kgestaltPwrBkEKDomKbd) || (id == kgestaltPwrBkEKISOKbd) ||
(id == kgestaltPwrBkEKJISKbd) || (id == kgestaltPwrBk99JISKbd))
{
if( (regEntry = IORegistryEntry::fromPath( "/pci@f2000000/mac-io/via-pmu/adb/keyboard", gIODTPlane )))
{
data = OSDynamicCast(OSData, regEntry->getProperty( "keyboard-id", gIODTPlane, kIORegistryIterateRecursively ));
if (data)
{
dataptr = (UInt32 *)data->getBytesNoCopy();
id = *dataptr; }
regEntry->release();
}
}
return id;
}
void AppleADBKeyboard::setAlphaLockFeedback ( bool to )
{
if (to)
turnLEDon &= ~ADBKS_LED_CAPSLOCK; else
turnLEDon |= ADBKS_LED_CAPSLOCK;
if ( !isInactive() && ledThreadCall) {
thread_call_enter(ledThreadCall);
}
}
void AppleADBKeyboard::setNumLockFeedback ( bool to )
{
if (to) turnLEDon &= ~ ADBKS_LED_NUMLOCK;
else
turnLEDon |= ADBKS_LED_NUMLOCK;
if ( !isInactive() && ledThreadCall) {
thread_call_enter(ledThreadCall);
}
}
static void asyncSetLEDFunc ( thread_call_param_t self, thread_call_param_t )
{
UInt16 value;
IOByteCount length = sizeof( UInt16);
if (!((AppleADBKeyboard*)self)->adbDevice)
return;
value = ((AppleADBKeyboard*)self)->turnLEDon;
((AppleADBKeyboard*)self)->adbDevice->writeRegister(2, (UInt8 *)&value, &length);
}
unsigned AppleADBKeyboard::getLEDStatus (void )
{
UInt8 data[8]; IOByteCount length = 8;
if (!adbDevice)
return 0;
bzero(data, 8);
LEDStatus = 0;
adbDevice->readRegister(2, data, &length);
if ((data[1] & ADBKS_LED_NUMLOCK) == 0)
LEDStatus |= ADBKS_LED_NUMLOCK;
if ((data[1] & ADBKS_LED_CAPSLOCK) == 0)
LEDStatus |= ADBKS_LED_CAPSLOCK;
if ((data[1] & ADBKS_LED_SCROLLLOCK) == 0)
LEDStatus |= ADBKS_LED_SCROLLLOCK;
return LEDStatus;
}
static void new_kbd_data ( IOService * us, UInt8 adbCommand, IOByteCount length, UInt8 * data )
{
((AppleADBKeyboard *)us)->packet(data,length,adbCommand);
}
static void AppleADBKeyboardReboot( thread_call_param_t arg, thread_call_param_t )
{
boot( 0, (int) arg, 0 );
}
void AppleADBKeyboard::dispatchKeyboardEvent(unsigned int keyCode,
bool goingDown,
AbsoluteTime time)
{
char * pvirtualmap;
if ( adbDevice && (adbDevice->handlerID() > 0xc0) && (keyCode == ADBK_CAPSLOCK) )
{
if (_oneshotCAPSLOCK)
{
return;
}
if (goingDown)
{
if ((_capsLockState & kCapsLockState_CapsLockEngaged) != 0)
{
return;
}
_capsLockState |= (kCapsLockState_CapsLockEngaged | kCapsLockState_CapsLockGoingDown);
}
else if (!goingDown)
{
if ((_capsLockState & kCapsLockState_CapsLockEngaged) == 0)
{
return;
}
else if ((_capsLockState & kCapsLockState_PowerCapsMapped) == 0)
{
super::dispatchKeyboardEvent(ADBK_CAPSLOCK, false, time);
super::dispatchKeyboardEvent(ADBK_CAPSLOCK, true, time);
}
else if ((_capsLockState & kCapsLockState_CapsLockGoingDown) == 0)
{
super::dispatchKeyboardEvent(ADBK_CAPSLOCK, true, time);
}
_capsLockState &= ~(kCapsLockState_CapsLockEngaged | kCapsLockState_CapsLockGoingDown);
}
_capsLockState &= ~kCapsLockState_PowerCapsMapped;
}
else if ( (_capsLockState & kCapsLockState_CapsLockEngaged) &&
!(_capsLockState & kCapsLockState_PowerEngaged) &&
(keyCode == ADBK_POWER) && (goingDown == false) )
{
if (((_capsLockState & kCapsLockState_CapsLockGoingDown) != 0) &&
((_capsLockState & kCapsLockState_PowerCapsMapped) == 0))
{
_capsLockState |= kCapsLockState_PowerCapsMapped;
_capsLockState &= ~kCapsLockState_CapsLockGoingDown;
keyCode = ADBK_CAPSLOCK;
}
else if (((_capsLockState & kCapsLockState_CapsLockGoingDown) == 0) &&
((_capsLockState & kCapsLockState_PowerCapsMapped) != 0))
{
_capsLockState |= kCapsLockState_CapsLockGoingDown;
goingDown = true;
keyCode = ADBK_CAPSLOCK;
}
}
pvirtualmap = _virtualmap;
if ((_stickymodeON) && (_sticky_fn_ON))
{
pvirtualmap = _fnvirtualmap;
}
if( !goingDown && programmerKey) {
programmerKey = false;
EVK_KEYUP( ADBK_CONTROL, _keyState);
SUB_ABSOLUTETIME( &time, &programmerKeyTime );
if( CMP_ABSOLUTETIME( &time, &rebootTime) >= 0) {
if ( rebootThreadCall ) {
thread_call_enter( rebootThreadCall );
}
} else if( CMP_ABSOLUTETIME( &time, &debuggerTime) >= 0) {
Debugger("Programmer Key");
}
}
else if ( keyCode == ADBK_POWER )
{
if ( goingDown )
_capsLockState |= kCapsLockState_PowerEngaged;
else
_capsLockState &= ~kCapsLockState_PowerEngaged;
if (EVK_IS_KEYDOWN( ADBK_CONTROL, _keyState)) {
if( !programmerKey) {
programmerKey = true;
programmerKeyTime = time;
}
return;
}
else if (deviceFlags() & NX_SECONDARYFNMASK)
{
keyCode = ADBK_FLOWER;
_fn_key_invoked_power = goingDown;
}
else if (_fn_key_invoked_power)
{
keyCode = ADBK_FLOWER;
_fn_key_invoked_power = false;
}
}
if ((_enable_fwd_delete) && (deviceFlags() & NX_SECONDARYFNMASK))
{
if (keyCode == ADBK_DELETE)
{
keyCode = ADBK_FORWARD_DELETE;
_fwd_delete_down = goingDown;
}
else if (keyCode == ADBK_PBFNKEY)
{
if ((!goingDown) && (_fwd_delete_down))
{
super::dispatchKeyboardEvent( pvirtualmap[ADBK_FORWARD_DELETE],
false, time );
_fwd_delete_down = false;
}
}
}
if ( adbDevice && (adbDevice->handlerID() > 0xc0))
{
switch ( keyCode )
{
case ADBK_CONTROL_R:
keyCode = ADBK_CONTROL;
break;
case ADBK_SHIFT_R:
keyCode = ADBK_SHIFT;
break;
case ADBK_OPTION_R:
keyCode = ADBK_OPTION;
break;
}
}
super::dispatchKeyboardEvent( pvirtualmap[keyCode], goingDown, time );
}
IOReturn AppleADBKeyboard::packet (UInt8 * data, IOByteCount, UInt8 adbCommand )
{
unsigned int keycode1, keycode2;
bool down;
AbsoluteTime now;
if ( _packetLock )
IOLockLock( _packetLock );
keycode1 = *data;
down = ((keycode1 & 0x80) == 0);
keycode1 &= 0x7f;
if(keycode1 == 0x7e) keycode1 = ADBK_POWER;
clock_get_uptime(&now);
setTimeLastNonmodKeydown(now, keycode1);
dispatchKeyboardEvent(keycode1,down,now);
keycode2 = *(data + 1);
if( keycode2 != 0xff ) {
down = ((keycode2 & 0x80) == 0);
keycode2 &= 0x7f;
if( keycode2 == 0x7e) keycode2 = ADBK_POWER;
if( (keycode1 != ADBK_POWER) || (keycode2 != ADBK_POWER))
dispatchKeyboardEvent(keycode2,down,now);
}
if ( _packetLock )
IOLockUnlock( _packetLock );
return kIOReturnSuccess;
}
void AppleADBKeyboard::setTimeLastNonmodKeydown (AbsoluteTime now, unsigned int keycode)
{
switch (_virtualmap[keycode]) {
case 0x3b: case ADBK_FLOWER:
case ADBK_SHIFT:
case ADBK_SHIFT_R:
case ADBK_CAPSLOCK:
case ADBK_OPTION:
case ADBK_OPTION_R:
case ADBK_PBFNKEY: break;
default:
_lastkeydown = now;
break;
}
}
AbsoluteTime AppleADBKeyboard::getTimeLastNonmodKeydown (void)
{
if (CMP_ABSOLUTETIME( &_lastkeyCGEvent, &_lastkeydown) > 0)
return _lastkeyCGEvent; else
return _lastkeydown; }
void AppleADBKeyboard::keyboardEvent(unsigned eventType,
unsigned flags,
unsigned keyCode,
unsigned charCode,
unsigned charSet,
unsigned origCharCode,
unsigned origCharSet)
{
switch ( _codeToRepeat)
{
case ADBK_F9:
case ADBK_F10:
case ADBK_F11:
case ADBK_F12:
case (unsigned) -1:
break;
default:
clock_get_uptime(&_lastkeyCGEvent);
break;
}
super::keyboardEvent( eventType, flags, keyCode, charCode, charSet,
origCharCode, origCharSet);
}
IOReturn AppleADBKeyboard::callPlatformFunction(const OSSymbol *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4)
{
if (functionName == _get_last_keydown)
{
AbsoluteTime *timeptr;
timeptr = (AbsoluteTime *)param1;
*timeptr = getTimeLastNonmodKeydown();
return kIOReturnSuccess;
}
if (functionName == _get_handler_id)
{
UInt32 *id;
id = (UInt32 *)param1;
*id = deviceType();
return kIOReturnSuccess;
}
if (functionName == _get_device_flags)
{
UInt32 *id;
id = (UInt32 *)param1;
*id = deviceFlags();
return kIOReturnSuccess;
}
return kIOReturnBadArgument;
}
UInt32 AppleADBKeyboard::maxKeyCodes ( void )
{
return 0x80;
}
bool AppleADBKeyboard::doesKeyLock ( unsigned key)
{
switch (key) {
case NX_KEYTYPE_CAPS_LOCK:
if ( adbDevice && (adbDevice->handlerID() > 0xc0))
return false;
else
return true;
case NX_KEYTYPE_NUM_LOCK:
return false;
default:
return false;
}
}
IOReturn AppleADBKeyboard::setParamProperties( OSDictionary * dict )
{
OSNumber *datan;
if (_keybrdLock)
IOLockLock (_keybrdLock);
if (datan = OSDynamicCast(OSNumber, dict->getObject(kIOHIDFKeyModeKey)))
{
bool theFkeyMode;
theFkeyMode = (bool) datan->unsigned32BitValue();
setFKeyMode(theFkeyMode); }
if (datan = OSDynamicCast(OSNumber, dict->getObject(kIOHIDStickyKeysOnKey)))
{
UInt32 propertydata;
propertydata = (bool) datan->unsigned32BitValue();;
if (propertydata)
{
_stickymodeON = true;
}
else
{
_stickymodeON = false;
}
}
if (_keybrdLock)
IOLockUnlock (_keybrdLock);
return super::setParamProperties(dict);
}
void AppleADBKeyboard::keyboardSpecialEvent( unsigned eventType, unsigned flags,
unsigned keyCode, unsigned flavor)
{
if ((_stickymodeON) && (eventType == NX_SYSDEFINED) && (keyCode == NX_NOSPECIALKEY))
{
if (flavor == NX_SUBTYPE_STICKYKEYS_FN_UP)
{
_sticky_fn_ON = false;
}
if ((flavor == NX_SUBTYPE_STICKYKEYS_FN_LOCK) ||
(flavor == NX_SUBTYPE_STICKYKEYS_FN_DOWN))
{
_sticky_fn_ON = true;
}
}
return super::keyboardSpecialEvent(eventType, flags, keyCode, flavor);
}
const unsigned char * AppleADBKeyboard::defaultKeymapOfLength (UInt32 * length )
{
static const unsigned char appleUSAKeyMap[] = {
0x00,0x00,
0x0b, 0x00,0x01,0x39, 0x01,0x01,0x38, 0x02,0x01,0x3b, 0x03,0x01,0x3a, 0x04,0x01,0x37, 0x05,0x11,0x52,0x41,0x4c,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
0x43,0x4b,0x51,0x4e,0x59, 0x06,0x01,0x72, 0x07,0x01,0x3f, 0x09,0x01,0x3c, 0x0a,0x01,0x3e, 0x0b,0x01,0x3d, 0x7f,0x0d,0x00,0x61,
0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01,0x0d,0x00,
0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13,0x0d,
0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04,
0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,
0x06,0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,
0x18,0x00,0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,
0x07,0x00,0x07,0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,
0x00,0x1a,0x00,0x1a,0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,
0xce,0x00,0x18,0x00,0x18,0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,
0x01,0xd3,0x00,0x03,0x00,0x03,0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,
0xd6,0x01,0xe0,0x00,0x16,0x00,0x16,0x02,0x00,0x3c,0x00,0x3e,0x0d,0x00,0x62,0x00,
0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02,0x0d,0x00,0x71,
0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11,0x0d,0x00,
0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17,0x0d,
0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05,
0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,
0x12,0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,
0x00,0x19,0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,
0x14,0x00,0x14,0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1,0x0e,0x00,0x32,0x00,
0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00,0x0a,0x00,0x33,
0x00,0x23,0x00,0xa3,0x01,0xba,0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8,0x0e,
0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e,
0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd,0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,
0x01,0xb1,0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab,0x0a,0x00,0x37,0x00,0x26,
0x01,0xb0,0x01,0xab,0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,
0xd0,0x00,0x1f,0x00,0x1f,0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4,0x0a,0x00,
0x30,0x00,0x29,0x00,0xad,0x00,0xbb,0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,
0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d,0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,
0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f,0x0d,0x00,0x75,0x00,0x55,0x00,0x15,
0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15,0x0e,0x00,0x5b,0x00,0x7b,0x00,
0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b,0x0d,0x00,0x69,0x00,0x49,
0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09,0x0d,0x00,0x70,0x00,
0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10,0x10,0x00,0x0d,
0x00,0x03,0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,
0x0c,0x00,0x0c,0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,
0x00,0x0a,0x00,0x0a,0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae,0x0d,0x00,0x6b,
0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b,0x0a,0x00,
0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2,0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,
0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c,0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,
0xa3,0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf,0x0d,0x00,0x6e,0x00,0x4e,0x00,
0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e,0x0d,0x00,0x6d,0x00,0x4d,
0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d,0x0a,0x00,0x2e,0x00,
0x3e,0x00,0xbc,0x01,0xb3,0x02,0x00,0x09,0x00,0x19,0x0c,0x00,0x20,0x00,0x00,0x00,
0x80,0x00,0x00,0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb,0x02,0x00,0x7f,0x00,
0x08,0xff,0x02,0x00,0x1b,0x00,0x7e,0xff,0xff,0xff,0xff,0xff,
0xff, 0xff, 0xff, 0xff,
0xff,0xff,0x00,0x00,0x2e,0xff,0x00,0x00,
0x2a,0xff,0x00,0x00,0x2b,0xff,0x00,0x00,0x1b,0xff,0xff,0xff,0x0e,0x00,0x2f,0x00,
0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00,0x00,0x00,0x0d, 0xff,0x00,0x00,0x2d,0xff,0xff,0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,
0x3d,0x00,0x7c,0x00,0x00,0x18,0x46,0x00,0x00,0x30,0x00,0x00,0x31,0x00,0x00,0x32,
0x00,0x00,0x33,0x00,0x00,0x34,0x00,0x00,0x35,0x00,0x00,0x36,0x00,0x00,0x37,0xff,
0x00,0x00,0x38,0x00,0x00,0x39,0xff,0xff,0xff,0x00,0xfe,0x24,0x00,0xfe,0x25,0x00,
0xfe,0x26,0x00,0xfe,0x22,0x00,0xfe,0x27,0x00,0xfe,0x28,0xff,0x00,0xfe,0x2a,0xff,
0x00,0xfe,0x32,0xff,0x00,0xfe,0x33,0xff,0x00,0xfe,0x29,0xff,0x00,0xfe,0x2b,0xff,
0x00,0xfe,0x34,0xff,0x00,0xfe,0x2e,0x00,0xfe,0x30,0x00,0xfe,0x2d,0x00,0xfe,0x23,
0x00,0xfe,0x2f,0x00,0xfe,0x21,0x00,0xfe,0x31,0x00,0xfe,0x20,
0x00,0x01,0xac, 0x00,0x01,0xae, 0x00,0x01,0xaf, 0x00,0x01,0xad, 0x0f,0x02,0xff,0x04,
0x00,0x31,0x02,0xff,0x04,0x00,0x32,0x02,0xff,0x04,0x00,0x33,0x02,0xff,0x04,0x00,
0x34,0x02,0xff,0x04,0x00,0x35,0x02,0xff,0x04,0x00,0x36,0x02,0xff,0x04,0x00,0x37,
0x02,0xff,0x04,0x00,0x38,0x02,0xff,0x04,0x00,0x39,0x02,0xff,0x04,0x00,0x30,0x02,
0xff,0x04,0x00,0x2d,0x02,0xff,0x04,0x00,0x3d,0x02,0xff,0x04,0x00,0x70,0x02,0xff,
0x04,0x00,0x5d,0x02,0xff,0x04,0x00,0x5b,
0x04, 0x05,0x72, 0x06,0x7f, 0x07,0x4a, 0x0a,0x47 };
static const unsigned char appleUSAPortableKeyMap[] = {
0x00,0x00,
0x08, 0x00,0x01,0x39, 0x01,0x01,0x38, 0x02,0x01,0x3b, 0x03,0x01,0x3a, 0x04,0x01,0x37, 0x05,0x11,0x52,0x41,0x4c,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
0x43,0x4b,0x51,0x4e,0x59, 0x06,0x01,0x72, 0x07,0x01,0x3f, 0x7f,0x0d,0x00,0x61,
0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01,0x0d,0x00,
0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13,0x0d,
0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04,
0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,
0x06,0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,
0x18,0x00,0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,
0x07,0x00,0x07,0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,
0x00,0x1a,0x00,0x1a,0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,
0xce,0x00,0x18,0x00,0x18,0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,
0x01,0xd3,0x00,0x03,0x00,0x03,0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,
0xd6,0x01,0xe0,0x00,0x16,0x00,0x16,0x02,0x00,0x3c,0x00,0x3e,0x0d,0x00,0x62,0x00,
0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02,0x0d,0x00,0x71,
0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11,0x0d,0x00,
0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17,0x0d,
0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05,
0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,
0x12,0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,
0x00,0x19,0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,
0x14,0x00,0x14,0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1,0x0e,0x00,0x32,0x00,
0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00,0x0a,0x00,0x33,
0x00,0x23,0x00,0xa3,0x01,0xba,0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8,0x0e,
0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e,
0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd,0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,
0x01,0xb1,0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab,0x0a,0x00,0x37,0x00,0x26,
0x01,0xb0,0x01,0xab,0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,
0xd0,0x00,0x1f,0x00,0x1f,0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4,0x0a,0x00,
0x30,0x00,0x29,0x00,0xad,0x00,0xbb,0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,
0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d,0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,
0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f,0x0d,0x00,0x75,0x00,0x55,0x00,0x15,
0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15,0x0e,0x00,0x5b,0x00,0x7b,0x00,
0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b,0x0d,0x00,0x69,0x00,0x49,
0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09,0x0d,0x00,0x70,0x00,
0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10,0x10,0x00,0x0d,
0x00,0x03,0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,
0x0c,0x00,0x0c,0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,
0x00,0x0a,0x00,0x0a,0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae,0x0d,0x00,0x6b,
0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b,0x0a,0x00,
0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2,0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,
0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c,0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,
0xa3,0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf,0x0d,0x00,0x6e,0x00,0x4e,0x00,
0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e,0x0d,0x00,0x6d,0x00,0x4d,
0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d,0x0a,0x00,0x2e,0x00,
0x3e,0x00,0xbc,0x01,0xb3,0x02,0x00,0x09,0x00,0x19,0x0c,0x00,0x20,0x00,0x00,0x00,
0x80,0x00,0x00,0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb,0x02,0x00,0x7f,0x00,
0x08,0xff,0x02,0x00,0x1b,0x00,0x7e,0xff,0xff,0xff,0xff,0xff,
0xff, 0xff, 0xff, 0xff,
0xff,0xff,0x00,0x00,0x2e,0xff,0x00,0x00,
0x2a,0xff,0x00,0x00,0x2b,0xff,0x00,0x00,0x1b,0xff,0xff,0xff,0x0e,0x00,0x2f,0x00,
0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00,0x00,0x00,0x0d, 0xff,0x00,0x00,0x2d,0xff,0xff,0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,
0x3d,0x00,0x7c,0x00,0x00,0x18,0x46,0x00,0x00,0x30,0x00,0x00,0x31,0x00,0x00,0x32,
0x00,0x00,0x33,0x00,0x00,0x34,0x00,0x00,0x35,0x00,0x00,0x36,0x00,0x00,0x37,0xff,
0x00,0x00,0x38,0x00,0x00,0x39,0xff,0xff,0xff,0x00,0xfe,0x24,0x00,0xfe,0x25,0x00,
0xfe,0x26,0x00,0xfe,0x22,0x00,0xfe,0x27,0x00,0xfe,0x28,0xff,0x00,0xfe,0x2a,0xff,
0x00,0xfe,0x32,0xff,0x00,0xfe,0x33,0xff,0x00,0xfe,0x29,0xff,0x00,0xfe,0x2b,0xff,
0x00,0xfe,0x34,0xff,0x00,0xfe,0x2e,0x00,0xfe,0x30,0x00,0xfe,0x2d,0x00,0xfe,0x23,
0x00,0xfe,0x2f,0x00,0xfe,0x21,0x00,0xfe,0x31,0x00,0xfe,0x20,
0x00,0x01,0xac, 0x00,0x01,0xae, 0x00,0x01,0xaf, 0x00,0x01,0xad, 0x0f,0x02,0xff,0x04,
0x00,0x31,0x02,0xff,0x04,0x00,0x32,0x02,0xff,0x04,0x00,0x33,0x02,0xff,0x04,0x00,
0x34,0x02,0xff,0x04,0x00,0x35,0x02,0xff,0x04,0x00,0x36,0x02,0xff,0x04,0x00,0x37,
0x02,0xff,0x04,0x00,0x38,0x02,0xff,0x04,0x00,0x39,0x02,0xff,0x04,0x00,0x30,0x02,
0xff,0x04,0x00,0x2d,0x02,0xff,0x04,0x00,0x3d,0x02,0xff,0x04,0x00,0x70,0x02,0xff,
0x04,0x00,0x5d,0x02,0xff,0x04,0x00,0x5b,
0x04, 0x05,0x72, 0x06,0x7f, 0x07,0x4a, 0x0a,0x47 };
if ( adbDevice && (adbDevice->handlerID() > 0xc0))
{
*length = sizeof(appleUSAPortableKeyMap);
return appleUSAPortableKeyMap;
}
*length = sizeof(appleUSAKeyMap);
return appleUSAKeyMap;
}