|
|
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: /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
23: *
24: * KeyMap.m - Generic keymap string parser and keycode translator.
25: *
26: * HISTORY
27: * 19 June 1992 Mike Paquette at NeXT
28: * Created.
29: * 5 Aug 1993 Erik Kay at NeXT
30: * minor API cleanup
31: * 11 Nov 1993 Erik Kay at NeXT
32: * fix to allow prevent long sequences from overflowing the event queue
33: * 12 Nov 1998 Dan Markarian at Apple
34: * major cleanup of public API's; converted to C++
35: */
36:
37: #include <IOKit/assert.h>
38: #include <IOKit/IOLib.h>
39: #include <IOKit/hidsystem/IOLLEvent.h>
40: #include <IOKit/hidsystem/IOHIKeyboard.h>
41: #include <IOKit/hidsystem/IOHIKeyboardMapper.h>
42:
43: #define super OSObject
44: OSDefineMetaClassAndStructors(IOHIKeyboardMapper, OSObject);
45:
46: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47:
48: IOHIKeyboardMapper * IOHIKeyboardMapper::keyboardMapper(
49: IOHIKeyboard * delegate,
50: const UInt8 * mapping,
51: UInt32 mappingLength,
52: bool mappingShouldBeFreed )
53: {
54: IOHIKeyboardMapper * me = new IOHIKeyboardMapper;
55:
56: if (me && !me->init(delegate, mapping, mappingLength, mappingShouldBeFreed))
57: {
58: me->free();
59: return 0;
60: }
61:
62: return me;
63: }
64:
65: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
66:
67: /*
68: * Common KeyMap initialization
69: */
70: bool IOHIKeyboardMapper::init( IOHIKeyboard * delegate,
71: const UInt8 * mapping,
72: UInt32 mappingLength,
73: bool mappingShouldBeFreed )
74: {
75: if (!super::init()) return false;
76:
77: if (!parseKeyMapping(mapping, mappingLength, &_parsedMapping)) return false;
78:
79: _delegate = delegate;
80: _mappingShouldBeFreed = mappingShouldBeFreed;
81: _parsedMapping.mapping = mapping;
82: _parsedMapping.mappingLen = mappingLength;
83:
84: return true;
85: }
86:
87: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
88:
89: void IOHIKeyboardMapper::free()
90: {
91: if (_mappingShouldBeFreed && _parsedMapping.mapping)
92: IOFree((void *)_parsedMapping.mapping, _parsedMapping.mappingLen);
93:
94: super::free();
95: }
96:
97: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
98:
99: const UInt8 * IOHIKeyboardMapper::mapping()
100: {
101: return (const UInt8 *)_parsedMapping.mapping;
102: }
103:
104: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
105:
106: UInt32 IOHIKeyboardMapper::mappingLength()
107: {
108: return _parsedMapping.mappingLen;
109: }
110:
111: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
112:
113: bool IOHIKeyboardMapper::serialize(OSSerialize *s) const
114: {
115: OSData * data;
116: bool ok;
117:
118: if (s->previouslySerialized(this)) return true;
119:
120: data = OSData::withBytesNoCopy( (void *) _parsedMapping.mapping, _parsedMapping.mappingLen );
121: if (data) {
122: ok = data->serialize(s);
123: data->release();
124: } else
125: ok = false;
126:
127: return( ok );
128: }
129:
130: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
131:
132: //
133: // Perform the mapping of 'key' moving in the specified direction
134: // into events.
135: //
136:
137: void IOHIKeyboardMapper::translateKeyCode(UInt8 key,
138: bool keyDown,
139: kbdBitVector keyBits)
140: {
141: unsigned char thisBits = _parsedMapping.keyBits[key];
142:
143: /* do mod bit update and char generation in useful order */
144:
145: if (keyDown)
146: {
147: EVK_KEYDOWN(key, keyBits);
148:
149: if (thisBits & NX_MODMASK) doModCalc(key, keyBits);
150: if (thisBits & NX_CHARGENMASK) doCharGen(key, keyDown);
151: }
152: else
153: {
154: EVK_KEYUP(key, keyBits);
155: if (thisBits & NX_CHARGENMASK) doCharGen(key, keyDown);
156: if (thisBits & NX_MODMASK) doModCalc(key, keyBits);
157: }
158: }
159:
160: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161:
162: //
163: // Support goop for parseKeyMapping. These routines are
164: // used to walk through the keymapping string. The string
165: // may be composed of bytes or shorts. If using shorts, it
166: // MUST always be aligned to use short boundries.
167: //
168: typedef struct {
169: unsigned const char *bp;
170: unsigned const char *endPtr;
171: int shorts;
172: } NewMappingData;
173:
174: static inline unsigned int NextNum(NewMappingData *nmd)
175: {
176: if (nmd->bp >= nmd->endPtr)
177: return(0);
178: if (nmd->shorts)
179: return(*((unsigned short *)nmd->bp)++);
180: else
181: return(*((unsigned char *)nmd->bp)++);
182: }
183:
184: //
185: // Perform the actual parsing operation on a keymap. Returns false on failure.
186: //
187:
188: bool IOHIKeyboardMapper::parseKeyMapping(const UInt8 * mapping,
189: UInt32 mappingLength,
190: NXParsedKeyMapping * parsedMapping) const
191: {
192: NewMappingData nmd;
193: int i, j, k, l, n;
194: unsigned int m;
195: int keyMask, numMods;
196: int maxSeqNum = -1;
197:
198: /* Initialize the new map. */
199: bzero( parsedMapping, sizeof (NXParsedKeyMapping) );
200: parsedMapping->maxMod = -1;
201: parsedMapping->numDefs = -1;
202: parsedMapping->numSeqs = -1;
203:
204: nmd.endPtr = mapping + mappingLength;
205: nmd.bp = mapping;
206: nmd.shorts = 1; // First value, the size, is always a short
207:
208: /* Start filling it in with the new data */
209: parsedMapping->mapping = (unsigned char *)mapping;
210: parsedMapping->mappingLen = mappingLength;
211: parsedMapping->shorts = nmd.shorts = NextNum(&nmd);
212:
213: /* Walk through the modifier definitions */
214: numMods = NextNum(&nmd);
215: for(i=0; i<numMods; i++)
216: {
217: /* Get bit number */
218: if ((j = NextNum(&nmd)) >= NX_NUMMODIFIERS)
219: return false;
220:
221: /* Check maxMod */
222: if (j > parsedMapping->maxMod)
223: parsedMapping->maxMod = j;
224:
225: /* record position of this def */
226: parsedMapping->modDefs[j] = (unsigned char *)nmd.bp;
227:
228: /* Loop through each key assigned to this bit */
229: for(k=0,n = NextNum(&nmd);k<n;k++)
230: {
231: /* Check that key code is valid */
232: if ((l = NextNum(&nmd)) >= NX_NUMKEYCODES)
233: return false;
234: /* Make sure the key's not already assigned */
235: if (parsedMapping->keyBits[l] & NX_MODMASK)
236: return false;
237: /* Set bit for modifier and which one */
238: parsedMapping->keyBits[l] |=NX_MODMASK | (j & NX_WHICHMODMASK);
239: }
240: }
241:
242: /* Walk through each key definition */
243: parsedMapping->numDefs = NextNum(&nmd);
244: n = parsedMapping->numDefs;
245: for( i=0; i < NX_NUMKEYCODES; i++)
246: {
247: if (i < n)
248: {
249: parsedMapping->keyDefs[i] = (unsigned char *)nmd.bp;
250: if ((keyMask = NextNum(&nmd)) != (nmd.shorts ? 0xFFFF: 0x00FF))
251: {
252: /* Set char gen bit for this guy: not a no-op */
253: parsedMapping->keyBits[i] |= NX_CHARGENMASK;
254: /* Check key defs to find max sequence number */
255: for(j=0, k=1; j<=parsedMapping->maxMod; j++, keyMask>>=1)
256: {
257: if (keyMask & 0x01)
258: k*= 2;
259: }
260: for(j=0; j<k; j++)
261: {
262: m = NextNum(&nmd);
263: l = NextNum(&nmd);
264: if (m == (unsigned)(nmd.shorts ? 0xFFFF: 0x00FF))
265: if (((int)l) > maxSeqNum)
266: maxSeqNum = l; /* Update expected # of seqs */
267: }
268: }
269: else /* unused code within active range */
270: parsedMapping->keyDefs[i] = NULL;
271: }
272: else /* Unused code past active range */
273: {
274: parsedMapping->keyDefs[i] = NULL;
275: }
276: }
277: /* Walk through sequence defs */
278: parsedMapping->numSeqs = NextNum(&nmd);
279: /* If the map calls more sequences than are declared, bail out */
280: if (parsedMapping->numSeqs <= maxSeqNum)
281: return false;
282:
283: /* Walk past all sequences */
284: for(i = 0; i < parsedMapping->numSeqs; i++)
285: {
286: parsedMapping->seqDefs[i] = (unsigned char *)nmd.bp;
287: /* Walk thru entries in a seq. */
288: for(j=0, l=NextNum(&nmd); j<l; j++)
289: {
290: NextNum(&nmd);
291: NextNum(&nmd);
292: }
293: }
294: /* Install Special device keys. These override default values. */
295: numMods = NextNum(&nmd); /* Zero on old style keymaps */
296: if ( numMods > NX_NUMSPECIALKEYS )
297: return false;
298: if ( numMods )
299: {
300: for ( i = 0; i < NX_NUMSPECIALKEYS; ++i )
301: parsedMapping->specialKeys[i] = NX_NOSPECIALKEY;
302: for ( i = 0; i < numMods; ++i )
303: {
304: j = NextNum(&nmd); /* Which modifier key? */
305: l = NextNum(&nmd); /* Scancode for modifier key */
306: if ( j >= NX_NUMSPECIALKEYS )
307: return false;
308: parsedMapping->specialKeys[j] = l;
309: }
310: }
311: else /* No special keys defs implies an old style keymap */
312: {
313: return false; /* Old style keymaps are guaranteed to do */
314: /* the wrong thing on ADB keyboards */
315: }
316: /* Install bits for Special device keys */
317: for(i=0; i<NX_NUM_SCANNED_SPECIALKEYS; i++)
318: {
319: if ( parsedMapping->specialKeys[i] != NX_NOSPECIALKEY )
320: {
321: parsedMapping->keyBits[parsedMapping->specialKeys[i]] |=
322: (NX_CHARGENMASK | NX_SPECIALKEYMASK);
323: }
324: }
325:
326: return true;
327: }
328:
329: static inline int NEXTNUM(unsigned char ** mapping, short shorts)
330: {
331: int returnValue;
332:
333: if (shorts)
334: {
335: returnValue = *((unsigned short *)*mapping);
336: *mapping += sizeof(unsigned short);
337: }
338: else
339: {
340: returnValue = **((unsigned char **)mapping);
341: *mapping += sizeof(unsigned char);
342: }
343:
344: return returnValue;
345: }
346:
347: //
348: // Look up in the keymapping each key associated with the modifier bit.
349: // Look in the device state to see if that key is down.
350: // Return 1 if a key for modifier 'bit' is down. Return 0 if none is down
351: //
352: static inline int IsModifierDown(NXParsedKeyMapping *parsedMapping,
353: kbdBitVector keyBits,
354: int bit )
355: {
356: int i, n;
357: unsigned char *mapping;
358: unsigned key;
359: short shorts = parsedMapping->shorts;
360:
361: if ( (mapping = parsedMapping->modDefs[bit]) != 0 ) {
362: for(i=0, n=NEXTNUM(&mapping, shorts); i<n; i++)
363: {
364: key = NEXTNUM(&mapping, shorts);
365: if ( EVK_IS_KEYDOWN(key, keyBits) )
366: return 1;
367: }
368: }
369: return 0;
370: }
371:
372: void IOHIKeyboardMapper::calcModBit(int bit, kbdBitVector keyBits)
373: {
374: int bitMask;
375: unsigned myFlags;
376:
377: bitMask = 1<<(bit+16);
378:
379: /* Initially clear bit, as if key-up */
380: myFlags = _delegate->deviceFlags() & (~bitMask);
381: /* Set bit if any associated keys are down */
382: if ( IsModifierDown( &_parsedMapping, keyBits, bit ) )
383: myFlags |= bitMask;
384:
385: if ( bit == NX_MODIFIERKEY_ALPHALOCK ) /* Caps Lock key */
386: _delegate->setAlphaLock((myFlags & NX_ALPHASHIFTMASK) ? true : false);
387:
388: _delegate->setDeviceFlags(myFlags);
389: }
390:
391:
392: //
393: // Perform flag state update and generate flags changed events for this key.
394: //
395: void IOHIKeyboardMapper::doModCalc(int key, kbdBitVector keyBits)
396: {
397: int thisBits;
398:
399: thisBits = _parsedMapping.keyBits[key];
400:
401: if (thisBits & NX_MODMASK)
402: {
403: calcModBit((thisBits & NX_WHICHMODMASK), keyBits);
404: /* The driver generates flags-changed events only when there is
405: no key-down or key-up event generated */
406: if (!(thisBits & NX_CHARGENMASK))
407: {
408: /* Post the flags-changed event */
409: _delegate->keyboardEvent(NX_FLAGSCHANGED,
410: /* flags */ _delegate->eventFlags(),
411: /* keyCode */ key,
412: /* charCode */ 0,
413: /* charSet */ 0,
414: /* originalCharCode */ 0,
415: /* originalCharSet */ 0);
416: }
417: else /* Update, but don't generate an event */
418: _delegate->updateEventFlags(_delegate->eventFlags());
419: }
420: }
421:
422: //
423: // Perform character event generation for this key
424: //
425: void IOHIKeyboardMapper::doCharGen(int keyCode, bool down)
426: {
427: int i, n, eventType, adjust, thisMask, modifiers, saveModifiers;
428: short shorts;
429: unsigned charSet, origCharSet;
430: unsigned charCode, origCharCode;
431: unsigned char *mapping;
432: unsigned eventFlags, origflags;
433:
434: _delegate->setCharKeyActive(true); // a character generating key is active
435:
436: eventType = (down == true) ? NX_KEYDOWN : NX_KEYUP;
437: eventFlags = _delegate->eventFlags();
438: saveModifiers = eventFlags >> 16; // machine independent mod bits
439: /* Set NX_ALPHASHIFTMASK based on alphaLock OR shift active */
440: if( saveModifiers & (NX_SHIFTMASK >> 16))
441: saveModifiers |= (NX_ALPHASHIFTMASK >> 16);
442:
443: /* Get this key's key mapping */
444: shorts = _parsedMapping.shorts;
445: mapping = _parsedMapping.keyDefs[keyCode];
446: modifiers = saveModifiers;
447: if ( mapping )
448: {
449: /* Build offset for this key */
450: thisMask = NEXTNUM(&mapping, shorts);
451: if (thisMask && modifiers)
452: {
453: adjust = (shorts ? sizeof(short) : sizeof(char))*2;
454: for( i = 0; i <= _parsedMapping.maxMod; ++i)
455: {
456: if (thisMask & 0x01)
457: {
458: if (modifiers & 0x01)
459: mapping += adjust;
460: adjust *= 2;
461: }
462: thisMask >>= 1;
463: modifiers >>= 1;
464: }
465: }
466: charSet = NEXTNUM(&mapping, shorts);
467: charCode = NEXTNUM(&mapping, shorts);
468:
469: /* construct "unmodified" character */
470: mapping = _parsedMapping.keyDefs[keyCode];
471: modifiers = saveModifiers & ((NX_ALPHASHIFTMASK | NX_SHIFTMASK) >> 16);
472:
473: thisMask = NEXTNUM(&mapping, shorts);
474: if (thisMask && modifiers)
475: {
476: adjust = (shorts ? sizeof(short) : sizeof(char)) * 2;
477: for ( i = 0; i <= _parsedMapping.maxMod; ++i)
478: {
479: if (thisMask & 0x01)
480: {
481: if (modifiers & 0x01)
482: mapping += adjust;
483: adjust *= 2;
484: }
485: thisMask >>= 1;
486: modifiers >>= 1;
487: }
488: }
489: origCharSet = NEXTNUM(&mapping, shorts);
490: origCharCode = NEXTNUM(&mapping, shorts);
491:
492: if (charSet == (unsigned)(shorts ? 0xFFFF : 0x00FF))
493: {
494: // Process as a character sequence
495: // charCode holds the sequence number
496: mapping = _parsedMapping.seqDefs[charCode];
497:
498: origflags = eventFlags;
499: for(i=0,n=NEXTNUM(&mapping, shorts);i<n;i++)
500: {
501: #if 0
502: // every 10 characters, give the windowserver a chance to
503: // actually read the events out of the event queue
504: if ((i % 10) == 9)
505: (void) thread_block();
506: #endif
507: if ( (charSet = NEXTNUM(&mapping, shorts)) == 0xFF ) /* metakey */
508: {
509: if ( down == true ) /* down or repeat */
510: {
511: eventFlags |= (1 << (NEXTNUM(&mapping, shorts) + 16));
512: _delegate->keyboardEvent(NX_FLAGSCHANGED,
513: /* flags */ _delegate->deviceFlags(),
514: /* keyCode */ keyCode,
515: /* charCode */ 0,
516: /* charSet */ 0,
517: /* originalCharCode */ 0,
518: /* originalCharSet */ 0);
519: }
520: else
521: NEXTNUM(&mapping, shorts); /* Skip over value */
522: }
523: else
524: {
525: charCode = NEXTNUM(&mapping, shorts);
526: _delegate->keyboardEvent(eventType,
527: /* flags */ eventFlags,
528: /* keyCode */ keyCode,
529: /* charCode */ charCode,
530: /* charSet */ charSet,
531: /* originalCharCode */ charCode,
532: /* originalCharSet */ charSet);
533: }
534: }
535: /* Done with macro. Restore the flags if needed. */
536: if ( eventFlags != origflags )
537: {
538: _delegate->keyboardEvent(NX_FLAGSCHANGED,
539: /* flags */ _delegate->deviceFlags(),
540: /* keyCode */ keyCode,
541: /* charCode */ 0,
542: /* charSet */ 0,
543: /* originalCharCode */ 0,
544: /* originalCharSet */ 0);
545: eventFlags = origflags;
546: }
547: }
548: else /* A simple character generating key */
549: {
550: _delegate->keyboardEvent(eventType,
551: /* flags */ eventFlags,
552: /* keyCode */ keyCode,
553: /* charCode */ charCode,
554: /* charSet */ charSet,
555: /* originalCharCode */ origCharCode,
556: /* originalCharSet */ origCharSet);
557: }
558: } /* if (mapping) */
559:
560: /*
561: * Check for a device control key: note that they always have CHARGEN
562: * bit set
563: */
564: if (_parsedMapping.keyBits[keyCode] & NX_SPECIALKEYMASK)
565: {
566: for(i=0; i<NX_NUM_SCANNED_SPECIALKEYS; i++)
567: {
568: if ( keyCode == _parsedMapping.specialKeys[i] )
569: {
570: _delegate->keyboardSpecialEvent(eventType,
571: /* flags */ eventFlags,
572: /* keyCode */ keyCode,
573: /* specialty */ i);
574: /*
575: * Special keys hack for letting an arbitrary (non-locking)
576: * key act as a CAPS-LOCK key. If a special CAPS LOCK key
577: * is designated, and there is no key designated for the
578: * AlphaLock function, then we'll let the special key toggle
579: * the AlphaLock state.
580: */
581: if (i == NX_KEYTYPE_CAPS_LOCK
582: && down == true
583: && !_parsedMapping.modDefs[NX_MODIFIERKEY_ALPHALOCK] )
584: {
585: unsigned myFlags = _delegate->deviceFlags();
586: bool alphaLock = (_delegate->alphaLock() == false);
587: // bool alphaLock = down;
588:
589: // Set delegate's alphaLock state
590: _delegate->setAlphaLock(alphaLock);
591: // Update the delegate's flags
592: if ( alphaLock )
593: myFlags |= NX_ALPHASHIFTMASK;
594: else
595: myFlags &= ~NX_ALPHASHIFTMASK;
596: _delegate->setDeviceFlags(myFlags);
597: _delegate->keyboardEvent(NX_FLAGSCHANGED,
598: /* flags */ myFlags,
599: /* keyCode */ keyCode,
600: /* charCode */ 0,
601: /* charSet */ 0,
602: /* originalCharCode */ 0,
603: /* originalCharSet */ 0);
604: }
605: break;
606: }
607: }
608: }
609: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.