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    _provider = NULL;
186    if (_asyncLEDThread)
187    {
188	thread_call_cancel(_asyncLEDThread);
189	thread_call_free(_asyncLEDThread);
190	_asyncLEDThread = 0;
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    UInt32          vendorID = _provider ? _provider->getVendorID() : 0;
217    unsigned int    keycode = 0xff;
218
219    if ((usagePage > 0xffff) || (usage > 0xffff))
220        IOLog("IOHIDKeyboard::dispatchKeyboardEvent usage/page unexpectedly large %02x:%02x\n", (int)usagePage, (int)usage);
221    setLastPageAndUsage(usagePage, usage);
222
223	switch (usagePage)
224	{
225		case kHIDPage_KeyboardOrKeypad:
226        case kHIDPage_AppleVendorKeyboard:
227            if (repeat != _repeat)
228            {
229                _repeat = repeat;
230                setRepeatMode(_repeat);
231            }
232
233            do {
234                if ( usagePage == kHIDPage_KeyboardOrKeypad ) {
235                    if ( alpha >= sizeof(_usb_2_adb_keymap) ) {
236                        IOLog("IOHIDKeyboard::dispatchKeyboardEvent usage unexpectedly large %02x:%02x\n", (int)usagePage, (int)usage);
237                        break;
238                    }
239
240                    keycode = _usb_2_adb_keymap[alpha];
241                }
242                else {
243                    if ( alpha >= sizeof(_usb_apple_2_adb_keymap) ) {
244                        IOLog("IOHIDKeyboard::dispatchKeyboardEvent usage unexpectedly large %02x:%02x\n", (int)usagePage, (int)usage);
245                        break;
246                    }
247
248                    keycode = _usb_apple_2_adb_keymap[alpha];
249                }
250
251                if ((usagePage == kHIDPage_AppleVendorKeyboard) &&
252                    (usage == kHIDUsage_AppleVendorKeyboard_Function) &&
253                    _containsFKey) {
254                    super::dispatchKeyboardEvent(0x3f, keyDown, timeStamp);
255                }
256                else {
257                    super::dispatchKeyboardEvent(keycode, keyDown, timeStamp);
258                }
259            } while ( 0 );
260            break;
261
262        case kHIDPage_AppleVendorTopCase:
263            if ((usage == kHIDUsage_AV_TopCase_KeyboardFn) && _containsFKey)
264                super::dispatchKeyboardEvent(0x3f, keyDown, timeStamp);
265			break;
266	}
267
268    clearLastPageAndUsage();
269}
270
271// **************************************************************************
272// _asyncLED
273//
274// Called asynchronously to turn on/off the keyboard LED
275//
276// **************************************************************************
277void
278IOHIDKeyboard::_asyncLED(OSObject *target)
279{
280    IOHIDKeyboard *me = OSDynamicCast(IOHIDKeyboard, target);
281    IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadActive, me, me ? me->_ledState : -1, me ? (uintptr_t)me->_provider : (uintptr_t)-1, 0);
282    me->Set_LED_States( me->_ledState );
283}
284
285void
286IOHIDKeyboard::Set_LED_States(UInt8 ledState)
287{
288    if (_provider) {
289    bool				resync = _resyncLED;
290
291    _resyncLED = FALSE;
292
293    for (int i=0; i<2; i++)
294    {
295        UInt32 value = (ledState >> i) & 1;
296
297        if (resync)
298			_provider->setElementValue(kHIDPage_LEDs, i + kHIDUsage_LED_NumLock, value ? 0 : 1);
299
300		_provider->setElementValue(kHIDPage_LEDs, i + kHIDUsage_LED_NumLock, value);
301    }
302    }
303}
304
305//******************************************************************************
306// COPIED from ADB keyboard driver 3/25/99
307// This is usually called on a call-out thread after the caps-lock key is pressed.
308// ADB operations to PMU are synchronous, and this is must not be done
309// on the call-out thread since that is the PMU driver workloop thread, and
310// it will block itself.
311//
312// Therefore, we schedule the ADB write to disconnect the call-out thread
313// and the one that initiates the ADB write.
314//
315// *******************************************************************************
316void
317IOHIDKeyboard::setAlphaLockFeedback ( bool LED_state)
318{
319    //*** TODO *** REVISIT ***
320    UInt8	newState = _ledState;
321
322    if (LED_state) //set alpha lock
323	newState |= kUSB_CAPSLOCKLED_SET;   //2nd bit is caps lock on USB
324    else
325	newState &= ~kUSB_CAPSLOCKLED_SET;
326
327    if (newState != _ledState)
328    {
329        _ledState = newState;
330
331        if (_asyncLEDThread) {
332            IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadTrigger, this, _ledState, 0, 0);
333            thread_call_enter(_asyncLEDThread);
334        }
335    }
336}
337
338
339
340void
341IOHIDKeyboard::setNumLockFeedback ( bool LED_state)
342{
343
344    //*** TODO *** REVISIT ***
345    UInt8	newState = _ledState;
346
347    if (LED_state)
348	newState |= kUSB_NUMLOCKLED_SET;   //1st bit is num lock on USB
349    else
350	newState &= ~kUSB_NUMLOCKLED_SET;
351
352    if (newState != _ledState)
353    {
354        _ledState = newState;
355
356        if (_asyncLEDThread) {
357            IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadTrigger, this, _ledState, 1, 0);
358            thread_call_enter(_asyncLEDThread);
359        }
360    }
361}
362
363
364//Called from parent classes
365unsigned
366IOHIDKeyboard::getLEDStatus (void )
367{
368    unsigned	ledState = 0;
369
370    if (_provider) {
371    for (int i=0; i<2; i++)
372    {
373		ledState |= (_provider->getElementValue(kHIDPage_LEDs, i + kHIDUsage_LED_NumLock)) << i;
374    }
375    }
376    return ledState;
377}
378
379// *************************************************************************
380// deviceType
381//
382// **************************************************************************
383UInt32
384IOHIDKeyboard::deviceType ( void )
385{
386    OSNumber 	*xml_handlerID;
387    UInt32      id;
388
389	// RY: If a _deviceType an IOHIKeyboard protected variable.  If it is
390    // non-zero, there is no need to obtain the handlerID again.  Just return
391    // the already set value.  This should prevent us from mistakenly changing
392    // changing a deviceType(keyboardType) value back to an unknow value after
393    // it has been set via MacBuddy or the keyboardPref.
394    if ( _deviceType )
395    {
396        id = _deviceType;
397    }
398    //Info.plist key is <integer>, not <string>
399    else {
400        xml_handlerID = _provider ? (OSNumber*)_provider->copyProperty("alt_handler_id") : NULL;
401        if ( OSDynamicCast(OSNumber, xml_handlerID) ) {
402        id = xml_handlerID->unsigned32BitValue();
403    }
404        else {
405        id = handlerID();
406    }
407        OSSafeReleaseNULL(xml_handlerID);
408    }
409
410    // ISO specific mappign to match ADB keyboards
411    // This should really be done in the keymaps.
412    switch ( id )
413    {
414        case kgestUSBCosmoISOKbd:
415        case kgestUSBAndyISOKbd:
416        case kgestQ6ISOKbd:
417        case kgestQ30ISOKbd:
418        case kgestM89ISOKbd:
419        case kgestUSBGenericISOkd:
420            _usb_2_adb_keymap[0x35] = 0x0a;
421            _usb_2_adb_keymap[0x64] = 0x32;
422            break;
423        default:
424            _usb_2_adb_keymap[0x35] = 0x32;
425            _usb_2_adb_keymap[0x64] = 0x0a;
426            break;
427    }
428
429    return id;
430
431}
432
433// ************************************************************************
434// interfaceID.  Fake ADB for now since USB defaultKeymapOfLength is too complex
435//
436// **************************************************************************
437UInt32
438IOHIDKeyboard::interfaceID ( void )
439{
440    //Return value must match "interface" line in .keyboard file
441    return NX_EVS_DEVICE_INTERFACE_ADB;  // 2 This matches contents of AppleExt.keyboard
442}
443
444
445/***********************************************/
446//Get handler ID
447//
448//  I assume that this method is only called if a valid USB keyboard
449//  is found. This method should return a 0 or something if there's
450//  no keyboard, but then the USB keyboard driver should never have
451//  been probed if there's no keyboard, so for now it won't return 0.
452UInt32
453IOHIDKeyboard::handlerID ( void )
454{
455    UInt32 ret_id       = kgestUSBUnknownANSIkd;  //Default for all unknown USB keyboards is 2
456
457    if (_provider) {
458        UInt16 productID    = _provider->getProductID();
459        UInt16 vendorID     = _provider->getVendorID();
460    if (vendorID == kIOUSBVendorIDAppleComputer)
461    {
462        switch (productID)
463        {
464            case kprodUSBCosmoANSIKbd:  //Cosmo ANSI is 0x201
465                    ret_id = kgestUSBCosmoANSIKbd; //0xc6
466                    break;
467            case kprodUSBCosmoISOKbd:  //Cosmo ISO
468                    ret_id = kgestUSBCosmoISOKbd; //0xc7
469                    break;
470            case kprodUSBCosmoJISKbd:  //Cosmo JIS
471                    ret_id = kgestUSBCosmoJISKbd;  //0xc8
472                    break;
473            case kprodUSBAndyANSIKbd:  //Andy ANSI is 0x204
474                    ret_id = kgestUSBAndyANSIKbd; //0xcc
475                    break;
476            case kprodUSBAndyISOKbd:  //Andy ISO
477                    ret_id = kgestUSBAndyISOKbd; //0xcd
478                    break;
479            case kprodUSBAndyJISKbd:  //Andy JIS is 0x206
480                    ret_id = kgestUSBAndyJISKbd; //0xce
481                    break;
482            case kprodQ6ANSIKbd:  //Q6 ANSI
483                    ret_id = kgestQ6ANSIKbd;
484                    break;
485            case kprodQ6ISOKbd:  //Q6 ISO
486                    ret_id = kgestQ6ISOKbd;
487                    break;
488            case kprodQ6JISKbd:  //Q6 JIS
489                    ret_id = kgestQ6JISKbd;
490                    break;
491            case kprodQ30ANSIKbd:  //Q30 ANSI
492                    ret_id = kgestQ30ANSIKbd;
493                    break;
494            case kprodQ30ISOKbd:  //Q30 ISO
495                    ret_id = kgestQ30ISOKbd;
496                    break;
497            case kprodQ30JISKbd:  //Q30 JIS
498                    ret_id = kgestQ30JISKbd;
499                    break;
500            case kprodFountainANSIKbd:  //Fountain ANSI
501                    ret_id = kgestFountainANSIKbd;
502                    break;
503            case kprodFountainISOKbd:  //Fountain ISO
504                    ret_id = kgestFountainISOKbd;
505                    break;
506            case kprodFountainJISKbd:  //Fountain JIS
507                    ret_id = kgestFountainJISKbd;
508                    break;
509            case kprodSantaANSIKbd:  //Santa ANSI
510                    ret_id = kgestSantaANSIKbd;
511                    break;
512            case kprodSantaISOKbd:  //Santa ISO
513                    ret_id = kgestSantaISOKbd;
514                    break;
515            case kprodSantaJISKbd:  //Santa JIS
516                    ret_id = kgestSantaJISKbd;
517                    break;
518
519
520            default:  // No Gestalt.h values, but still is Apple keyboard,
521                    //   so return a generic Cosmo ANSI
522                    ret_id = kgestUSBCosmoANSIKbd;
523                    break;
524        }
525    }
526    }
527
528    return ret_id;  //non-Apple USB keyboards should all return "2"
529}
530
531
532// *****************************************************************************
533// defaultKeymapOfLength
534// A.W. copied from ADB keyboard, I don't have time to make custom USB version
535// *****************************************************************************
536const unsigned char *
537IOHIDKeyboard::defaultKeymapOfLength (UInt32 * length )
538{
539    if ( _containsFKey )
540    {
541        // this one defines the FKeyMap
542        static const unsigned char appleUSAFKeyMap[] = {
543            0x00,0x00,
544
545            // Modifier Defs
546            0x0b,   //Number of modifier keys.  Was 7
547            //0x00,0x01,0x39,  //CAPSLOCK, uses one byte.
548            0x01,0x01,0x38,
549            0x02,0x01,0x3b,
550            0x03,0x01,0x3a,
551            0x04,0x01,0x37,
552            0x05,0x14,0x52,0x41,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
553            0x43,0x4b,0x51,0x7b,0x7d,0x7e,0x7c,0x4e,0x59,
554            0x06,0x01,0x72,
555            0x07,0x01,0x3f, //NX_MODIFIERKEY_SECONDARYFN 8th modifier
556            0x09,0x01,0x3c, //Right shift
557            0x0a,0x01,0x3e, //Right control
558            0x0b,0x01,0x3d, //Right Option
559            0x0c,0x01,0x36, //Right Command
560
561        // key deffs
562        0xa2,
563        0x0d,0x00,0x61,0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01, //00
564        0x0d,0x00,0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13, //01
565        0x0d,0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04, //02
566        0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,0x06, //03
567        0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,0x18,0x00, //04
568        0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,0x07,0x00,0x07, //05
569        0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,0x00,0x1a,0x00,0x1a, //06
570        0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,0xce,0x00,0x18,0x00,0x18, //07
571        0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,0x01,0xd3,0x00,0x03,0x00,0x03, //08
572        0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,0xd6,0x01,0xe0,0x00,0x16,0x00,0x16, //09
573        0x02,0x00,0x3c,0x00,0x3e, //0a
574        0x0d,0x00,0x62,0x00,0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02, //0b
575        0x0d,0x00,0x71,0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11, //0c
576        0x0d,0x00,0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17, //0d
577        0x0d,0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05, //0e
578        0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,0x12, //0f
579        0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,0x00,0x19, //10
580        0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,0x14,0x00,0x14, //11
581        0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1, //12
582        0x0e,0x00,0x32,0x00,0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00, //13
583        0x0a,0x00,0x33,0x00,0x23,0x00,0xa3,0x01,0xba, //14
584        0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8, //15
585        0x0e,0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e, //16
586        0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd, //17
587        0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,0x01,0xb1, //18
588        0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab, //19
589        0x0a,0x00,0x37,0x00,0x26,0x01,0xb0,0x01,0xab, //1a
590        0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,0xd0,0x00,0x1f,0x00,0x1f, //1b
591        0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4, //1c
592        0x0a,0x00,0x30,0x00,0x29,0x00,0xad,0x00,0xbb, //1d
593        0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d, //1e
594        0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f, //1f
595        0x0d,0x00,0x75,0x00,0x55,0x00,0x15,0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15, //20
596        0x0e,0x00,0x5b,0x00,0x7b,0x00,0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b, //21
597        0x0d,0x00,0x69,0x00,0x49,0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09, //22
598        0x0d,0x00,0x70,0x00,0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10, //23
599        0x10,0x00,0x0d,0x00,0x03, //24
600        0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,0x0c,0x00,0x0c, //25
601        0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,0x00,0x0a,0x00,0x0a, //26
602        0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae, //27
603        0x0d,0x00,0x6b,0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b, //28
604        0x0a,0x00,0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2, //29
605        0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c, //2a
606        0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,0xa3, //2b
607        0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf, //2c
608        0x0d,0x00,0x6e,0x00,0x4e,0x00,0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e, //2d
609        0x0d,0x00,0x6d,0x00,0x4d,0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d, //2e
610        0x0a,0x00,0x2e,0x00,0x3e,0x00,0xbc,0x01,0xb3, //2f
611        0x02,0x00,0x09,0x00,0x19, //30
612        0x0c,0x00,0x20,0x00,0x00,0x00,0x80,0x00,0x00, //31
613        0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb, //32
614        0x02,0x00,0x7f,0x00,0x08, //33
615        0xff, //34
616        0x02,0x00,0x1b,0x00,0x7e, //35
617        0xff, //36
618        0xff, //37
619        0xff, //38
620        0xff, //39
621        0xff, //3a
622        0xff, //3b
623        0xff, //3c
624        0xff, //3d
625        0xff, //3e
626        0xff, //3f
627        0x00,0xfe,0x36, //40 is F17
628        0x00,0x00,0x2e, //41
629        0xff, //42
630        0x00,0x00,0x2a, //43
631        0xff, //44
632        0x00,0x00,0x2b, //45
633        0xff, //46
634        0x00,0x00,0x1b, //47
635        0xff, //48
636        0xff, //49
637        0xff, //4a
638        0x0e,0x00,0x2f,0x00,0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00, //4b
639        0x00,0x00,0x0d,  //4c //XX03
640        0xff, //4d
641        0x00,0x00,0x2d, //4e
642        0x00,0xfe,0x37, //4f is F18
643        0x00,0xfe,0x38, //50 is F19
644        0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,0x3d,0x00,0x7c,0x00,0x00,0x18,0x46, //51
645        0x00,0x00,0x30, //52
646        0x00,0x00,0x31, //53
647        0x00,0x00,0x32, //54
648        0x00,0x00,0x33, //55
649        0x00,0x00,0x34, //56
650        0x00,0x00,0x35, //57
651        0x00,0x00,0x36, //58
652        0x00,0x00,0x37, //59
653        0x00,0xfe,0x39, //5a is F20
654        0x00,0x00,0x38, //5b
655        0x00,0x00,0x39, //5c
656        0xff, //5d
657        0xff, //5e
658        0xff, //5f
659        0x00,0xfe,0x24, //60
660        0x00,0xfe,0x25, //61
661        0x00,0xfe,0x26, //62
662        0x00,0xfe,0x22, //63
663        0x00,0xfe,0x27, //64
664        0x00,0xfe,0x28, //65
665        0xff, //66
666        0x00,0xfe,0x2a, //67
667        0xff, //68
668        0x00,0xfe,0x32, //69
669        0x00,0xfe,0x35, //6a
670        0x00,0xfe,0x33, //6b
671        0xff, //6c
672        0x00,0xfe,0x29, //6d
673        0xff, //6e
674        0x00,0xfe,0x2b, //6f
675        0xff, //70
676        0x00,0xfe,0x34, //71
677        0xff, //72
678        0x00,0xfe,0x2e, //73
679        0x00,0xfe,0x30, //74
680        0x00,0xfe,0x2d, //75
681        0x00,0xfe,0x23, //76
682        0x00,0xfe,0x2f, //77
683        0x00,0xfe,0x21, //78
684        0x00,0xfe,0x31, //79
685        0x00,0xfe,0x20, //7a
686        0x00,0x01,0xac, //ADB=0x7b is left arrow
687        0x00,0x01,0xae, //ADB = 0x7c is right arrow
688        0x00,0x01,0xaf, //ADB=0x7d is down arrow.
689        0x00,0x01,0xad, //ADB=0x7e is up arrow
690
691            0x00,0x00,0x00,
692            0x00,0x00,0x00,
693            0x00,0x00,0x00, // Virtual = 0x81 is Spotlight
694            0x00,0x00,0x00, // Virtual = 0x82 is Dashboard
695            0x00,0x00,0x00, // Virtual = 0x83 is Launchpad
696            0x00,0x00,0x00,
697            0x00,0x00,0x00,
698            0x00,0x00,0x00,
699            0x00,0x00,0x00,
700            0x00,0x00,0x00,
701            0x00,0x00,0x00,
702            0x00,0x00,0x00,
703            0x00,0x00,0x00,
704            0x00,0x00,0x00,
705            0x00,0x00,0x00,
706            0x00,0x00,0x00,
707            0x00,0x00,0x00,
708            0x00,0x00,0x00, // Virtual = 0x90 is Main Brightness Up
709            0x00,0x00,0x00, // Virtual = 0x91 is Main Brightness Down
710            0x00,0x00,0x00,
711            0x00,0x00,0x00,
712            0x00,0x00,0x00,
713            0x00,0x00,0x00,
714            0x00,0x00,0x00,
715            0x00,0x00,0x00,
716            0x00,0x00,0x00,
717            0x00,0x00,0x00,
718            0x00,0x00,0x00,
719            0x00,0x00,0x00,
720            0x00,0x00,0x00,
721            0x00,0x00,0x00,
722            0x00,0x00,0x00,
723            0x00,0x00,0x00,
724            0x00,0x00,0x00, // Virtual = 0xa0 is Exposes All
725            0x00,0x00,0x00, // Virtual = 0xa1 is Expose Desktop
726
727                0x0f,0x02,0xff,0x04,
728                0x00,0x31,0x02,0xff,0x04,0x00,0x32,0x02,0xff,0x04,0x00,0x33,0x02,0xff,0x04,0x00,
729                0x34,0x02,0xff,0x04,0x00,0x35,0x02,0xff,0x04,0x00,0x36,0x02,0xff,0x04,0x00,0x37,
730                0x02,0xff,0x04,0x00,0x38,0x02,0xff,0x04,0x00,0x39,0x02,0xff,0x04,0x00,0x30,0x02,
731                0xff,0x04,0x00,0x2d,0x02,0xff,0x04,0x00,0x3d,0x02,0xff,0x04,0x00,0x70,0x02,0xff,
732                0x04,0x00,0x5d,0x02,0xff,0x04,0x00,0x5b,
733                0x07, // following are 7 special keys
734                0x04,0x39,  //caps lock
735                0x05,0x72,  //NX_KEYTYPE_HELP is 5, ADB code is 0x72
736                0x06,0x7f,  //NX_POWER_KEY is 6, ADB code is 0x7f
737                0x07,0x4a,  //NX_KEYTYPE_MUTE is 7, ADB code is 0x4a
738                0x00,0x48,  //NX_KEYTYPE_SOUND_UP is 0, ADB code is 0x48
739                0x01,0x49,  //NX_KEYTYPE_SOUND_DOWN is 1, ADB code is 0x49
740                0x0a,0x47   //NX_KEYTYPE_NUM_LOCK is 10, ADB combines with CLEAR key for numlock
741        };
742        *length = sizeof(appleUSAFKeyMap);
743        return appleUSAFKeyMap;
744    }
745
746    static const unsigned char appleUSAKeyMap[] = {
747        0x00,0x00,
748
749        // Modifier Defs
750        0x0a,   //Number of modifier keys.  Was 7
751        //0x00,0x01,0x39,  //CAPSLOCK, uses one byte.
752        0x01,0x01,0x38,
753        0x02,0x01,0x3b,
754        0x03,0x01,0x3a,
755        0x04,0x01,0x37,
756        0x05,0x15,0x52,0x41,0x4c,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
757        0x43,0x4b,0x51,0x7b,0x7d,0x7e,0x7c,0x4e,0x59,
758        0x06,0x01,0x72,
759        0x09,0x01,0x3c, //Right shift
760        0x0a,0x01,0x3e, //Right control
761        0x0b,0x01,0x3d, //Right Option
762        0x0c,0x01,0x36, //Right Command
763
764        // key deffs
765        0xa2,
766        0x0d,0x00,0x61,0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01, //00
767        0x0d,0x00,0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13, //01
768        0x0d,0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04, //02
769        0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,0x06, //03
770        0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,0x18,0x00, //04
771        0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,0x07,0x00,0x07, //05
772        0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,0x00,0x1a,0x00,0x1a, //06
773        0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,0xce,0x00,0x18,0x00,0x18, //07
774        0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,0x01,0xd3,0x00,0x03,0x00,0x03, //08
775        0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,0xd6,0x01,0xe0,0x00,0x16,0x00,0x16, //09
776        0x02,0x00,0x3c,0x00,0x3e, //0a
777        0x0d,0x00,0x62,0x00,0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02, //0b
778        0x0d,0x00,0x71,0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11, //0c
779        0x0d,0x00,0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17, //0d
780        0x0d,0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05, //0e
781        0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,0x12, //0f
782        0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,0x00,0x19, //10
783        0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,0x14,0x00,0x14, //11
784        0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1, //12
785        0x0e,0x00,0x32,0x00,0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00, //13
786        0x0a,0x00,0x33,0x00,0x23,0x00,0xa3,0x01,0xba, //14
787        0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8, //15
788        0x0e,0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e, //16
789        0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd, //17
790        0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,0x01,0xb1, //18
791        0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab, //19
792        0x0a,0x00,0x37,0x00,0x26,0x01,0xb0,0x01,0xab, //1a
793        0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,0xd0,0x00,0x1f,0x00,0x1f, //1b
794        0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4, //1c
795        0x0a,0x00,0x30,0x00,0x29,0x00,0xad,0x00,0xbb, //1d
796        0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d, //1e
797        0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f, //1f
798        0x0d,0x00,0x75,0x00,0x55,0x00,0x15,0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15, //20
799        0x0e,0x00,0x5b,0x00,0x7b,0x00,0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b, //21
800        0x0d,0x00,0x69,0x00,0x49,0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09, //22
801        0x0d,0x00,0x70,0x00,0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10, //23
802        0x10,0x00,0x0d,0x00,0x03, //24
803        0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,0x0c,0x00,0x0c, //25
804        0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,0x00,0x0a,0x00,0x0a, //26
805        0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae, //27
806        0x0d,0x00,0x6b,0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b, //28
807        0x0a,0x00,0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2, //29
808        0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c, //2a
809        0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,0xa3, //2b
810        0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf, //2c
811        0x0d,0x00,0x6e,0x00,0x4e,0x00,0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e, //2d
812        0x0d,0x00,0x6d,0x00,0x4d,0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d, //2e
813        0x0a,0x00,0x2e,0x00,0x3e,0x00,0xbc,0x01,0xb3, //2f
814        0x02,0x00,0x09,0x00,0x19, //30
815        0x0c,0x00,0x20,0x00,0x00,0x00,0x80,0x00,0x00, //31
816        0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb, //32
817        0x02,0x00,0x7f,0x00,0x08, //33
818        0xff, //34
819        0x02,0x00,0x1b,0x00,0x7e, //35
820        0xff, //36
821        0xff, //37
822        0xff, //38
823        0xff, //39
824        0xff, //3a
825        0xff, //3b
826        0xff, //3c
827        0xff, //3d
828        0xff, //3e
829        0xff, //3f
830        0x00,0xfe,0x36, //40 is F17
831        0x00,0x00,0x2e, //41
832        0xff, //42
833        0x00,0x00,0x2a, //43
834        0xff, //44
835        0x00,0x00,0x2b, //45
836        0xff, //46
837        0x00,0x00,0x1b, //47
838        0xff, //48
839        0xff, //49
840        0xff, //4a
841        0x0e,0x00,0x2f,0x00,0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00, //4b
842        0x00,0x00,0x0d,  //4c //XX03
843        0xff, //4d
844        0x00,0x00,0x2d, //4e
845        0x00,0xfe,0x37, //4f is F18
846        0x00,0xfe,0x38, //50 is F19
847        0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,0x3d,0x00,0x7c,0x00,0x00,0x18,0x46, //51
848        0x00,0x00,0x30, //52
849        0x00,0x00,0x31, //53
850        0x00,0x00,0x32, //54
851        0x00,0x00,0x33, //55
852        0x00,0x00,0x34, //56
853        0x00,0x00,0x35, //57
854        0x00,0x00,0x36, //58
855        0x00,0x00,0x37, //59
856        0x00,0xfe,0x39, //5a is F20
857        0x00,0x00,0x38, //5b
858        0x00,0x00,0x39, //5c
859        0xff, //5d
860        0xff, //5e
861        0xff, //5f
862        0x00,0xfe,0x24, //60
863        0x00,0xfe,0x25, //61
864        0x00,0xfe,0x26, //62
865        0x00,0xfe,0x22, //63
866        0x00,0xfe,0x27, //64
867        0x00,0xfe,0x28, //65
868        0xff, //66
869        0x00,0xfe,0x2a, //67
870        0xff, //68
871        0x00,0xfe,0x32, //69
872        0x00,0xfe,0x35, //6a
873        0x00,0xfe,0x33, //6b
874        0xff, //6c
875        0x00,0xfe,0x29, //6d
876        0xff, //6e
877        0x00,0xfe,0x2b, //6f
878        0xff, //70
879        0x00,0xfe,0x34, //71
880        0xff, //72
881        0x00,0xfe,0x2e, //73
882        0x00,0xfe,0x30, //74
883        0x00,0xfe,0x2d, //75
884        0x00,0xfe,0x23, //76
885        0x00,0xfe,0x2f, //77
886        0x00,0xfe,0x21, //78
887        0x00,0xfe,0x31, //79
888        0x00,0xfe,0x20, //7a
889        0x00,0x01,0xac, //ADB=0x7b is left arrow
890        0x00,0x01,0xae, //ADB = 0x7c is right arrow
891        0x00,0x01,0xaf, //ADB=0x7d is down arrow.
892        0x00,0x01,0xad, //ADB=0x7e is up arrow
893
894            0x00,0x00,0x00,
895            0x00,0x00,0x00,
896            0x00,0x00,0x00, // Virtual = 0x81 is Spotlight
897            0x00,0x00,0x00, // Virtual = 0x82 is Dashboard
898            0x00,0x00,0x00, // Virtual = 0x83 is Launchpad
899            0x00,0x00,0x00,
900            0x00,0x00,0x00,
901            0x00,0x00,0x00,
902            0x00,0x00,0x00,
903            0x00,0x00,0x00,
904            0x00,0x00,0x00,
905            0x00,0x00,0x00,
906            0x00,0x00,0x00,
907            0x00,0x00,0x00,
908            0x00,0x00,0x00,
909            0x00,0x00,0x00,
910            0x00,0x00,0x00,
911            0x00,0x00,0x00, // Virtual = 0x90 is Main Brightness Up
912            0x00,0x00,0x00, // Virtual = 0x91 is Main Brightness Down
913            0x00,0x00,0x00,
914            0x00,0x00,0x00,
915            0x00,0x00,0x00,
916            0x00,0x00,0x00,
917            0x00,0x00,0x00,
918            0x00,0x00,0x00,
919            0x00,0x00,0x00,
920            0x00,0x00,0x00,
921            0x00,0x00,0x00,
922            0x00,0x00,0x00,
923            0x00,0x00,0x00,
924            0x00,0x00,0x00,
925            0x00,0x00,0x00,
926            0x00,0x00,0x00,
927            0x00,0x00,0x00, // Virtual = 0xa0 is Exposes All
928            0x00,0x00,0x00, // Virtual = 0xa1 is Expose Desktop
929
930
931        0x0f, // 15 sequences
932        0x02,0xff,0x04,0x00,0x31,
933        0x02,0xff,0x04,0x00,0x32,
934        0x02,0xff,0x04,0x00,0x33,
935        0x02,0xff,0x04,0x00,0x34,
936        0x02,0xff,0x04,0x00,0x35,
937        0x02,0xff,0x04,0x00,0x36,
938        0x02,0xff,0x04,0x00,0x37,
939        0x02,0xff,0x04,0x00,0x38,
940        0x02,0xff,0x04,0x00,0x39,
941        0x02,0xff,0x04,0x00,0x30,
942        0x02,0xff,0x04,0x00,0x2d,
943        0x02,0xff,0x04,0x00,0x3d,
944        0x02,0xff,0x04,0x00,0x70,
945        0x02,0xff,0x04,0x00,0x5d,
946        0x02,0xff,0x04,0x00,0x5b,
947
948            0x07, // following are 7 special keys
949            0x04,0x39,  //caps lock
950            0x05,0x72,  //NX_KEYTYPE_HELP is 5, ADB code is 0x72
951            0x06,0x7f,  //NX_POWER_KEY is 6, ADB code is 0x7f
952            0x07,0x4a,  //NX_KEYTYPE_MUTE is 7, ADB code is 0x4a
953            0x00,0x48,  //NX_KEYTYPE_SOUND_UP is 0, ADB code is 0x48
954            0x01,0x49,  //NX_KEYTYPE_SOUND_DOWN is 1, ADB code is 0x49
955            0x0a,0x47   //NX_KEYTYPE_NUM_LOCK is 10, ADB combines with CLEAR key for numlock
956    };
957    *length = sizeof(appleUSAKeyMap);
958    return appleUSAKeyMap;
959
960}
961
962//====================================================================================================
963// setParamProperties
964//====================================================================================================
965IOReturn IOHIDKeyboard::setParamProperties( OSDictionary * dict )
966{
967    IOHID_DEBUG(kIOHIDDebugCode_KeyboardSetParam, this, dict, dict ? dict->getCount() : 0, 0);
968
969    if ( _containsFKey ) {
970        setProperty(kIOHIDFKeyModeKey, OSDynamicCast(OSNumber, dict->getObject(kIOHIDFKeyModeKey)));
971    }
972
973    if ( _asyncLEDThread ) {
974        if ( OSDynamicCast(OSBoolean, dict->getObject(kIOHIDResetLEDsKey) ) ) {
975        	_resyncLED = TRUE;
976            IOHID_DEBUG(kIOHIDDebugCode_KeyboardLEDThreadTrigger, this, _ledState, 2, 0);
977            thread_call_enter(_asyncLEDThread);
978        }
979    }
980
981    return super::setParamProperties(dict);
982}
983