1/*
2 *
3 * @APPLE_LICENSE_HEADER_START@
4 *
5 * Copyright (c) 1999-2009 Apple Computer, Inc.  All Rights Reserved.
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25/*
26 * 13 Aug 2002 		ryepez
27 *			This class is based off IOHIKeyboard and handles
28 *			USB HID report based keyboard devices
29 */
30
31#include <IOKit/IOLib.h>
32#include <IOKit/assert.h>
33#include <IOKit/hidsystem/IOHIDUsageTables.h>
34#include <IOKit/hidsystem/IOHIDParameter.h>
35#include <IOKit/hidsystem/IOHIDShared.h>
36#include <IOKit/usb/USB.h>
37
38#include "IOHIDKeyboard.h"
39#include "IOHIDKeys.h"
40#include "IOHIDElement.h"
41#include "IOHIDFamilyTrace.h"
42#include "AppleHIDUsageTables.h"
43
44#define kFnModifierUsagePageKey		"FnModifierUsagePage"
45#define kFnModifierUsageKey		"FnModifierUsage"
46#define kFnSpecialKeyMapKey		"FnSpecialKeyMap"
47#define	kFnNonSpecialUsageMapKey	"FnNonSpecialUsageMap"
48#define	kNumPadUsageMapKey		"NumPadUsageMap"
49
50#define super IOHIKeyboard
51
52OSDefineMetaClassAndStructors(IOHIDKeyboard, super)
53
54extern unsigned int hid_usb_2_adb_keymap[];  //In Cosmo_USB2ADB.cpp
55extern unsigned int hid_usb_apple_2_adb_keymap[];  //In Cosmo_USB2ADB.cpp
56
57IOHIDKeyboard *
58IOHIDKeyboard::Keyboard(UInt32 supportedModifiers, bool isDispatcher)
59{
60    IOHIDKeyboard *keyboard = new IOHIDKeyboard;
61
62    if ((keyboard == 0) || !keyboard->init())
63    {
64        if (keyboard) keyboard->release();
65        return 0;
66    }
67
68    keyboard->_containsFKey = ( supportedModifiers & NX_SECONDARYFNMASK );
69
70    keyboard->setProperty( kIOHIDKeyboardSupportedModifiersKey, supportedModifiers, 32 );
71
72    keyboard->_isDispatcher = isDispatcher;
73
74    return keyboard;
75}
76
77bool
78IOHIDKeyboard::init(OSDictionary *properties)
79{
80  if (!super::init(properties))  return false;
81
82    _asyncLEDThread 	= 0;
83    _ledState 		= 0;
84	_repeat			= true;
85	setRepeatMode(_repeat);
86
87    _containsFKey = 0;
88
89    //This makes separate copy of ADB translation table.  Needed to allow ISO
90    //  keyboards to swap two keys without affecting non-ISO keys that are
91    //  also connected, or that will be plugged in later through USB ports
92    bcopy(hid_usb_2_adb_keymap, _usb_2_adb_keymap, sizeof(unsigned int ) * ADB_CONVERTER_LEN);
93    bcopy(hid_usb_apple_2_adb_keymap, _usb_apple_2_adb_keymap, sizeof(unsigned int) * APPLE_ADB_CONVERTER_LEN);
94
95    return true;
96}
97
98
99bool
100IOHIDKeyboard::start(IOService *provider)
101{
102    OSNumber *xml_swap_CTRL_CAPSLOCK;
103    OSNumber *xml_swap_CMD_ALT;
104	OSNumber *xml_use_pc_keyboard;
105
106    UInt16 productIDVal;
107    UInt16 vendorIDVal;
108
109    _provider = OSDynamicCast(IOHIDEventService, provider);
110
111    if ( !_provider )
112        return false;
113
114    if ( _isDispatcher )
115        setProperty(kIOHIDVirtualHIDevice, kOSBooleanTrue);
116
117    productIDVal    = _provider->getProductID();
118    vendorIDVal     = _provider->getVendorID();
119
120    xml_swap_CTRL_CAPSLOCK = (OSNumber*)provider->copyProperty("Swap control and capslock");
121    if (OSDynamicCast( OSNumber, xml_swap_CTRL_CAPSLOCK ))
122    {
123        if ( xml_swap_CTRL_CAPSLOCK->unsigned32BitValue())
124        {
125            char temp;
126
127            temp = _usb_2_adb_keymap[0x39];  //Caps lock
128                _usb_2_adb_keymap[0x39] = _usb_2_adb_keymap[0xe0];  //Left CONTROL modifier
129                _usb_2_adb_keymap[0xe0] = temp;
130        }
131    }
132    OSSafeReleaseNULL(xml_swap_CTRL_CAPSLOCK);
133
134    xml_swap_CMD_ALT = (OSNumber*)provider->copyProperty("Swap command and alt");
135    if (OSDynamicCast( OSNumber, xml_swap_CMD_ALT ))
136    {
137        if ( xml_swap_CMD_ALT->unsigned32BitValue())
138        {
139            char temp;
140
141            temp = _usb_2_adb_keymap[0xe2];  //left alt
142                _usb_2_adb_keymap[0xe2] = _usb_2_adb_keymap[0xe3];  //Left command modifier
143                _usb_2_adb_keymap[0xe3] = temp;
144
145                temp = _usb_2_adb_keymap[0xe6];  //right alt
146                _usb_2_adb_keymap[0xe6] = _usb_2_adb_keymap[0xe7];  //right command modifier
147                _usb_2_adb_keymap[0xe7] = temp;
148
149        }
150    }
151    OSSafeReleaseNULL(xml_swap_CMD_ALT);
152
153	xml_use_pc_keyboard = (OSNumber*)provider->copyProperty("Use PC keyboard");
154	if (OSDynamicCast( OSNumber, xml_use_pc_keyboard ))
155	{
156        if ( xml_use_pc_keyboard->unsigned32BitValue())
157        {
158            char temp;
159
160            temp = _usb_2_adb_keymap[0xe0];                       // Save left control
161            _usb_2_adb_keymap[0xe0] = _usb_2_adb_keymap[0xe2];    // Left control becomes left alt(option)
162            _usb_2_adb_keymap[0xe2] = _usb_2_adb_keymap[0xe3];    // Left alt becomes left flower(start)
163            _usb_2_adb_keymap[0xe3] = temp;                      // Left flower becomes left control
164
165            temp = _usb_2_adb_keymap[0xe6];                      // Save right alt
166            _usb_2_adb_keymap[0xe6] = _usb_2_adb_keymap[0xe7];    // Right alt becomes right flower
167            _usb_2_adb_keymap[0xe4] = temp;                      // Right control becomes right alt
168        }
169	}
170    OSSafeReleaseNULL(xml_use_pc_keyboard);
171
172    // Need separate thread to handle LED
173    _asyncLEDThread = thread_call_allocate((thread_call_func_t)_asyncLED, (thread_call_param_t)this);
174
175    if ( _containsFKey )
176    {
177        setProperty(kIOHIDFKeyModeKey, (unsigned long long)0, (unsigned int)32);
178    }
179
180    return super::start(provider);
181}
182
183void IOHIDKeyboard::stop(IOService * provider)
184{
185    if (_asyncLEDThread)
186    {
187	thread_call_cancel(_asyncLEDThread);
188	thread_call_free(_asyncLEDThread);
189	_asyncLEDThread = 0;
190    }
191
192    super::stop(provider);
193}
194
195void IOHIDKeyboard::free()
196{
197    super::free();
198}
199
200extern "C" {
201	void Debugger( const char * );
202	void boot(int paniced, int howto, char * command);
203#define RB_BOOT		1	/* Causes reboot, not halt.  Is in xnu/bsd/sys/reboot.h */
204
205}
206
207void IOHIDKeyboard::dispatchKeyboardEvent(
208                                AbsoluteTime                timeStamp,
209                                UInt32                      usagePage,
210                                UInt32                      usage,
211                                bool                        keyDown,
212                                IOOptionBits                options)
213{
214    UInt32  alpha   = usage;
215    bool    repeat  = ((options & kHIDDispatchOptionKeyboardNoRepeat) == 0);
216
217    if ((usagePage > 0xffff) || (usage > 0xffff))
218        IOLog("IOHIDKeyboard::dispatchKeyboardEvent usage/page unexpectedly large %02x:%02x\n", (int)usagePage, (int)usage);
219    setLastPageAndUsage(usagePage, usage);
220
221	switch (usagePage)
222	{
223		case kHIDPage_KeyboardOrKeypad:
224        case kHIDPage_AppleVendorKeyboard:
225            unsigned int keycode;
226
227            if (repeat != _repeat)
228            {
229                _repeat = repeat;
230                setRepeatMode(_repeat);
231            }
232            if ( usagePage == kHIDPage_KeyboardOrKeypad )
233                keycode = _usb_2_adb_keymap[alpha];
234            else
235                keycode = _usb_apple_2_adb_keymap[alpha];
236
237            if ((usagePage == kHIDPage_AppleVendorKeyboard) && (usage == kHIDUsage_AppleVendorKeyboard_Function) && (_provider->getVendorID() == kIOUSBVendorIDAppleComputer))
238                super::dispatchKeyboardEvent(0x3f, keyDown, timeStamp);
239            else
240                super::dispatchKeyboardEvent(keycode, keyDown, timeStamp);
241            break;
242        case kHIDPage_AppleVendorTopCase:
243            if ((usage == kHIDUsage_AV_TopCase_KeyboardFn) && (_provider->getVendorID() == kIOUSBVendorIDAppleComputer))
244                super::dispatchKeyboardEvent(0x3f, keyDown, timeStamp);
245			break;
246	}
247
248    clearLastPageAndUsage();
249}
250
251// **************************************************************************
252// _asyncLED
253//
254// Called asynchronously to turn on/off the keyboard LED
255//
256// **************************************************************************
257void
258IOHIDKeyboard::_asyncLED(OSObject *target)
259{
260    IOHIDKeyboard *me = OSDynamicCast(IOHIDKeyboard, target);
261    IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadActive, me, me ? me->_ledState : -1, me ? (uintptr_t)me->_provider : (uintptr_t)-1, 0);
262    me->Set_LED_States( me->_ledState );
263}
264
265void
266IOHIDKeyboard::Set_LED_States(UInt8 ledState)
267{
268    bool				resync = _resyncLED;
269
270    _resyncLED = FALSE;
271
272    for (int i=0; i<2; i++)
273    {
274        UInt32 value = (ledState >> i) & 1;
275
276        if (resync)
277			_provider->setElementValue(kHIDPage_LEDs, i + kHIDUsage_LED_NumLock, value ? 0 : 1);
278
279		_provider->setElementValue(kHIDPage_LEDs, i + kHIDUsage_LED_NumLock, value);
280    }
281}
282
283//******************************************************************************
284// COPIED from ADB keyboard driver 3/25/99
285// This is usually called on a call-out thread after the caps-lock key is pressed.
286// ADB operations to PMU are synchronous, and this is must not be done
287// on the call-out thread since that is the PMU driver workloop thread, and
288// it will block itself.
289//
290// Therefore, we schedule the ADB write to disconnect the call-out thread
291// and the one that initiates the ADB write.
292//
293// *******************************************************************************
294void
295IOHIDKeyboard::setAlphaLockFeedback ( bool LED_state)
296{
297    //*** TODO *** REVISIT ***
298    UInt8	newState = _ledState;
299
300    if (LED_state) //set alpha lock
301	newState |= kUSB_CAPSLOCKLED_SET;   //2nd bit is caps lock on USB
302    else
303	newState &= ~kUSB_CAPSLOCKLED_SET;
304
305    if (newState != _ledState)
306    {
307        _ledState = newState;
308
309        if (_asyncLEDThread) {
310            IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadTrigger, this, _ledState, 0, 0);
311            thread_call_enter(_asyncLEDThread);
312        }
313    }
314}
315
316
317
318void
319IOHIDKeyboard::setNumLockFeedback ( bool LED_state)
320{
321
322    //*** TODO *** REVISIT ***
323    UInt8	newState = _ledState;
324
325    if (LED_state)
326	newState |= kUSB_NUMLOCKLED_SET;   //1st bit is num lock on USB
327    else
328	newState &= ~kUSB_NUMLOCKLED_SET;
329
330    if (newState != _ledState)
331    {
332        _ledState = newState;
333
334        if (_asyncLEDThread) {
335            IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadTrigger, this, _ledState, 1, 0);
336            thread_call_enter(_asyncLEDThread);
337        }
338    }
339}
340
341
342//Called from parent classes
343unsigned
344IOHIDKeyboard::getLEDStatus (void )
345{
346    unsigned	ledState = 0;
347
348    for (int i=0; i<2; i++)
349    {
350		ledState |= (_provider->getElementValue(kHIDPage_LEDs, i + kHIDUsage_LED_NumLock)) << i;
351    }
352    return ledState;
353}
354
355// *************************************************************************
356// deviceType
357//
358// **************************************************************************
359UInt32
360IOHIDKeyboard::deviceType ( void )
361{
362    OSNumber 	*xml_handlerID;
363    UInt32      id;
364
365	// RY: If a _deviceType an IOHIKeyboard protected variable.  If it is
366    // non-zero, there is no need to obtain the handlerID again.  Just return
367    // the already set value.  This should prevent us from mistakenly changing
368    // changing a deviceType(keyboardType) value back to an unknow value after
369    // it has been set via MacBuddy or the keyboardPref.
370    if ( _deviceType )
371    {
372        id = _deviceType;
373    }
374    //Info.plist key is <integer>, not <string>
375    else {
376        xml_handlerID = (OSNumber*)_provider->copyProperty("alt_handler_id");
377        if ( OSDynamicCast(OSNumber, xml_handlerID) ) {
378        id = xml_handlerID->unsigned32BitValue();
379    }
380        else {
381        id = handlerID();
382    }
383        OSSafeReleaseNULL(xml_handlerID);
384    }
385
386    // ISO specific mappign to match ADB keyboards
387    // This should really be done in the keymaps.
388    switch ( id )
389    {
390        case kgestUSBCosmoISOKbd:
391        case kgestUSBAndyISOKbd:
392        case kgestQ6ISOKbd:
393        case kgestQ30ISOKbd:
394        case kgestM89ISOKbd:
395        case kgestUSBGenericISOkd:
396            _usb_2_adb_keymap[0x35] = 0x0a;
397            _usb_2_adb_keymap[0x64] = 0x32;
398            break;
399        default:
400            _usb_2_adb_keymap[0x35] = 0x32;
401            _usb_2_adb_keymap[0x64] = 0x0a;
402            break;
403    }
404
405    return id;
406
407}
408
409// ************************************************************************
410// interfaceID.  Fake ADB for now since USB defaultKeymapOfLength is too complex
411//
412// **************************************************************************
413UInt32
414IOHIDKeyboard::interfaceID ( void )
415{
416    //Return value must match "interface" line in .keyboard file
417    return NX_EVS_DEVICE_INTERFACE_ADB;  // 2 This matches contents of AppleExt.keyboard
418}
419
420
421/***********************************************/
422//Get handler ID
423//
424//  I assume that this method is only called if a valid USB keyboard
425//  is found. This method should return a 0 or something if there's
426//  no keyboard, but then the USB keyboard driver should never have
427//  been probed if there's no keyboard, so for now it won't return 0.
428UInt32
429IOHIDKeyboard::handlerID ( void )
430{
431    UInt16 productID    = _provider->getProductID();
432    UInt16 vendorID     = _provider->getVendorID();
433    UInt32 ret_id       = kgestUSBUnknownANSIkd;  //Default for all unknown USB keyboards is 2
434
435    //New feature for hardware identification using Gestalt.h values
436    if (vendorID == kIOUSBVendorIDAppleComputer)
437    {
438        switch (productID)
439        {
440            case kprodUSBCosmoANSIKbd:  //Cosmo ANSI is 0x201
441                    ret_id = kgestUSBCosmoANSIKbd; //0xc6
442                    break;
443            case kprodUSBCosmoISOKbd:  //Cosmo ISO
444                    ret_id = kgestUSBCosmoISOKbd; //0xc7
445                    break;
446            case kprodUSBCosmoJISKbd:  //Cosmo JIS
447                    ret_id = kgestUSBCosmoJISKbd;  //0xc8
448                    break;
449            case kprodUSBAndyANSIKbd:  //Andy ANSI is 0x204
450                    ret_id = kgestUSBAndyANSIKbd; //0xcc
451                    break;
452            case kprodUSBAndyISOKbd:  //Andy ISO
453                    ret_id = kgestUSBAndyISOKbd; //0xcd
454                    break;
455            case kprodUSBAndyJISKbd:  //Andy JIS is 0x206
456                    ret_id = kgestUSBAndyJISKbd; //0xce
457                    break;
458            case kprodQ6ANSIKbd:  //Q6 ANSI
459                    ret_id = kgestQ6ANSIKbd;
460                    break;
461            case kprodQ6ISOKbd:  //Q6 ISO
462                    ret_id = kgestQ6ISOKbd;
463                    break;
464            case kprodQ6JISKbd:  //Q6 JIS
465                    ret_id = kgestQ6JISKbd;
466                    break;
467            case kprodQ30ANSIKbd:  //Q30 ANSI
468                    ret_id = kgestQ30ANSIKbd;
469                    break;
470            case kprodQ30ISOKbd:  //Q30 ISO
471                    ret_id = kgestQ30ISOKbd;
472                    break;
473            case kprodQ30JISKbd:  //Q30 JIS
474                    ret_id = kgestQ30JISKbd;
475                    break;
476            case kprodFountainANSIKbd:  //Fountain ANSI
477                    ret_id = kgestFountainANSIKbd;
478                    break;
479            case kprodFountainISOKbd:  //Fountain ISO
480                    ret_id = kgestFountainISOKbd;
481                    break;
482            case kprodFountainJISKbd:  //Fountain JIS
483                    ret_id = kgestFountainJISKbd;
484                    break;
485            case kprodSantaANSIKbd:  //Santa ANSI
486                    ret_id = kgestSantaANSIKbd;
487                    break;
488            case kprodSantaISOKbd:  //Santa ISO
489                    ret_id = kgestSantaISOKbd;
490                    break;
491            case kprodSantaJISKbd:  //Santa JIS
492                    ret_id = kgestSantaJISKbd;
493                    break;
494
495
496            default:  // No Gestalt.h values, but still is Apple keyboard,
497                    //   so return a generic Cosmo ANSI
498                    ret_id = kgestUSBCosmoANSIKbd;
499                    break;
500        }
501    }
502
503    return ret_id;  //non-Apple USB keyboards should all return "2"
504}
505
506
507// *****************************************************************************
508// defaultKeymapOfLength
509// A.W. copied from ADB keyboard, I don't have time to make custom USB version
510// *****************************************************************************
511const unsigned char *
512IOHIDKeyboard::defaultKeymapOfLength (UInt32 * length )
513{
514    if ( _containsFKey )
515    {
516        // this one defines the FKeyMap
517        static const unsigned char appleUSAFKeyMap[] = {
518            0x00,0x00,
519
520            // Modifier Defs
521            0x0b,   //Number of modifier keys.  Was 7
522            //0x00,0x01,0x39,  //CAPSLOCK, uses one byte.
523            0x01,0x01,0x38,
524            0x02,0x01,0x3b,
525            0x03,0x01,0x3a,
526            0x04,0x01,0x37,
527            0x05,0x14,0x52,0x41,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
528            0x43,0x4b,0x51,0x7b,0x7d,0x7e,0x7c,0x4e,0x59,
529            0x06,0x01,0x72,
530            0x07,0x01,0x3f, //NX_MODIFIERKEY_SECONDARYFN 8th modifier
531            0x09,0x01,0x3c, //Right shift
532            0x0a,0x01,0x3e, //Right control
533            0x0b,0x01,0x3d, //Right Option
534            0x0c,0x01,0x36, //Right Command
535
536        // key deffs
537        0xa2,
538        0x0d,0x00,0x61,0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01, //00
539        0x0d,0x00,0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13, //01
540        0x0d,0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04, //02
541        0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,0x06, //03
542        0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,0x18,0x00, //04
543        0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,0x07,0x00,0x07, //05
544        0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,0x00,0x1a,0x00,0x1a, //06
545        0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,0xce,0x00,0x18,0x00,0x18, //07
546        0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,0x01,0xd3,0x00,0x03,0x00,0x03, //08
547        0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,0xd6,0x01,0xe0,0x00,0x16,0x00,0x16, //09
548        0x02,0x00,0x3c,0x00,0x3e, //0a
549        0x0d,0x00,0x62,0x00,0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02, //0b
550        0x0d,0x00,0x71,0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11, //0c
551        0x0d,0x00,0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17, //0d
552        0x0d,0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05, //0e
553        0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,0x12, //0f
554        0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,0x00,0x19, //10
555        0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,0x14,0x00,0x14, //11
556        0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1, //12
557        0x0e,0x00,0x32,0x00,0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00, //13
558        0x0a,0x00,0x33,0x00,0x23,0x00,0xa3,0x01,0xba, //14
559        0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8, //15
560        0x0e,0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e, //16
561        0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd, //17
562        0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,0x01,0xb1, //18
563        0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab, //19
564        0x0a,0x00,0x37,0x00,0x26,0x01,0xb0,0x01,0xab, //1a
565        0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,0xd0,0x00,0x1f,0x00,0x1f, //1b
566        0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4, //1c
567        0x0a,0x00,0x30,0x00,0x29,0x00,0xad,0x00,0xbb, //1d
568        0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d, //1e
569        0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f, //1f
570        0x0d,0x00,0x75,0x00,0x55,0x00,0x15,0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15, //20
571        0x0e,0x00,0x5b,0x00,0x7b,0x00,0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b, //21
572        0x0d,0x00,0x69,0x00,0x49,0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09, //22
573        0x0d,0x00,0x70,0x00,0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10, //23
574        0x10,0x00,0x0d,0x00,0x03, //24
575        0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,0x0c,0x00,0x0c, //25
576        0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,0x00,0x0a,0x00,0x0a, //26
577        0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae, //27
578        0x0d,0x00,0x6b,0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b, //28
579        0x0a,0x00,0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2, //29
580        0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c, //2a
581        0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,0xa3, //2b
582        0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf, //2c
583        0x0d,0x00,0x6e,0x00,0x4e,0x00,0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e, //2d
584        0x0d,0x00,0x6d,0x00,0x4d,0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d, //2e
585        0x0a,0x00,0x2e,0x00,0x3e,0x00,0xbc,0x01,0xb3, //2f
586        0x02,0x00,0x09,0x00,0x19, //30
587        0x0c,0x00,0x20,0x00,0x00,0x00,0x80,0x00,0x00, //31
588        0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb, //32
589        0x02,0x00,0x7f,0x00,0x08, //33
590        0xff, //34
591        0x02,0x00,0x1b,0x00,0x7e, //35
592        0xff, //36
593        0xff, //37
594        0xff, //38
595        0xff, //39
596        0xff, //3a
597        0xff, //3b
598        0xff, //3c
599        0xff, //3d
600        0xff, //3e
601        0xff, //3f
602        0x00,0xfe,0x36, //40 is F17
603        0x00,0x00,0x2e, //41
604        0xff, //42
605        0x00,0x00,0x2a, //43
606        0xff, //44
607        0x00,0x00,0x2b, //45
608        0xff, //46
609        0x00,0x00,0x1b, //47
610        0xff, //48
611        0xff, //49
612        0xff, //4a
613        0x0e,0x00,0x2f,0x00,0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00, //4b
614        0x00,0x00,0x0d,  //4c //XX03
615        0xff, //4d
616        0x00,0x00,0x2d, //4e
617        0x00,0xfe,0x37, //4f is F18
618        0x00,0xfe,0x38, //50 is F19
619        0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,0x3d,0x00,0x7c,0x00,0x00,0x18,0x46, //51
620        0x00,0x00,0x30, //52
621        0x00,0x00,0x31, //53
622        0x00,0x00,0x32, //54
623        0x00,0x00,0x33, //55
624        0x00,0x00,0x34, //56
625        0x00,0x00,0x35, //57
626        0x00,0x00,0x36, //58
627        0x00,0x00,0x37, //59
628        0x00,0xfe,0x39, //5a is F20
629        0x00,0x00,0x38, //5b
630        0x00,0x00,0x39, //5c
631        0xff, //5d
632        0xff, //5e
633        0xff, //5f
634        0x00,0xfe,0x24, //60
635        0x00,0xfe,0x25, //61
636        0x00,0xfe,0x26, //62
637        0x00,0xfe,0x22, //63
638        0x00,0xfe,0x27, //64
639        0x00,0xfe,0x28, //65
640        0xff, //66
641        0x00,0xfe,0x2a, //67
642        0xff, //68
643        0x00,0xfe,0x32, //69
644        0x00,0xfe,0x35, //6a
645        0x00,0xfe,0x33, //6b
646        0xff, //6c
647        0x00,0xfe,0x29, //6d
648        0xff, //6e
649        0x00,0xfe,0x2b, //6f
650        0xff, //70
651        0x00,0xfe,0x34, //71
652        0xff, //72
653        0x00,0xfe,0x2e, //73
654        0x00,0xfe,0x30, //74
655        0x00,0xfe,0x2d, //75
656        0x00,0xfe,0x23, //76
657        0x00,0xfe,0x2f, //77
658        0x00,0xfe,0x21, //78
659        0x00,0xfe,0x31, //79
660        0x00,0xfe,0x20, //7a
661        0x00,0x01,0xac, //ADB=0x7b is left arrow
662        0x00,0x01,0xae, //ADB = 0x7c is right arrow
663        0x00,0x01,0xaf, //ADB=0x7d is down arrow.
664        0x00,0x01,0xad, //ADB=0x7e is up arrow
665
666            0x00,0x00,0x00,
667            0x00,0x00,0x00,
668            0x00,0x00,0x00, // Virtual = 0x81 is Spotlight
669            0x00,0x00,0x00, // Virtual = 0x82 is Dashboard
670            0x00,0x00,0x00, // Virtual = 0x83 is Launchpad
671            0x00,0x00,0x00,
672            0x00,0x00,0x00,
673            0x00,0x00,0x00,
674            0x00,0x00,0x00,
675            0x00,0x00,0x00,
676            0x00,0x00,0x00,
677            0x00,0x00,0x00,
678            0x00,0x00,0x00,
679            0x00,0x00,0x00,
680            0x00,0x00,0x00,
681            0x00,0x00,0x00,
682            0x00,0x00,0x00,
683            0x00,0x00,0x00, // Virtual = 0x90 is Main Brightness Up
684            0x00,0x00,0x00, // Virtual = 0x91 is Main Brightness Down
685            0x00,0x00,0x00,
686            0x00,0x00,0x00,
687            0x00,0x00,0x00,
688            0x00,0x00,0x00,
689            0x00,0x00,0x00,
690            0x00,0x00,0x00,
691            0x00,0x00,0x00,
692            0x00,0x00,0x00,
693            0x00,0x00,0x00,
694            0x00,0x00,0x00,
695            0x00,0x00,0x00,
696            0x00,0x00,0x00,
697            0x00,0x00,0x00,
698            0x00,0x00,0x00,
699            0x00,0x00,0x00, // Virtual = 0xa0 is Exposes All
700            0x00,0x00,0x00, // Virtual = 0xa1 is Expose Desktop
701
702                0x0f,0x02,0xff,0x04,
703                0x00,0x31,0x02,0xff,0x04,0x00,0x32,0x02,0xff,0x04,0x00,0x33,0x02,0xff,0x04,0x00,
704                0x34,0x02,0xff,0x04,0x00,0x35,0x02,0xff,0x04,0x00,0x36,0x02,0xff,0x04,0x00,0x37,
705                0x02,0xff,0x04,0x00,0x38,0x02,0xff,0x04,0x00,0x39,0x02,0xff,0x04,0x00,0x30,0x02,
706                0xff,0x04,0x00,0x2d,0x02,0xff,0x04,0x00,0x3d,0x02,0xff,0x04,0x00,0x70,0x02,0xff,
707                0x04,0x00,0x5d,0x02,0xff,0x04,0x00,0x5b,
708                0x07, // following are 7 special keys
709                0x04,0x39,  //caps lock
710                0x05,0x72,  //NX_KEYTYPE_HELP is 5, ADB code is 0x72
711                0x06,0x7f,  //NX_POWER_KEY is 6, ADB code is 0x7f
712                0x07,0x4a,  //NX_KEYTYPE_MUTE is 7, ADB code is 0x4a
713                0x00,0x48,  //NX_KEYTYPE_SOUND_UP is 0, ADB code is 0x48
714                0x01,0x49,  //NX_KEYTYPE_SOUND_DOWN is 1, ADB code is 0x49
715                0x0a,0x47   //NX_KEYTYPE_NUM_LOCK is 10, ADB combines with CLEAR key for numlock
716        };
717        *length = sizeof(appleUSAFKeyMap);
718        return appleUSAFKeyMap;
719    }
720
721    static const unsigned char appleUSAKeyMap[] = {
722        0x00,0x00,
723
724        // Modifier Defs
725        0x0a,   //Number of modifier keys.  Was 7
726        //0x00,0x01,0x39,  //CAPSLOCK, uses one byte.
727        0x01,0x01,0x38,
728        0x02,0x01,0x3b,
729        0x03,0x01,0x3a,
730        0x04,0x01,0x37,
731        0x05,0x15,0x52,0x41,0x4c,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
732        0x43,0x4b,0x51,0x7b,0x7d,0x7e,0x7c,0x4e,0x59,
733        0x06,0x01,0x72,
734        0x09,0x01,0x3c, //Right shift
735        0x0a,0x01,0x3e, //Right control
736        0x0b,0x01,0x3d, //Right Option
737        0x0c,0x01,0x36, //Right Command
738
739        // key deffs
740        0xa2,
741        0x0d,0x00,0x61,0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01, //00
742        0x0d,0x00,0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13, //01
743        0x0d,0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04, //02
744        0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,0x06, //03
745        0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,0x18,0x00, //04
746        0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,0x07,0x00,0x07, //05
747        0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,0x00,0x1a,0x00,0x1a, //06
748        0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,0xce,0x00,0x18,0x00,0x18, //07
749        0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,0x01,0xd3,0x00,0x03,0x00,0x03, //08
750        0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,0xd6,0x01,0xe0,0x00,0x16,0x00,0x16, //09
751        0x02,0x00,0x3c,0x00,0x3e, //0a
752        0x0d,0x00,0x62,0x00,0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02, //0b
753        0x0d,0x00,0x71,0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11, //0c
754        0x0d,0x00,0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17, //0d
755        0x0d,0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05, //0e
756        0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,0x12, //0f
757        0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,0x00,0x19, //10
758        0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,0x14,0x00,0x14, //11
759        0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1, //12
760        0x0e,0x00,0x32,0x00,0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00, //13
761        0x0a,0x00,0x33,0x00,0x23,0x00,0xa3,0x01,0xba, //14
762        0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8, //15
763        0x0e,0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e, //16
764        0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd, //17
765        0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,0x01,0xb1, //18
766        0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab, //19
767        0x0a,0x00,0x37,0x00,0x26,0x01,0xb0,0x01,0xab, //1a
768        0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,0xd0,0x00,0x1f,0x00,0x1f, //1b
769        0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4, //1c
770        0x0a,0x00,0x30,0x00,0x29,0x00,0xad,0x00,0xbb, //1d
771        0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d, //1e
772        0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f, //1f
773        0x0d,0x00,0x75,0x00,0x55,0x00,0x15,0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15, //20
774        0x0e,0x00,0x5b,0x00,0x7b,0x00,0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b, //21
775        0x0d,0x00,0x69,0x00,0x49,0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09, //22
776        0x0d,0x00,0x70,0x00,0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10, //23
777        0x10,0x00,0x0d,0x00,0x03, //24
778        0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,0x0c,0x00,0x0c, //25
779        0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,0x00,0x0a,0x00,0x0a, //26
780        0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae, //27
781        0x0d,0x00,0x6b,0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b, //28
782        0x0a,0x00,0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2, //29
783        0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c, //2a
784        0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,0xa3, //2b
785        0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf, //2c
786        0x0d,0x00,0x6e,0x00,0x4e,0x00,0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e, //2d
787        0x0d,0x00,0x6d,0x00,0x4d,0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d, //2e
788        0x0a,0x00,0x2e,0x00,0x3e,0x00,0xbc,0x01,0xb3, //2f
789        0x02,0x00,0x09,0x00,0x19, //30
790        0x0c,0x00,0x20,0x00,0x00,0x00,0x80,0x00,0x00, //31
791        0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb, //32
792        0x02,0x00,0x7f,0x00,0x08, //33
793        0xff, //34
794        0x02,0x00,0x1b,0x00,0x7e, //35
795        0xff, //36
796        0xff, //37
797        0xff, //38
798        0xff, //39
799        0xff, //3a
800        0xff, //3b
801        0xff, //3c
802        0xff, //3d
803        0xff, //3e
804        0xff, //3f
805        0x00,0xfe,0x36, //40 is F17
806        0x00,0x00,0x2e, //41
807        0xff, //42
808        0x00,0x00,0x2a, //43
809        0xff, //44
810        0x00,0x00,0x2b, //45
811        0xff, //46
812        0x00,0x00,0x1b, //47
813        0xff, //48
814        0xff, //49
815        0xff, //4a
816        0x0e,0x00,0x2f,0x00,0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00, //4b
817        0x00,0x00,0x0d,  //4c //XX03
818        0xff, //4d
819        0x00,0x00,0x2d, //4e
820        0x00,0xfe,0x37, //4f is F18
821        0x00,0xfe,0x38, //50 is F19
822        0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,0x3d,0x00,0x7c,0x00,0x00,0x18,0x46, //51
823        0x00,0x00,0x30, //52
824        0x00,0x00,0x31, //53
825        0x00,0x00,0x32, //54
826        0x00,0x00,0x33, //55
827        0x00,0x00,0x34, //56
828        0x00,0x00,0x35, //57
829        0x00,0x00,0x36, //58
830        0x00,0x00,0x37, //59
831        0x00,0xfe,0x39, //5a is F20
832        0x00,0x00,0x38, //5b
833        0x00,0x00,0x39, //5c
834        0xff, //5d
835        0xff, //5e
836        0xff, //5f
837        0x00,0xfe,0x24, //60
838        0x00,0xfe,0x25, //61
839        0x00,0xfe,0x26, //62
840        0x00,0xfe,0x22, //63
841        0x00,0xfe,0x27, //64
842        0x00,0xfe,0x28, //65
843        0xff, //66
844        0x00,0xfe,0x2a, //67
845        0xff, //68
846        0x00,0xfe,0x32, //69
847        0x00,0xfe,0x35, //6a
848        0x00,0xfe,0x33, //6b
849        0xff, //6c
850        0x00,0xfe,0x29, //6d
851        0xff, //6e
852        0x00,0xfe,0x2b, //6f
853        0xff, //70
854        0x00,0xfe,0x34, //71
855        0xff, //72
856        0x00,0xfe,0x2e, //73
857        0x00,0xfe,0x30, //74
858        0x00,0xfe,0x2d, //75
859        0x00,0xfe,0x23, //76
860        0x00,0xfe,0x2f, //77
861        0x00,0xfe,0x21, //78
862        0x00,0xfe,0x31, //79
863        0x00,0xfe,0x20, //7a
864        0x00,0x01,0xac, //ADB=0x7b is left arrow
865        0x00,0x01,0xae, //ADB = 0x7c is right arrow
866        0x00,0x01,0xaf, //ADB=0x7d is down arrow.
867        0x00,0x01,0xad, //ADB=0x7e is up arrow
868
869            0x00,0x00,0x00,
870            0x00,0x00,0x00,
871            0x00,0x00,0x00, // Virtual = 0x81 is Spotlight
872            0x00,0x00,0x00, // Virtual = 0x82 is Dashboard
873            0x00,0x00,0x00, // Virtual = 0x83 is Launchpad
874            0x00,0x00,0x00,
875            0x00,0x00,0x00,
876            0x00,0x00,0x00,
877            0x00,0x00,0x00,
878            0x00,0x00,0x00,
879            0x00,0x00,0x00,
880            0x00,0x00,0x00,
881            0x00,0x00,0x00,
882            0x00,0x00,0x00,
883            0x00,0x00,0x00,
884            0x00,0x00,0x00,
885            0x00,0x00,0x00,
886            0x00,0x00,0x00, // Virtual = 0x90 is Main Brightness Up
887            0x00,0x00,0x00, // Virtual = 0x91 is Main Brightness Down
888            0x00,0x00,0x00,
889            0x00,0x00,0x00,
890            0x00,0x00,0x00,
891            0x00,0x00,0x00,
892            0x00,0x00,0x00,
893            0x00,0x00,0x00,
894            0x00,0x00,0x00,
895            0x00,0x00,0x00,
896            0x00,0x00,0x00,
897            0x00,0x00,0x00,
898            0x00,0x00,0x00,
899            0x00,0x00,0x00,
900            0x00,0x00,0x00,
901            0x00,0x00,0x00,
902            0x00,0x00,0x00, // Virtual = 0xa0 is Exposes All
903            0x00,0x00,0x00, // Virtual = 0xa1 is Expose Desktop
904
905
906        0x0f, // 15 sequences
907        0x02,0xff,0x04,0x00,0x31,
908        0x02,0xff,0x04,0x00,0x32,
909        0x02,0xff,0x04,0x00,0x33,
910        0x02,0xff,0x04,0x00,0x34,
911        0x02,0xff,0x04,0x00,0x35,
912        0x02,0xff,0x04,0x00,0x36,
913        0x02,0xff,0x04,0x00,0x37,
914        0x02,0xff,0x04,0x00,0x38,
915        0x02,0xff,0x04,0x00,0x39,
916        0x02,0xff,0x04,0x00,0x30,
917        0x02,0xff,0x04,0x00,0x2d,
918        0x02,0xff,0x04,0x00,0x3d,
919        0x02,0xff,0x04,0x00,0x70,
920        0x02,0xff,0x04,0x00,0x5d,
921        0x02,0xff,0x04,0x00,0x5b,
922
923            0x07, // following are 7 special keys
924            0x04,0x39,  //caps lock
925            0x05,0x72,  //NX_KEYTYPE_HELP is 5, ADB code is 0x72
926            0x06,0x7f,  //NX_POWER_KEY is 6, ADB code is 0x7f
927            0x07,0x4a,  //NX_KEYTYPE_MUTE is 7, ADB code is 0x4a
928            0x00,0x48,  //NX_KEYTYPE_SOUND_UP is 0, ADB code is 0x48
929            0x01,0x49,  //NX_KEYTYPE_SOUND_DOWN is 1, ADB code is 0x49
930            0x0a,0x47   //NX_KEYTYPE_NUM_LOCK is 10, ADB combines with CLEAR key for numlock
931    };
932    *length = sizeof(appleUSAKeyMap);
933    return appleUSAKeyMap;
934
935}
936
937//====================================================================================================
938// setParamProperties
939//====================================================================================================
940IOReturn IOHIDKeyboard::setParamProperties( OSDictionary * dict )
941{
942    IOHID_DEBUG(kIOHIDDebugCode_KeyboardSetParam, this, dict, dict ? dict->getCount() : 0, 0);
943
944    if ( _containsFKey ) {
945        setProperty(kIOHIDFKeyModeKey, OSDynamicCast(OSNumber, dict->getObject(kIOHIDFKeyModeKey)));
946    }
947
948    if ( _asyncLEDThread ) {
949        if ( OSDynamicCast(OSBoolean, dict->getObject(kIOHIDResetLEDsKey) ) ) {
950        	_resyncLED = TRUE;
951            IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadTrigger, this, _ledState, 2, 0);
952            thread_call_enter(_asyncLEDThread);
953        }
954    }
955
956    return super::setParamProperties(dict);
957}
958