|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1998, 1999 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: *
27: */
28: #include <libkern/OSByteOrder.h>
29:
30: #include "AppleKeyboard.h"
31: #include <IOKit/hidsystem/IOHIPointing.h>
32: #include <IOKit/IOBufferMemoryDescriptor.h>
33: #include <IOKit/usb/IOUSBInterface.h>
34: #include <IOKit/usb/IOUSBPipe.h>
35: #include <IOKit/usb/IOUSBController.h>
36:
37: extern "C" {
38: #include <pexpert/pexpert.h>
39: }
40:
41:
42: #define super IOHIKeyboard
43: #define self this
44: #define DEBUGGING_LEVEL 0
45:
46: OSDefineMetaClassAndStructors(AppleKeyboard, IOHIKeyboard)
47:
48: extern unsigned char usb_2_adb_keymap[]; //In Cosmo_USB2ADB.cpp
49:
50: static IOUSBController *sPollControl;
51: static IOUSBPipe *sPollPipe;
52: static UInt8 sBuffer[8];
53: static IOMemoryDescriptor *sBufDesc;
54: static bool sComplete = true;
55:
56:
57: static void bodgeComplete(void *target, void * parameter, IOReturn status, UInt32 bufferSizeRemaining)
58: {
59: sComplete = true;
60: }
61:
62: static int PE_usb_poll_input(unsigned int options, char * c)
63: {
64: static char adbkeycodes2ascii[] = "asdfhgzxcv_bqwer"//00
65: "yt123465=97-80]o" //10
66: "u[ip\nlj'k;_,/nm." //20
67: "\t_"; //30
68: *c = 0xff;
69:
70: if(!sPollPipe)
71: return 0;
72: if(sComplete) {
73: IOUSBCompletion completion;
74: sComplete = false;
75:
76: *c = adbkeycodes2ascii[usb_2_adb_keymap[sBuffer[2]]];
77: completion.target = 0;
78: completion.action = bodgeComplete;
79: completion.parameter = 0;
80:
81: sPollControl->PolledRead(
82: sPollPipe->address() /*functionAddress*/,
83: sPollPipe->endpoint()->number /*endpointNumber*/,
84: completion /*completion*/,
85: sBufDesc /*buffer*/,
86: true /*bufferRounding*/,
87: sizeof(sBuffer) /*bufferSize*/);
88: }
89: else
90: sPollControl->pollInterrupts(bodgeComplete); // Only complete our transactions
91:
92: return 0;
93: }
94:
95: void usb_asyncLED ( AppleKeyboard * me );
96: AppleKeyboard *glob_usbkeyboard_obj;
97:
98: bool AppleKeyboard::start(IOService * provider)
99: {
100: IOReturn err = 0;
101:
102: if( !super::start(provider))
103: return (false);
104:
105: // remember my device
106: _interface = OSDynamicCast(IOUSBInterface, provider);
107: _deviceDescriptor = _interface->deviceDescriptor();
108: _prevent_LED_set = FALSE;
109:
110: //Following 3 lines moved here from Simulate_ADB_Event to make multiple
111: // keyboards work correctly. The instance variables cannot be shared
112: // between each instance of this driver for each USB keyboard.
113: prev_bytes_read=8;
114: oldmodifier = 0xff;
115: bzero( old_array, kUSB_LOWSPEED_MAXPACKET);
116:
117:
118: if (_interface->open(self) == false) return false;
119:
120: //Fix hardware bug in iMac USB keyboard mapping for ISO keyboards
121: //kprintf("\nUSB product = %x, vendor = %x\n", _deviceDescriptor->product, _deviceDescriptor->vendor);
122: if ( _deviceDescriptor) //just to be safe
123: {
124: if (_deviceDescriptor->vendor == 0xac05) //Apple Corp. vendor ID, not byte swapped
125: {
126: switch (_deviceDescriptor->product)
127: {
128: case 0x0201: //North American iMac keyboard
129: break; // return 18
130: case 0x0203: //38=Japanese. 34 is adjustable JIS
131: break; // return 34;
132: case 0x0202: //Arabic, other ISO such as German
133: //Swap two ISO keys around
134: usb_2_adb_keymap[0x35] = 0x0a; //Cosmo key18 swaps with key74, 0a is ADB keycode
135: usb_2_adb_keymap[0x64] = 0x32;
136: break;
137: // return 21; //21 is Apple ISO Extended Keyboard
138: default:
139: //return 18;
140: break;
141: }
142: }
143:
144:
145:
146: if (_deviceDescriptor->vendor == 0x5e04) //Microsoft ID
147: {
148: //Figure out what to do with Microsoft keyboard later
149:
150: //if (usb_kbd_product_id == 0x000b) //Natural USB+PS/2 keyboard
151: //return 18;
152: }
153: }
154:
155: do {
156: IOLog("%s: USB Generic Keyboard @ %d\n", getName(), _interface->address());
157:
158: #if 0
159:
160: kprintf("Adam: Class is %d\n", req.theClass); //3 HID
161: kprintf("Adam: SubClass is %d\n", req.subClass); //1
162: kprintf("Adam: Protocol is %d\n", req.protocol); //1 keyboard
163:
164: kprintf("Adam: Type is %d\n", (_interface->endpoints[0])->transferType); //I get 1
165: kprintf("Adam: Number is %d\n", (_interface->endpoints[0])->number); // I get 1
166:
167: #endif
168:
169: //setAlphaLockFeedback(false); //Disable caps lock LED at first
170:
171: IOUSBFindEndpointRequest request;
172: request.type = kUSBInterrupt;
173: request.direction = kUSBIn;
174: _interruptPipe = _interface->findNextPipe(NULL, &request);
175:
176: if(!_interruptPipe)
177: return false;
178:
179: _maxPacketSize = request.maxPacketSize;
180: _buffer = IOBufferMemoryDescriptor::withCapacity(8, kIODirectionIn);
181:
182: _completion.target = (void *)self;
183: _completion.action = (IOUSBCompletionAction) &AppleKeyboard::readHandler;
184: _completion.parameter = (void *)0; // not used
185:
186: _buffer->setLength(_maxPacketSize); // shouldn't this be _maxPacketSize?
187:
188: if ((err = _interruptPipe->read(_buffer, &_completion)))
189: break;
190:
191: #if (DEBUGGING_LEVEL > 0)
192: //printInterfaceDescriptor(_interface->descriptor);
193: #endif
194:
195: // Save stuff for polled mode
196: sPollControl = _interface->bus();
197: sPollPipe = _interruptPipe;
198: sBufDesc = IOMemoryDescriptor::withAddress(sBuffer, 8, kIODirectionIn);
199: PE_poll_input = PE_usb_poll_input;
200:
201: return(true);
202:
203: } while (false);
204:
205: IOLog("%s: aborting startup. err = %d\n", getName(), err);
206:
207: provider->close(this);
208: stop(provider);
209:
210: return(false);
211: }
212:
213: void AppleKeyboard::stop(IOService * provider)
214: {
215: if (_buffer) {
216: _buffer->release();
217: _buffer = 0;
218: }
219: if(sPollPipe == _interruptPipe) {
220: sPollControl = NULL;
221: sPollPipe = NULL;
222: sBufDesc->release();
223: sBufDesc = NULL;
224: }
225: super::stop(provider);
226: }
227:
228: void AppleKeyboard::test_myusb_f1(void)
229: {
230: /*
231: char dummy[8];
232: IOReturn err = kIOReturnSuccess;
233: OSData *writebuf;
234: IOUSBPipe * tinterruptPipe;
235:
236: writebuf = OSData::withCapacity(8);
237: err = _device->openPipe(&tinterruptPipe, _interface->endpoints[0]);
238: kprintf("Adam1: err is %x\n", err);
239: dummy[0] = 0xff;
240: dummy[1] = 0xff;
241: dummy[2] = 0xff;
242: dummy[3] = 0xff;
243: dummy[4] = 0xff;
244: dummy[5] = 0xff;
245: dummy[6] = 0xff;
246: dummy[7] = 0xff;
247:
248: writebuf->appendBytes(dummy, 8);
249: // err = _device->write(writebuf, tinterruptPipe);
250: kprintf("Adam2: err is %x\n", err);
251: //deallocate writebuf
252: */
253: }
254:
255:
256: //bits = 2 is Caps Lock, I haven't tried anything else. 0 clears all
257: void AppleKeyboard::Set_LED_States(UInt8 bits)
258: {
259: IOReturn err = kIOReturnSuccess;
260: IOUSBCompletion completion;
261:
262:
263: if (_prevent_LED_set)
264: return;
265:
266: //_request and _hid_report must be static because the deviceRequest() call
267: // is asynchronous.
268:
269: _request.rqDirection = kUSBOut;
270: _request.rqType = kUSBClass;
271: _request.rqRecipient = kUSBInterface;
272: _request.bRequest = kHIDRqSetReport; //Set Report in HID specs
273: OSWriteLittleInt16(&_request.wValue, 0, (UInt16) kHIDRtOutputReport << 8 );
274: OSWriteLittleInt16(&_request.wIndex, 0,
275: _interface->interfaceDescriptor()->interfaceNumber); // 0 for iMac keyboards
276: OSWriteLittleInt16(&_request.wLength, 0, 1); // MacOS 8.5 hard-codes it to 1 byte length
277: _hid_report[0] = bits; // 2 to set LED, 0 to clear all LEDs
278: _hid_report[1] = 0;
279: _request.pData = (void *)_hid_report;
280:
281: completion.target = (void *)self;
282: completion.action = &AppleKeyboard::setLEDHandler;
283: completion.parameter = (void *)0;
284: err = _interface->deviceRequest(&_request, &completion);
285: return;
286:
287: }
288:
289:
290: extern "C" {
291: void Debugger( const char * );
292: void boot(int paniced, int howto, char * command);
293: #define RB_BOOT 1 /* Causes reboot, not halt. Is in xnu/bsd/sys/reboot.h */
294:
295: }
296:
297:
298: //This helper function is only called by StartHandler below. key_ptr points
299: // to 8 (kUSB_LOWSPEED_MAXPACKET) valid bytes of data
300: void AppleKeyboard::Simulate_ADB_Event(UInt8 *key_ptr, UInt32 bytes_read)
301: {
302: UInt8 alpha, modifier=0;
303: bool found;
304: AbsoluteTime now;
305: UInt8 seq_key, i;//counter for alpha keys pressed.
306:
307: /**
308: UInt8 *kbdData;
309: kbdData = key_ptr;
310: kprintf("Num = %d x%x x%x x%x x%x x%x x%x x%x x%x\n",
311: bytes_read, *kbdData, *(kbdData +1),
312: *(kbdData+2), *(kbdData +3),
313: *(kbdData+4), *(kbdData +5),
314: *(kbdData+6), *(kbdData +7)
315: );
316: **/
317:
318: // Test for the keyboard bug where all the keys are 0x01. JDC.
319: found = true;
320: for (seq_key = 2; seq_key < prev_bytes_read; seq_key++) {
321: if (*(key_ptr + seq_key) != 1) found = false;
322: }
323: if (found) return;
324:
325:
326: if (bytes_read > kUSB_LOWSPEED_MAXPACKET) // 8 bytes
327: {
328: bytes_read = kUSB_LOWSPEED_MAXPACKET; //Limit myself to low-speed keyboards
329: }
330: modifier = *key_ptr;
331: //alpha = *(key_ptr +2); // byte +1 seems to be unused
332: //adb_code = usb_2_adb_keymap[alpha];
333:
334: //Handle new key information. The first byte is a set of bits describing
335: // which modifier keys are down. The 2nd byte never seems to be used.
336: // The third byte is the first USB key down, and the fourth byte is the
337: // second key down, and so on.
338: //When a key is released, there's no code... just a zero upon USB polling
339: //8/2/99 A.W. fixed Blue Box's multiple modifier keys being pressed
340: // simultaneously. The trick is if a modifier key DOWN event is reported,
341: // and another DOWN is reported, then Blue Box loses track of it. I must
342: // report a UP key event first, or else avoid resending the DOWN event.
343:
344:
345: //SECTION 1. Handle modifier keys here first
346: if (modifier == oldmodifier)
347: {
348: //Do nothing. Same keys are still pressed, or if 0 then none pressed
349: // so don't overload the HID system with useless events.
350: }
351: else //Modifiers may or may not be pressed right now
352: {
353: //kprintf("mod is %x\n", modifier);
354: clock_get_uptime(&now);
355:
356: //left-hand CONTROL modifier key
357: if ((modifier & kUSB_LEFT_CONTROL_BIT) && !(oldmodifier & kUSB_LEFT_CONTROL_BIT))
358: {
359: dispatchKeyboardEvent(0x36, true, now); //ADB left-hand CONTROL
360: _control_key = true; //determine if we reboot CPU. Is instance variable.
361: }
362: else if ((oldmodifier & kUSB_LEFT_CONTROL_BIT) && !(modifier & kUSB_LEFT_CONTROL_BIT))
363: {
364: //Now check for released modifier keys
365: dispatchKeyboardEvent(0x36, false, now);
366: _control_key = false;
367: }
368:
369: //right-hand CONTROL modifier
370: if ((modifier & kUSB_RIGHT_CONTROL_BIT) && !(oldmodifier & kUSB_RIGHT_CONTROL_BIT))
371: {
372: dispatchKeyboardEvent(0x7d, true, now); //right-hand CONTROL
373: _control_key = true; //determine if we reboot CPU. Is instance variable.
374: }
375: else if ((oldmodifier & kUSB_RIGHT_CONTROL_BIT) && !(modifier & kUSB_RIGHT_CONTROL_BIT))
376: {
377: dispatchKeyboardEvent(0x7d, false, now);
378: _control_key = false;
379: }
380:
381: //left-hand SHIFT
382: if ((modifier & kUSB_LEFT_SHIFT_BIT) && !(oldmodifier & kUSB_LEFT_SHIFT_BIT))
383: {
384: // Debugger("LEFT SHIFT");
385:
386: dispatchKeyboardEvent(0x38, true, now);
387: }
388: else if ((oldmodifier & kUSB_LEFT_SHIFT_BIT) && !(modifier & kUSB_LEFT_SHIFT_BIT))
389: {
390: dispatchKeyboardEvent(0x38, false, now);
391: }
392:
393: //right-hand SHIFT
394: if ((modifier & kUSB_RIGHT_SHIFT_BIT) && !(oldmodifier & kUSB_RIGHT_SHIFT_BIT))
395: {
396: dispatchKeyboardEvent(0x7b, true, now);
397: }
398: else if ((oldmodifier & kUSB_RIGHT_SHIFT_BIT) && !(modifier & kUSB_RIGHT_SHIFT_BIT))
399: {
400: dispatchKeyboardEvent(0x7b, false, now);
401: }
402:
403: if ((modifier & kUSB_LEFT_ALT_BIT) && !(oldmodifier & kUSB_LEFT_ALT_BIT))
404: {
405: dispatchKeyboardEvent(0x3a, true, now);
406: }
407: else if ((oldmodifier & kUSB_LEFT_ALT_BIT) && !(modifier & kUSB_LEFT_ALT_BIT))
408: {
409: dispatchKeyboardEvent(0x3a, false, now);
410: }
411:
412: if ((modifier & kUSB_RIGHT_ALT_BIT) && !(oldmodifier & kUSB_RIGHT_ALT_BIT))
413: {
414: dispatchKeyboardEvent(0x7c, true, now);
415: }
416: else if ((oldmodifier & kUSB_RIGHT_ALT_BIT) && !(modifier & kUSB_RIGHT_ALT_BIT))
417: {
418: dispatchKeyboardEvent(0x7c, false, now);
419: }
420:
421: if ((modifier & kUSB_LEFT_FLOWER_BIT) && !(oldmodifier & kUSB_LEFT_FLOWER_BIT))
422: {
423: dispatchKeyboardEvent(0x37, true, now);
424: _flower_key = true; //determine if we go into kernel debugger, or reboot CPU
425: }
426: else if ((oldmodifier & kUSB_LEFT_FLOWER_BIT) && !(modifier & kUSB_LEFT_FLOWER_BIT))
427: {
428: dispatchKeyboardEvent(0x37, false, now);
429: _flower_key = false;
430: }
431:
432: if ((modifier & kUSB_RIGHT_FLOWER_BIT) && !(oldmodifier & kUSB_RIGHT_FLOWER_BIT))
433: {
434: //dispatchKeyboardEvent(0x7e, true, now);
435: //WARNING... NeXT only recognizes left-hand flower key, so
436: // emulate that for now
437: dispatchKeyboardEvent(0x37, true, now);
438: _flower_key = true;
439: }
440: else if ((oldmodifier & kUSB_RIGHT_FLOWER_BIT) && !(modifier & kUSB_RIGHT_FLOWER_BIT))
441: {
442: dispatchKeyboardEvent(0x37, false, now);
443: _flower_key = false;
444: }
445:
446: }
447:
448: //SECTION 2. Handle regular alphanumeric keys now. Look first at previous keystrokes.
449: // Alphanumeric portion of HID report starts at byte +2.
450:
451: for (seq_key = 2; seq_key < prev_bytes_read; seq_key++)
452: {
453: alpha = old_array[seq_key];
454: if (alpha == 0) //No keys pressed
455: {
456: break;
457: }
458: found = false;
459: for (i = 2; i < bytes_read; i++) //Look through current keypresses
460: {
461: if (alpha == *(key_ptr + i))
462: {
463: found = true; //This key has been held down for a while, so do nothing.
464: break; // Autorepeat is taken care of by IOKit.
465: }
466: }
467: if (!found)
468: {
469: clock_get_uptime(&now);
470: if (alpha == 0x39) //This is USB Caps Lock scan code
471: {
472: if (!_capsLockState)
473: {
474: dispatchKeyboardEvent(usb_2_adb_keymap[0x39], false, now);
475: //Only dispatch if we're in the correct state for Caps Lock
476: Set_LED_States(0);
477: }
478: }
479: else //For any other keys except LED-setting keys, dispatch immediately
480: {
481: dispatchKeyboardEvent(usb_2_adb_keymap[alpha], false, now); //KEY UP
482: }
483: }
484: }
485:
486: //Now take care of KEY DOWN.
487: for (seq_key = 2; seq_key < bytes_read; seq_key++)
488: {
489: alpha = *(key_ptr + seq_key);
490: if (alpha == 0) //No keys pressed
491: {
492: break;
493: }
494: else if (alpha == 0x66) //POWER ON key
495: {
496: if ((_control_key) && (_flower_key)) //User wants to reboot
497: {
498: boot( RB_BOOT, 0, 0 ); //call to xnu/bsd/kern/kern_shutdown.c
499: }
500: if (_flower_key) // Apple CMD modifier must be simultaneously held down
501: {
502: PE_enter_debugger("USB Programmer Key");
503: //In xnu/pexpert/ppc/pe_interrupt.c and defined in pexpert.h above
504: }
505: //The reason this kernel debugger call is made here instead of KEY UP
506: // is that the HID system will see the POWER key and bring up a
507: // dialog box to shut down the computer, which is not what we want.
508: }
509:
510: //Don't dispatch the same key again which was held down previously
511: found = false;
512: for (i = 2; i < prev_bytes_read; i++)
513: {
514: if (alpha == old_array[i])
515: {
516: found = true;
517: break;
518: }
519: }
520: if (!found)
521: {
522: clock_get_uptime(&now);
523: //If Debugger() is triggered then I shouldn't show the restart dialog
524: // box, but I think developers doing kernel debugging can live with
525: // this minor incovenience. Otherwise I need to do more checking here.
526:
527: if (alpha == 0x39) //This is USB Caps Lock scan code
528: {
529: if (_capsLockState)
530: {
531: _capsLockState = 0;
532: //Don't do anything else, wait for KEY_UP loop above to handle it
533: }
534: else
535: {
536: _capsLockState = 1;
537: Set_LED_States(kUSB_CAPSLOCKLED_SET); // kUSB_CAPSLOCKLED_SET = 2
538: }
539: }
540:
541: dispatchKeyboardEvent(usb_2_adb_keymap[alpha], true, now);
542: }
543: }
544:
545: //Save the history for next time
546: oldmodifier = modifier;
547: prev_bytes_read = bytes_read;
548: for (i=0; i< bytes_read; i++) //guaranteed not to exceed 8
549: {
550: old_array[i] = *(key_ptr + i);
551: }
552:
553: }
554:
555:
556:
557: void AppleKeyboard::setLEDHandler(void * parameter,
558: IOReturn status,
559: UInt32 bufferSizeRemaining)
560: {
561: if (status)
562: {
563: //Setting the LED causes problems on CMD USB controller on MacOSX,
564: // so if error then prevent further attempts. Log the failure
565: IOLog("USB Keyboard Caps Lock LED failed\n");
566: kprintf("USB Keyboard Caps Lock LED failed\n");
567: _prevent_LED_set = TRUE;
568: }
569: }
570:
571: void AppleKeyboard::readHandler(void * parameter,
572: IOReturn status,
573: UInt32 bufferSizeRemaining)
574: {
575: IOReturn err = kIOReturnSuccess;
576:
577: // Handle the error if any
578: switch (status)
579: {
580: case kIOReturnSuccess:
581: break;
582:
583: case kIOReturnOverrun:
584: // Not sure what to do with this error. It means more data
585: // came back than the size of a descriptor. Hmmm. For now
586: // just ignore it and assume the data that did come back is
587: // useful.
588: IOLog("%s: overrun error. ignoring.\n", getName());
589: break;
590:
591: case kIOReturnNotResponding:
592: // This probably means the device was unplugged. Now
593: // we need to close the driver.
594: IOLog("%s: Device unplugged. Goodbye\n", getName());
595: goto close;
596:
597: default:
598: // We should handle other errors more intelligently, but
599: // for now just return and assume the error is recoverable.
600: IOLog("%s: error %d reading interrupt pipe\n", getName(), status);
601: goto queueAnother;
602: }
603:
604: // Handle the data
605: Simulate_ADB_Event((UInt8 *)_buffer->getBytesNoCopy(),
606: (UInt32) _maxPacketSize - bufferSizeRemaining);
607:
608: queueAnother:
609: // Reset the buffer
610: _buffer->setLength(_maxPacketSize);
611:
612: // Queue up another one before we leave.
613: if ((err = _interruptPipe->read(_buffer, &_completion)))
614: {
615: // This is bad. We probably shouldn't continue on from here.
616: IOLog("%s: immediate error %d queueing read\n", getName(), err);
617: goto close;
618: }
619:
620: return;
621:
622: close:
623: _interface->close(this);
624: return;
625: }
626:
627:
628:
629: // ***************************************************************************
630: // usb_asyncLED
631: //
632: // Called asynchronously to turn on/off the keyboard LED
633: //
634: // **************************************************************************
635: void usb_asyncLED( thread_call_param_t param, thread_call_param_t )
636: {
637: AppleKeyboard * me = (AppleKeyboard *) param;
638: me->Set_LED_States( me->_ledState );
639: }
640:
641:
642: //******************************************************************************
643: // COPIED from ADB keyboard driver 3/25/99
644: // This is usually called on a call-out thread after the caps-lock key is pressed.
645: // ADB operations to PMU are synchronous, and this is must not be done
646: // on the call-out thread since that is the PMU driver workloop thread, and
647: // it will block itself.
648: //
649: // Therefore, we schedule the ADB write to disconnect the call-out thread
650: // and the one that initiates the ADB write.
651: //
652: // *******************************************************************************
653: void AppleKeyboard::setLEDFeedback( UInt8 LED_state)
654: {
655: _ledState = LED_state;
656:
657: thread_call_func(usb_asyncLED, (thread_call_param_t)this, true);
658: }
659:
660:
661: // *****************************************************************************
662: // maxKeyCodes
663: // A.W. copied 3/25/99 from ADB keyboard driver, I don't know what this does
664: // ***************************************************************************
665: UInt32 AppleKeyboard::maxKeyCodes (void )
666: {
667: return 0x80;
668: }
669:
670:
671: // *************************************************************************
672: // deviceType
673: //
674: // **************************************************************************
675: UInt32 AppleKeyboard::deviceType ( void )
676: {
677: return 2;
678: }
679:
680: // ************************************************************************
681: // interfaceID. Fake ADB for now since USB defaultKeymapOfLength is too complex
682: //
683: // **************************************************************************
684: UInt32 AppleKeyboard::interfaceID ( void )
685: {
686: //Return value must match "interface" line in .keyboard file
687: return NX_EVS_DEVICE_INTERFACE_ADB; // 2 This matches contents of AppleExt.keyboard
688: }
689:
690:
691: /***********************************************/
692: //Get handler ID
693: //
694: // I assume that this method is only called if a valid USB keyboard
695: // is found. This method should return a 0 or something if there's
696: // no keyboard, but then the USB keyboard driver should never have
697: // been probed if there's no keyboard, so for now it won't return 0.
698: UInt32 AppleKeyboard::handlerID ( void )
699: {
700: UInt32 ret_id = 0x201; //513 decimal is ANSI USB iMac keyboard
701:
702: //Return value must match "handler_id" line in .keyboard file
703: // For some reason the ADB and PS/2 keyboard drivers are missing this method
704: // Also, Beaker Keyboard Prefs doesn't run properly
705: //Fix hardware bug in iMac USB keyboard mapping for ISO keyboards
706: //kprintf("\nUSB product = %x, vendor = %x\n", _deviceDescriptor->product, _deviceDescriptor->vendor);
707: if ( _deviceDescriptor) //just to be safe
708: {
709: if (_deviceDescriptor->vendor == 0xac05) //Apple USB keyboards
710: {
711: ret_id = _deviceDescriptor->product; //0x201=ANSI, 0x202=ISO, or 0x203=JIS
712: if (ret_id == 0x202)
713: {
714: usb_2_adb_keymap[0x35] = 0x0a; //Cosmo key18 swaps with key74, 0a is ADB keycode
715: usb_2_adb_keymap[0x64] = 0x32;
716: IOLog("USB ISO keys swapped\n");
717: }
718: }
719:
720: if (_deviceDescriptor->vendor == 0x045e) //Microsoft ID
721: {
722: if (_deviceDescriptor->product == 0x000b) //Natural USB+PS/2 keyboard
723: ret_id = 18; //18 is Apple Extended ADB keyboard
724: }
725: }
726:
727: return ret_id;
728: }
729:
730:
731: // *****************************************************************************
732: // defaultKeymapOfLength
733: // A.W. copied from ADB keyboard, I don't have time to make custom USB version
734: // *****************************************************************************
735: const unsigned char * AppleKeyboard::defaultKeymapOfLength (UInt32 * length )
736: {
737: static const unsigned char appleUSAKeyMap[] = {
738: 0x00,0x00,0x07,
739: 0x00,0x01,0x39,
740: 0x01,0x02,0x38,0x7b,
741: 0x02,0x02,0x36,0x7d,0x03,0x02,0x3a,0x7c,0x04,
742: 0x01,0x37,0x05,0x15,0x52,0x41,0x4c,0x53,0x54,0x55,0x45,0x58,0x57,0x56,0x5b,0x5c,
743: 0x43,0x4b,0x51,0x3b,0x3d,0x3e,0x3c,0x4e,0x59,0x06,0x01,0x72,0x7b,0x0d,0x00,0x61,
744: 0x00,0x41,0x00,0x01,0x00,0x01,0x00,0xca,0x00,0xc7,0x00,0x01,0x00,0x01,0x0d,0x00,
745: 0x73,0x00,0x53,0x00,0x13,0x00,0x13,0x00,0xfb,0x00,0xa7,0x00,0x13,0x00,0x13,0x0d,
746: 0x00,0x64,0x00,0x44,0x00,0x04,0x00,0x04,0x01,0x44,0x01,0xb6,0x00,0x04,0x00,0x04,
747: 0x0d,0x00,0x66,0x00,0x46,0x00,0x06,0x00,0x06,0x00,0xa6,0x01,0xac,0x00,0x06,0x00,
748: 0x06,0x0d,0x00,0x68,0x00,0x48,0x00,0x08,0x00,0x08,0x00,0xe3,0x00,0xeb,0x00,0x00,
749: 0x18,0x00,0x0d,0x00,0x67,0x00,0x47,0x00,0x07,0x00,0x07,0x00,0xf1,0x00,0xe1,0x00,
750: 0x07,0x00,0x07,0x0d,0x00,0x7a,0x00,0x5a,0x00,0x1a,0x00,0x1a,0x00,0xcf,0x01,0x57,
751: 0x00,0x1a,0x00,0x1a,0x0d,0x00,0x78,0x00,0x58,0x00,0x18,0x00,0x18,0x01,0xb4,0x01,
752: 0xce,0x00,0x18,0x00,0x18,0x0d,0x00,0x63,0x00,0x43,0x00,0x03,0x00,0x03,0x01,0xe3,
753: 0x01,0xd3,0x00,0x03,0x00,0x03,0x0d,0x00,0x76,0x00,0x56,0x00,0x16,0x00,0x16,0x01,
754: 0xd6,0x01,0xe0,0x00,0x16,0x00,0x16,0x02,0x00,0x3c,0x00,0x3e,0x0d,0x00,0x62,0x00,
755: 0x42,0x00,0x02,0x00,0x02,0x01,0xe5,0x01,0xf2,0x00,0x02,0x00,0x02,0x0d,0x00,0x71,
756: 0x00,0x51,0x00,0x11,0x00,0x11,0x00,0xfa,0x00,0xea,0x00,0x11,0x00,0x11,0x0d,0x00,
757: 0x77,0x00,0x57,0x00,0x17,0x00,0x17,0x01,0xc8,0x01,0xc7,0x00,0x17,0x00,0x17,0x0d,
758: 0x00,0x65,0x00,0x45,0x00,0x05,0x00,0x05,0x00,0xc2,0x00,0xc5,0x00,0x05,0x00,0x05,
759: 0x0d,0x00,0x72,0x00,0x52,0x00,0x12,0x00,0x12,0x01,0xe2,0x01,0xd2,0x00,0x12,0x00,
760: 0x12,0x0d,0x00,0x79,0x00,0x59,0x00,0x19,0x00,0x19,0x00,0xa5,0x01,0xdb,0x00,0x19,
761: 0x00,0x19,0x0d,0x00,0x74,0x00,0x54,0x00,0x14,0x00,0x14,0x01,0xe4,0x01,0xd4,0x00,
762: 0x14,0x00,0x14,0x0a,0x00,0x31,0x00,0x21,0x01,0xad,0x00,0xa1,0x0e,0x00,0x32,0x00,
763: 0x40,0x00,0x32,0x00,0x00,0x00,0xb2,0x00,0xb3,0x00,0x00,0x00,0x00,0x0a,0x00,0x33,
764: 0x00,0x23,0x00,0xa3,0x01,0xba,0x0a,0x00,0x34,0x00,0x24,0x00,0xa2,0x00,0xa8,0x0e,
765: 0x00,0x36,0x00,0x5e,0x00,0x36,0x00,0x1e,0x00,0xb6,0x00,0xc3,0x00,0x1e,0x00,0x1e,
766: 0x0a,0x00,0x35,0x00,0x25,0x01,0xa5,0x00,0xbd,0x0a,0x00,0x3d,0x00,0x2b,0x01,0xb9,
767: 0x01,0xb1,0x0a,0x00,0x39,0x00,0x28,0x00,0xac,0x00,0xab,0x0a,0x00,0x37,0x00,0x26,
768: 0x01,0xb0,0x01,0xab,0x0e,0x00,0x2d,0x00,0x5f,0x00,0x1f,0x00,0x1f,0x00,0xb1,0x00,
769: 0xd0,0x00,0x1f,0x00,0x1f,0x0a,0x00,0x38,0x00,0x2a,0x00,0xb7,0x00,0xb4,0x0a,0x00,
770: 0x30,0x00,0x29,0x00,0xad,0x00,0xbb,0x0e,0x00,0x5d,0x00,0x7d,0x00,0x1d,0x00,0x1d,
771: 0x00,0x27,0x00,0xba,0x00,0x1d,0x00,0x1d,0x0d,0x00,0x6f,0x00,0x4f,0x00,0x0f,0x00,
772: 0x0f,0x00,0xf9,0x00,0xe9,0x00,0x0f,0x00,0x0f,0x0d,0x00,0x75,0x00,0x55,0x00,0x15,
773: 0x00,0x15,0x00,0xc8,0x00,0xcd,0x00,0x15,0x00,0x15,0x0e,0x00,0x5b,0x00,0x7b,0x00,
774: 0x1b,0x00,0x1b,0x00,0x60,0x00,0xaa,0x00,0x1b,0x00,0x1b,0x0d,0x00,0x69,0x00,0x49,
775: 0x00,0x09,0x00,0x09,0x00,0xc1,0x00,0xf5,0x00,0x09,0x00,0x09,0x0d,0x00,0x70,0x00,
776: 0x50,0x00,0x10,0x00,0x10,0x01,0x70,0x01,0x50,0x00,0x10,0x00,0x10,0x10,0x00,0x0d,
777: 0x00,0x03,0x0d,0x00,0x6c,0x00,0x4c,0x00,0x0c,0x00,0x0c,0x00,0xf8,0x00,0xe8,0x00,
778: 0x0c,0x00,0x0c,0x0d,0x00,0x6a,0x00,0x4a,0x00,0x0a,0x00,0x0a,0x00,0xc6,0x00,0xae,
779: 0x00,0x0a,0x00,0x0a,0x0a,0x00,0x27,0x00,0x22,0x00,0xa9,0x01,0xae,0x0d,0x00,0x6b,
780: 0x00,0x4b,0x00,0x0b,0x00,0x0b,0x00,0xce,0x00,0xaf,0x00,0x0b,0x00,0x0b,0x0a,0x00,
781: 0x3b,0x00,0x3a,0x01,0xb2,0x01,0xa2,0x0e,0x00,0x5c,0x00,0x7c,0x00,0x1c,0x00,0x1c,
782: 0x00,0xe3,0x00,0xeb,0x00,0x1c,0x00,0x1c,0x0a,0x00,0x2c,0x00,0x3c,0x00,0xcb,0x01,
783: 0xa3,0x0a,0x00,0x2f,0x00,0x3f,0x01,0xb8,0x00,0xbf,0x0d,0x00,0x6e,0x00,0x4e,0x00,
784: 0x0e,0x00,0x0e,0x00,0xc4,0x01,0xaf,0x00,0x0e,0x00,0x0e,0x0d,0x00,0x6d,0x00,0x4d,
785: 0x00,0x0d,0x00,0x0d,0x01,0x6d,0x01,0xd8,0x00,0x0d,0x00,0x0d,0x0a,0x00,0x2e,0x00,
786: 0x3e,0x00,0xbc,0x01,0xb3,0x02,0x00,0x09,0x00,0x19,0x0c,0x00,0x20,0x00,0x00,0x00,
787: 0x80,0x00,0x00,0x0a,0x00,0x60,0x00,0x7e,0x00,0x60,0x01,0xbb,0x02,0x00,0x7f,0x00,
788: 0x08,0xff,0x02,0x00,0x1b,0x00,0x7e,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xac,0x00,
789: 0x01,0xae,0x00,0x01,0xaf,0x00,0x01,0xad,0xff,0xff,0x00,0x00,0x2e,0xff,0x00,0x00,
790: 0x2a,0xff,0x00,0x00,0x2b,0xff,0x00,0x00,0x1b,0xff,0xff,0xff,0x0e,0x00,0x2f,0x00,
791: 0x5c,0x00,0x2f,0x00,0x1c,0x00,0x2f,0x00,0x5c,0x00,0x00,0x0a,0x00,0x00,0x00,0x0d, //XX03
792: 0xff,0x00,0x00,0x2d,0xff,0xff,0x0e,0x00,0x3d,0x00,0x7c,0x00,0x3d,0x00,0x1c,0x00,
793: 0x3d,0x00,0x7c,0x00,0x00,0x18,0x46,0x00,0x00,0x30,0x00,0x00,0x31,0x00,0x00,0x32,
794: 0x00,0x00,0x33,0x00,0x00,0x34,0x00,0x00,0x35,0x00,0x00,0x36,0x00,0x00,0x37,0xff,
795: 0x00,0x00,0x38,0x00,0x00,0x39,0xff,0xff,0xff,0x00,0xfe,0x24,0x00,0xfe,0x25,0x00,
796: 0xfe,0x26,0x00,0xfe,0x22,0x00,0xfe,0x27,0x00,0xfe,0x28,0xff,0x00,0xfe,0x2a,0xff,
797: 0x00,0xfe,0x32,0xff,0x00,0xfe,0x33,0xff,0x00,0xfe,0x29,0xff,0x00,0xfe,0x2b,0xff,
798: 0x00,0xfe,0x34,0xff,0x00,0xfe,0x2e,0x00,0xfe,0x30,0x00,0xfe,0x2d,0x00,0xfe,0x23,
799: 0x00,0xfe,0x2f,0x00,0xfe,0x21,0x00,0xfe,0x31,0x00,0xfe,0x20,0x0f,0x02,0xff,0x04,
800: 0x00,0x31,0x02,0xff,0x04,0x00,0x32,0x02,0xff,0x04,0x00,0x33,0x02,0xff,0x04,0x00,
801: 0x34,0x02,0xff,0x04,0x00,0x35,0x02,0xff,0x04,0x00,0x36,0x02,0xff,0x04,0x00,0x37,
802: 0x02,0xff,0x04,0x00,0x38,0x02,0xff,0x04,0x00,0x39,0x02,0xff,0x04,0x00,0x30,0x02,
803: 0xff,0x04,0x00,0x2d,0x02,0xff,0x04,0x00,0x3d,0x02,0xff,0x04,0x00,0x70,0x02,0xff,
804: 0x04,0x00,0x5d,0x02,0xff,0x04,0x00,0x5b,0x04,0x05,0x72,0x06,0x7f,0x07,
805: 0x3e,0x08,0x3d
806: };
807:
808: *length = sizeof(appleUSAKeyMap);
809: return appleUSAKeyMap;
810: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.