Annotation of driverkit/libDriver/Kernel/KeyMap.m, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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