Annotation of XNU/iokit/Families/IOHIDSystem/IOHIKeyboardMapper.cpp, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.