|
|
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.