|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this 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 OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: File: KeyIn.c
27:
28: Contains: ADB keyboard simulation (non-shim based).
29:
30: Version: xxx put version here xxx
31:
32: Copyright: � 1998 by Apple Computer, Inc., all rights reserved.
33:
34: File Ownership:
35:
36: DRI: David Ferguson
37:
38: Other Contact: xxx put other contact here xxx
39:
40: Technology: xxx put technology here xxx
41:
42: Writers:
43:
44: (TEB) Ted Burge
45: (BWS) Brent Schorsch
46: (BG) Bill Galcher
47: (DKF) David Ferguson
48: (CJK) Craig Keithley
49:
50: Change History (most recent first):
51:
52: <USB24> 9/10/98 TEB [2267641] Changed the right shift, right option and right
53: control keys to use 0x38, 0x3A and 0x3B and not the type 3
54: keyboard virtual key codes: 0x3C, 0x3D, and 0x3E listed here
55: respectively.
56: <USB23> 6/29/98 CJK correct numeric keypad = key so that it reports as keypad =, not
57: as keypad enter
58: <USB22> 6/22/98 CJK change left & right modifier keys to be unique. This change
59: only affects the DDK, not C1.
60: <USB21> 6/18/98 BWS fix interrupt refcon support
61: <USB20> 6/10/98 CJK make certain power key is sent twice (before keyup).
62: <USB19> 6/10/98 CJK [2238229] change applicatinon key to $6E
63: <USB18> 5/28/98 CJK change to MPW type file
64: <USB17> 5/22/98 CJK Fix for CodeWarrior
65: <USB16> 5/19/98 BG Add include of LowMem.h to bring in needed prototype.
66: <USB15> 4/26/98 CJK update to match reworked keyboard interface driver
67: <USB14> 4/9/98 CJK replace include of USBHIDModules.h with include of USB.h
68: <13> 4/8/98 CJK update selector name
69: <12> 4/8/98 CJK rework PostUSBKeyToMac to work the same way as the standard interrupt
70: handler
71: <11> 3/26/98 CJK remove debugstr
72: <10> 3/19/98 CJK Remove numlock & capslock toggle/led handling
73: <9> 3/17/98 CJK change } to just }. MetroWerks has a problem with }.
74: <8> 3/12/98 CJK Re-work modifier key handling so that it only propagates key
75: state changes when the key is pressed, ignores modifier key up
76: key codes, and "simulates" modifier key up routines to the Mac
77: OS (when the keystate is toggled back to 'not pressed').
78: <7> 3/2/98 CJK remove include of KBDHIDEmulation.h
79: <6> 2/27/98 CJK disable call to HID Module control routine.
80: <5> 2/27/98 CJK Add include of USBHIDModules.h. Change keycode constants to be
81: kUSB...
82: <4> 2/26/98 CJK add capslock, scroll lock, and num lock LED support.
83: <USB3> 2/19/98 DKF Fix keymapping for \, swap alt & command, update lowmem
84: accessors
85: <2> 2/17/98 CJK Add change history.
86: <1> 2/17/98 CJK First time check in.
87: */
88:
89: /*
90: USB Keyboard Translation to Macintosh
91: */
92: #include "../driverservices.h"
93: //#include <Types.h>
94: #include "Events.h"
95: //#include <Resources.h>
96: //#include <LowMem.h>
97: #include "../USB.h"
98: #include "KeyboardModule.h"
99:
100:
101: #define DOWN 0
102: #define UP 1
103:
104: #define TRUE 1
105: #define FALSE 0
106:
107: #define FakeADBAddr 16
108: #define FakeKBDType 2 // this should be the same as the Apple extended keyboard for now
109:
110: static UInt32 myKeyMAP[4];
111: static UInt32 keyTransState;
112: static Handle handleKCHR;
113: static UInt8* KCHRptr;
114:
115: typedef KeyMap * KeyMapPtr;
116:
117: /* prototypes */
118: Boolean KeyInArray(UInt8 key, UInt8 *array, UInt16 len);
119: Boolean SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value);
120: void PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state);
121:
122: /* when we move to master interfaces we can get this stuff from LowMemPriv.h */
123: /* be sure to turn on DIRECT_LOWMEM_ACCESSORS */
124: #define LMSetKbdVars(value) ((*(short *)0x0216) = (value))
125: #define LMSetKeyLast(value) ((*(short *)0x0184) = (value))
126: #define LMSetKeyTime(value) ((*(long *)0x0186) = (value))
127: #define LMSetKeyRepTime(value) ((*(long *)0x018A) = (value))
128: #define LMSetKeyMap(KeyMapValue) BlockMove((Ptr)(KeyMapValue), (Ptr)0x0174, sizeof(KeyMap))
129:
130:
131: // index represents USB keyboard usage value, content is Mac virtual keycode
132: static UInt8 USBKMAP[256] = {
133: 0xFF, /* 00 no event */
134: 0xFF, /* 01 ErrorRollOver */
135: 0xFF, /* 02 POSTFail */
136: 0xFF, /* 03 ErrorUndefined */
137: 0x00, /* 04 A */
138: 0x0B, /* 05 B */
139: 0x08, /* 06 C */
140: 0x02, /* 07 D */
141: 0x0E, /* 08 E */
142: 0x03, /* 09 F */
143: 0x05, /* 0A G */
144: 0x04, /* 0B H */
145: 0x22, /* 0C I */
146: 0x26, /* 0D J */
147: 0x28, /* 0E K */
148: 0x25, /* 0F L */
149:
150: 0x2E, /* 10 M */
151: 0x2D, /* 11 N */
152: 0x1F, /* 12 O */
153: 0x23, /* 13 P */
154: 0x0C, /* 14 Q */
155: 0x0F, /* 15 R */
156: 0x01, /* 16 S */
157: 0x11, /* 17 T */
158: 0x20, /* 18 U */
159: 0x09, /* 19 V */
160: 0x0D, /* 1A W */
161: 0x07, /* 1B X */
162: 0x10, /* 1C Y */
163: 0x06, /* 1D Z */
164: 0x12, /* 1E 1/! */
165: 0x13, /* 1F 2/@ */
166:
167: 0x14, /* 20 3 # */
168: 0x15, /* 21 4 $ */
169: 0x17, /* 22 5 % */
170: 0x16, /* 23 6 ^ */
171: 0x1A, /* 24 7 & */
172: 0x1C, /* 25 8 * */
173: 0x19, /* 26 9 ( */
174: 0x1D, /* 27 0 ) */
175: 0x24, /* 28 Return (Enter) */
176: 0x35, /* 29 ESC */
177: 0x33, /* 2A Delete (Backspace) */
178: 0x30, /* 2B Tab */
179: 0x31, /* 2C Spacebar */
180: 0x1B, /* 2D - _ */
181: 0x18, /* 2E = + */
182: 0x21, /* 2F [ { */
183:
184: 0x1E, /* 30 ] } */
185: 0x2A, /* 31 \ | */
186: 0xFF, /* 32 Non-US # and ~ (what?!!!) */
187: 0x29, /* 33 ; : */
188: 0x27, /* 34 ' " */
189: 0x32, /* 35 ` ~ */
190: 0x2B, /* 36 , < */
191: 0x2F, /* 37 . > */
192: 0x2C, /* 38 / ? */
193: 0x39, /* 39 Caps Lock */
194: 0x7A, /* 3A F1 */
195: 0x78, /* 3B F2 */
196: 0x63, /* 3C F3 */
197: 0x76, /* 3D F4 */
198: 0x60, /* 3E F5 */
199: 0x61, /* 3F F6 */
200:
201: 0x62, /* 40 F7 */
202: 0x64, /* 41 F8 */
203: 0x65, /* 42 F9 */
204: 0x6D, /* 43 F10 */
205: 0x67, /* 44 F11 */
206: 0x6F, /* 45 F12 */
207: 0x69, /* 46 F13/PrintScreen */
208: 0x6B, /* 47 F14/ScrollLock */
209: 0x71, /* 48 F15/Pause */
210: 0x72, /* 49 Insert */
211: 0x73, /* 4A Home */
212: 0x74, /* 4B PageUp */
213: 0x75, /* 4C Delete Forward */
214: 0x77, /* 4D End */
215: 0x79, /* 4E PageDown */
216: 0x7C, /* 4F RightArrow */
217:
218: 0x7B, /* 50 LeftArrow */
219: 0x7D, /* 51 DownArrow */
220: 0x7E, /* 52 UpArrow */
221: 0x47, /* 53 NumLock/Clear */
222: 0x4B, /* 54 Keypad / */
223: 0x43, /* 55 Keypad * */
224: 0x4E, /* 56 Keypad - */
225: 0x45, /* 57 Keypad + */
226: 0x4C, /* 58 Keypad Enter */
227: 0x53, /* 59 Keypad 1 */
228: 0x54, /* 5A Keypad 2 */
229: 0x55, /* 5B Keypad 3 */
230: 0x56, /* 5C Keypad 4 */
231: 0x57, /* 5D Keypad 5 */
232: 0x58, /* 5E Keypad 6 */
233: 0x59, /* 5F Keypad 7 */
234:
235: 0x5B, /* 60 Keypad 8 */
236: 0x5C, /* 61 Keypad 9 */
237: 0x52, /* 62 Keypad 0 */
238: 0x41, /* 63 Keypad . */
239: 0xFF, /* 64 Non-US \ and | (what ??!!) */
240: 0x6E, /* 65 ApplicationKey (not on a mac!)*/
241: 0x7F, /* 66 PowerKey */
242: 0x51, /* 67 Keypad = */
243: 0x69, /* 68 F13 */
244: 0x6B, /* 69 F14 */
245: 0x71, /* 6A F15 */
246: 0xFF, /* 6B F16 */
247: 0xFF, /* 6C F17 */
248: 0xFF, /* 6D F18 */
249: 0xFF, /* 6E F19 */
250: 0xFF, /* 6F F20 */
251:
252: 0x5B, /* 70 F21 */
253: 0x5C, /* 71 F22 */
254: 0x52, /* 72 F23 */
255: 0x41, /* 73 F24 */
256: 0xFF, /* 74 Execute */
257: 0xFF, /* 75 Help */
258: 0x7F, /* 76 Menu */
259: 0x4C, /* 77 Select */
260: 0x69, /* 78 Stop */
261: 0x6B, /* 79 Again */
262: 0x71, /* 7A Undo */
263: 0xFF, /* 7B Cut */
264: 0xFF, /* 7C Copy */
265: 0xFF, /* 7D Paste */
266: 0xFF, /* 7E Find */
267: 0xFF, /* 7F Mute */
268:
269: 0xFF, /* 80 no event */
270: 0xFF, /* 81 no event */
271: 0xFF, /* 82 no event */
272: 0xFF, /* 83 no event */
273: 0xFF, /* 84 no event */
274: 0xFF, /* 85 no event */
275: 0xFF, /* 86 no event */
276: 0xFF, /* 87 no event */
277: 0xFF, /* 88 no event */
278: 0xFF, /* 89 no event */
279: 0xFF, /* 8A no event */
280: 0xFF, /* 8B no event */
281: 0xFF, /* 8C no event */
282: 0xFF, /* 8D no event */
283: 0xFF, /* 8E no event */
284: 0xFF, /* 8F no event */
285:
286: 0xFF, /* 90 no event */
287: 0xFF, /* 91 no event */
288: 0xFF, /* 92 no event */
289: 0xFF, /* 93 no event */
290: 0xFF, /* 94 no event */
291: 0xFF, /* 95 no event */
292: 0xFF, /* 96 no event */
293: 0xFF, /* 97 no event */
294: 0xFF, /* 98 no event */
295: 0xFF, /* 99 no event */
296: 0xFF, /* 9A no event */
297: 0xFF, /* 9B no event */
298: 0xFF, /* 9C no event */
299: 0xFF, /* 9D no event */
300: 0xFF, /* 9E no event */
301: 0xFF, /* 9F no event */
302:
303: 0xFF, /* A0 no event */
304: 0xFF, /* A1 no event */
305: 0xFF, /* A2 no event */
306: 0xFF, /* A3 no event */
307: 0xFF, /* A4 no event */
308: 0xFF, /* A5 no event */
309: 0xFF, /* A6 no event */
310: 0xFF, /* A7 no event */
311: 0xFF, /* A8 no event */
312: 0xFF, /* A9 no event */
313: 0xFF, /* AA no event */
314: 0xFF, /* AB no event */
315: 0xFF, /* AC no event */
316: 0xFF, /* AD no event */
317: 0xFF, /* AE no event */
318: 0xFF, /* AF no event */
319:
320: 0xFF, /* B0 no event */
321: 0xFF, /* B1 no event */
322: 0xFF, /* B2 no event */
323: 0xFF, /* B3 no event */
324: 0xFF, /* B4 no event */
325: 0xFF, /* B5 no event */
326: 0xFF, /* B6 no event */
327: 0xFF, /* B7 no event */
328: 0xFF, /* B8 no event */
329: 0xFF, /* B9 no event */
330: 0xFF, /* BA no event */
331: 0xFF, /* BB no event */
332: 0xFF, /* BC no event */
333: 0xFF, /* BD no event */
334: 0xFF, /* BE no event */
335: 0xFF, /* BF no event */
336:
337: 0xFF, /* C0 no event */
338: 0xFF, /* C1 no event */
339: 0xFF, /* C2 no event */
340: 0xFF, /* C3 no event */
341: 0xFF, /* C4 no event */
342: 0xFF, /* C5 no event */
343: 0xFF, /* C6 no event */
344: 0xFF, /* C7 no event */
345: 0xFF, /* C8 no event */
346: 0xFF, /* C9 no event */
347: 0xFF, /* CA no event */
348: 0xFF, /* CB no event */
349: 0xFF, /* CC no event */
350: 0xFF, /* CD no event */
351: 0xFF, /* CE no event */
352: 0xFF, /* CF no event */
353:
354: 0xFF, /* D0 no event */
355: 0xFF, /* D1 no event */
356: 0xFF, /* D2 no event */
357: 0xFF, /* D3 no event */
358: 0xFF, /* D4 no event */
359: 0xFF, /* D5 no event */
360: 0xFF, /* D6 no event */
361: 0xFF, /* D7 no event */
362: 0xFF, /* D8 no event */
363: 0xFF, /* D9 no event */
364: 0xFF, /* DA no event */
365: 0xFF, /* DB no event */
366: 0xFF, /* DC no event */
367: 0xFF, /* DD no event */
368: 0xFF, /* DE no event */
369: 0xFF, /* DF no event */
370:
371: 0x3B, /* E0 left control key */
372: 0x38, /* E1 left shift key key */
373: 0x3A, /* E2 left alt/option key */
374: 0x37, /* E3 left GUI (windows/cmd) key */
375:
376: 0x3B, /* E4 right control key */
377: 0x38, /* E5 right shift key key */
378: 0x3A, /* E6 right alt/option key */
379: 0x37, /* E7 right GUI (windows/cmd) key */
380: 0xFF, /* E8 no event */
381: 0xFF, /* E9 no event */
382: 0xFF, /* EA no event */
383: 0xFF, /* EB no event */
384: 0xFF, /* EC no event */
385: 0xFF, /* ED no event */
386: 0xFF, /* EE no event */
387: 0xFF, /* EF no event */
388:
389: 0xFF, /* F0 no event */
390: 0xFF, /* F1 no event */
391: 0xFF, /* F2 no event */
392: 0xFF, /* F3 no event */
393: 0xFF, /* F4 no event */
394: 0xFF, /* F5 no event */
395: 0xFF, /* F6 no event */
396: 0xFF, /* F7 no event */
397: 0xFF, /* F8 no event */
398: 0xFF, /* F9 no event */
399: 0xFF, /* FA no event */
400: 0xFF, /* FB no event */
401: 0xFF, /* FC no event */
402: 0xFF, /* FD no event */
403: 0xFF, /* FE no event */
404: 0xFF, /* FF no event */
405: };
406:
407: void
408: InitUSBKeyboard()
409: {
410: handleKCHR = GetResource('KCHR',0); // US keyboard mapping (handled differently by ADB Mgr)
411: HLock(handleKCHR);
412: KCHRptr = (UInt8 *)*handleKCHR;
413: }
414:
415:
416:
417: void PostUSBKeyToMac(UInt16 rawUSBkey)
418: {
419: static UInt8 oldLEDState = 0x00;
420: static UInt8 newLEDState = 0x00;
421:
422: static UInt8 capsLockState = 0x00;
423: static UInt8 numLockState = 0x00;
424: static UInt8 scrollLockState = 0x00;
425:
426: register UInt8 virtualKeycode, keystate;
427:
428:
429: if (KCHRptr == 0)
430: {
431: InitUSBKeyboard();
432: }
433:
434: keystate = (rawUSBkey & 0x8000) ? UP : DOWN;
435: rawUSBkey &= 0x0FF;
436:
437: if (keystate == DOWN)
438: {
439: newLEDState = oldLEDState;
440:
441: switch (rawUSBkey)
442: {
443: // Note: This switch statement is being left it to make it easy to add "toggling" keys in the future.
444: // it used to support toggled numlock & scroll lock... It doesn't anymore.
445: case kUSBCapsLockKey:
446: newLEDState ^= (1 << kCapsLockLED);
447: keystate = (newLEDState & (1 << kCapsLockLED)) ? DOWN : UP;
448: break;
449: }
450:
451: if (newLEDState != oldLEDState)
452: {
453: oldLEDState = newLEDState;
454: kbd_USBHIDControlDevice(kHIDSetLEDStateByBits, &newLEDState);
455: }
456: }
457: else
458: {
459: switch (rawUSBkey)
460: {
461: // Note: This switch statement is being left it to make it easy to add "toggling" keys in the future.
462: case kUSBCapsLockKey:
463: return;
464: break;
465: }
466: }
467:
468: // look up rawUSBkey in KMAP resource to get virtual keycode
469: if (rawUSBkey < sizeof(USBKMAP))
470: {
471: virtualKeycode = USBKMAP[rawUSBkey];
472: }
473: else
474: {
475: // DebugStr("\pPostUSBKeyToMac: Need bigger KMAP table");
476: virtualKeycode = 0xFF;
477: }
478:
479: PostADBKeyToMac(virtualKeycode, keystate);
480: if (virtualKeycode == 0x7F)
481: PostADBKeyToMac(virtualKeycode, keystate);
482: }
483:
484: void
485: PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state)
486: {
487: UInt32 keyEventMsg;
488:
489: if (virtualKeycode > 127) return; // not handled by MacOS!
490:
491: // stop repeating
492: LMSetKeyLast(0);
493: LMSetKbdVars(0);
494:
495: // update our keymap
496: SetBit((UInt8 *)myKeyMAP, virtualKeycode, state == DOWN ? 1 : 0);
497: LMSetKeyMap(&myKeyMAP);
498:
499: // set this keyboard as the last keyboard
500: LMSetKbdLast(FakeADBAddr);
501: LMSetKbdType(FakeKBDType);
502:
503: // call KeyTrans to get character code
504: virtualKeycode |= ((myKeyMAP[1]<<9) & 0x00FE00) | ((myKeyMAP[1]>>7) & 0x0100) | ((state==UP) ? 0x080 : 0);
505: keyEventMsg = KeyTranslate(KCHRptr, virtualKeycode , &keyTransState);
506: virtualKeycode &= 0x7F;
507:
508: if (keyEventMsg & 0xFFFF0000) {
509: // post event
510: UInt32 event =(keyEventMsg & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00) | ((keyEventMsg>>16) & 0x0FF);
511: if (state == DOWN){
512: UInt32 ticks = TickCount();
513: LMSetKeyTime(ticks);
514: LMSetKeyRepTime(ticks);
515: LMSetKeyLast(event & 0x0FFFF);
516: LMSetKbdVars((event>>16) & 0x0FFFF);
517: }
518: PostEvent((state == DOWN ? keyDown : keyUp), event);
519: }
520: if (keyEventMsg & 0x0000FFFF) {
521: // post event
522: UInt32 event =((keyEventMsg<<16) & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00) | (keyEventMsg & 0x0FF);
523: if (state == DOWN){
524: UInt32 ticks = TickCount();
525: LMSetKeyTime(ticks);
526: LMSetKeyRepTime(ticks);
527: LMSetKeyLast(event & 0x0FFFF);
528: LMSetKbdVars((event>>16) & 0x0FFFF);
529: }
530: PostEvent((state == DOWN ? keyDown : keyUp), event);
531: }
532: }
533:
534: // Sets the bitmapArray[index] to value
535: // returns old value;
536: Boolean
537: SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value)
538: {
539: UInt32 mask = 0x1 << (index % 8 );
540: Boolean oldVal;
541:
542: oldVal = (bitmapArray[index/8] & mask) ? TRUE : FALSE;
543:
544: if (value){
545: bitmapArray[index/8] |= mask;
546: }else{
547: bitmapArray[index/8] &= ~mask;
548: }
549:
550: return (oldVal);
551: }
552:
553: void USBDemoKeyIn(UInt32 refcon, void * theData)
554: {
555: #pragma unused (refcon)
556:
557: USBHIDDataPtr pTheKeyboardData;
558: register UInt8 i;
559:
560: pTheKeyboardData = (USBHIDDataPtr)theData;
561: for (i=0; i<pTheKeyboardData->kbd.keycount; i++)
562: {
563: // no shim installed, let's just post some Macintosh keyevents
564: PostUSBKeyToMac(pTheKeyboardData->kbd.usbkeycode[i]);
565: }
566:
567: }
568:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.