Annotation of kernel/bsd/dev/ppc/EventSrcPCKeyboard.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: 
                     25: /*     Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved. 
                     26:  *
                     27:  * EventSrcPCKeyoard.m - PC Keyboard EventSrc subclass implementation
                     28:  *
                     29:  * HISTORY
                     30:  * 10 Sep 1992    Joe Pasqua
                     31:  *      Created. 
                     32:  * 5 Nov, 1993
                     33:  *     Modified for Hppa
                     34:  * 15 Dec 1993
                     35:  *     Modified for 712
                     36:  * 23 Mar 1997
                     37:  *     Modified for PPC
                     38:  */
                     39: 
                     40: // TO DO:
                     41: //
                     42: // NOTES:
                     43: // * We override methods in the EventSrcExported protocol so that we can
                     44: //   intercept messages used to control who owns us. This gives us
                     45: //   an opportunity to acquire/release the PCKeyboard device we want to own.
                     46: // * In the current system the EventDriver instance is always the owner
                     47: //   of this EventSrc. In the future the km driver and the EventDriver might
                     48: //   both be potential owners.
                     49: // * The device dependent portion of the event flags are set by this module
                     50: //   before the flags are passed up to our owner. There are a couple of notes
                     51: //   on this. First, the PC keyboard has no key labelled "Command", therefore
                     52: //   the NX_NEXT[RL]CMDKEYMASK flag bits will never be set. Conversely, the
                     53: //   PC keyboard has both a left and a right Control key. When either key is
                     54: //   pressed we set the NX_NEXTCTLKEYMASK mask. The code processing events
                     55: //   must determine which one it was by looking at the code that is generated.
                     56: // * To find things that need to be fixed, search for FIX, to find questions
                     57: //   to be resolved, search for ASK, to find stuff that still needs to be
                     58: //   done, search for TO DO.
                     59: //
                     60: 
                     61: #import <driverkit/generalFuncs.h>
                     62: #import <machkit/NXLock.h>
                     63: #import <driverkit/KeyMap.h>
                     64: #import <bsd/dev/evsio.h>
                     65: #import <bsd/dev/ppc/event.h>
                     66: #import <bsd/dev/ppc/PPCKeymap.c>      // The default keymapping string
                     67: #import <bsd/dev/ppc/EventSrcPCKeyboard.h> 
                     68: #import <bsd/dev/ppc/PCKeyboardDefs.h>
                     69: #import <bsd/dev/ppc/PPCKeyboardPriv.h>
                     70: 
                     71: // Private variables that are global to the module:
                     72: static EventSrcPCKeyboard *instance = (EventSrcPCKeyboard *)0;
                     73: 
                     74: // Forward declarations
                     75: static void autoRepeatCallout( void *data );
                     76: unsigned int wserver_on=0;
                     77: 
                     78: //Make sure USB exists
                     79: id usb_UIM_object = 0;
                     80: 
                     81: // FIXME: Nasty hack to reinit mouse on server startup
                     82: #include "PPCMouse.h"
                     83: extern PPCMouse *_my_Mouse;
                     84: 
                     85: @implementation EventSrcPCKeyboard
                     86: 
                     87: //
                     88: // BEGIN:      Utility Procedures
                     89: //
                     90: static void nsecs_to_packed_ns(ns_time_t *nsecs, unsigned int *pnsecs)
                     91: {
                     92:     _NX_packed_time_t data;
                     93:     int i;
                     94: 
                     95:     data.tval = *nsecs;        // nsecs to ns_time_t
                     96:     for ( i = 0; i < EVS_PACKED_TIME_SIZE; ++i )
                     97:        pnsecs[i] = data.itval[i];
                     98: }
                     99: 
                    100: static void packed_nsecs_to_nsecs(unsigned int *pnsecs, ns_time_t *nsecs)
                    101: {
                    102:     _NX_packed_time_t data;
                    103:     int i;
                    104: 
                    105:     for ( i = 0; i < EVS_PACKED_TIME_SIZE; ++i )
                    106:        data.itval[i] = pnsecs[i];
                    107:     *nsecs = data.tval;
                    108: }
                    109: //
                    110: // END:        Utility Procedures
                    111: //
                    112: 
                    113: 
                    114: //
                    115: // BEGIN:      Implementation of Private EventSrcPCKeyoard methods
                    116: //
                    117: - resetKeyboard
                    118: // Description:        Reset the keymapping to the default value and reconfigure
                    119: //             the keyboards.
                    120: {
                    121:     [deviceLock lock];
                    122:     if ( keyMap != nil )
                    123:        [keyMap free];
                    124:     // Set up default keymapping.
                    125: 
                    126:     keyMap = [[KeyMap alloc] initFromKeyMapping:PPCDefaultKeymap
                    127:        length:sizeof PPCDefaultKeymap
                    128:        canFree:NO];
                    129: 
                    130:     [keyMap setDelegate:self];
                    131:     keyRepeat = EV_DEFAULTKEYREPEAT;
                    132:     initialKeyRepeat = EV_DEFAULTINITIALREPEAT;
                    133:     [deviceLock unlock];
                    134:     return self;
                    135: }
                    136: 
                    137: - scheduleAutoRepeat
                    138: // Description:        Schedule a procedure to be called when a timeout has expired
                    139: //             so that we can generate a repeated key.
                    140: // Preconditions:
                    141: // *   deviceLock should be held on entry
                    142: {
                    143:     if ( calloutPending == YES )
                    144:     {
                    145:        ns_untimeout( (func)autoRepeatCallout, (void *)self );
                    146:        calloutPending = NO;
                    147:     }
                    148:     if ( downRepeatTime > 0ULL )
                    149:     {
                    150:        ns_abstimeout(
                    151:            (func)autoRepeatCallout,
                    152:            (void *)self,
                    153:            downRepeatTime,
                    154:            CALLOUT_PRI_THREAD );
                    155:        calloutPending = YES;
                    156:     }
                    157:     return self;
                    158: }
                    159: 
                    160: - autoRepeat
                    161: // Description:        Repeat the currently pressed key and schedule ourselves
                    162: //             to be called again after another interval elapses. 
                    163: // Preconditions:
                    164: // *   Should only be executed on callout thread
                    165: // *   deviceLock should be unlocked on entry.
                    166: {
                    167:     ns_time_t ns;
                    168:     
                    169:     IOGetTimestamp(&ns);
                    170:     [deviceLock lock];
                    171:     if ( calloutPending == NO )
                    172:     {
                    173:        [deviceLock unlock];
                    174:        return self;
                    175:     }
                    176:     calloutPending = NO;
                    177:     isRepeat = YES;
                    178:     
                    179:     if ( downRepeatTime > 0ULL && downRepeatTime <= ns )
                    180:     {
                    181:        // Device is due to generate a repeat
                    182:        lastEventTime = ns;
                    183:        [keyMap doKeyboardEvent:codeToRepeat
                    184:            direction:YES
                    185:            keyBits:keyState];
                    186:        downRepeatTime += keyRepeat;
                    187:     }
                    188: 
                    189:     isRepeat = NO;
                    190:     [self scheduleAutoRepeat];
                    191:     [deviceLock unlock];
                    192:     return self;
                    193: }
                    194: 
                    195: static void autoRepeatCallout( void *data )
                    196: // Description:        Callout used to enter Obj-C autoRepeat code from NS timer
                    197: //             callout. This proc was set as a callback in scheduleAutoRepeat.
                    198: {
                    199:     EventSrcPCKeyboard *kbd = (EventSrcPCKeyboard *)data;
                    200:     [kbd autoRepeat];
                    201: }
                    202: 
                    203: 
                    204: - setRepeat:(unsigned)eventType forCode:(unsigned)keyCode
                    205: // Description:        Set up or tear dow key repeat operations. The method
                    206: //             that locks deviceLock is a bit higher on the call stack.
                    207: //             This method is invoked as a side effect of our own
                    208: //             invocation of [keyMap doKeyboardEvent].
                    209: // Preconditions:
                    210: // *   deviceLock should be held upon entry.
                    211: {
                    212:     if ( isRepeat == NO )  // make sure we're not already repeating
                    213:     {
                    214:        if (eventType == NX_KEYDOWN)    // Start repeat
                    215:        {
                    216:            // Set this key to repeat (push out last key if present)
                    217:            downRepeatTime = initialKeyRepeat + lastEventTime; 
                    218:            codeToRepeat = keyCode;
                    219:            // reschedule key repeat event here
                    220:            [self scheduleAutoRepeat];
                    221:        }
                    222:        else if (eventType == NX_KEYUP) // End repeat
                    223:        {
                    224:            /* Remove from downKey */
                    225:            if (codeToRepeat == keyCode)
                    226:            {
                    227:                downRepeatTime = 0ULL;
                    228:                codeToRepeat = -1;
                    229:                [self scheduleAutoRepeat];
                    230:            }
                    231:        }
                    232:     }
                    233:     return self;
                    234: }
                    235: 
                    236: - initKeyboard
                    237: // Description:        Perform setup work needed to find and configure our
                    238: //             PCKeyboard device. We have to tell it to send events to us.
                    239: {
                    240:     IOReturn drtn;
                    241:     
                    242: 
                    243:     drtn = IOGetObjectForDeviceName("PPCKeyboard0", &kbdDevice);
                    244:     if(drtn) {
                    245:        IOLog("initKeyboard: Can't find PPCKeyboard0 (%s)\n",
                    246:            [self stringFromReturn:drtn]);
                    247:        return nil;
                    248:     }
                    249:     return self;
                    250: }
                    251: //
                    252: // END:        Implementation of Private EventSrcPCKeyoard methods
                    253: //
                    254: 
                    255: 
                    256: //
                    257: // BEGIN:      Implementation of the KeyMapDelegate protocol
                    258: //
                    259: - keyboardEvent:(int)eventType
                    260:     flags:(unsigned)flags
                    261:     keyCode:(unsigned)keyCode
                    262:     charCode:(unsigned)charCode
                    263:     charSet:(unsigned)charSet
                    264:     originalCharCode:(unsigned)origCharCode
                    265:     originalCharSet:(unsigned)origCharSet
                    266: // Description: We use this notification to set up our keyRepeat timer
                    267: //             and to pass along the event to our owner. In the current
                    268: //             implementation this is always the EventDriver. In the future,
                    269: //             the km driver may be another potential owner. This method
                    270: //             will be called while the KeyMap object is processing
                    271: //             the key code we've sent it using doKeyboardEvent.
                    272: {
                    273:     [[self owner] keyboardEvent        :eventType
                    274:        flags:(flags | deviceDependentFlags)
                    275:        keyCode:keyCode
                    276:        charCode:charCode
                    277:        charSet:charSet
                    278:        originalCharCode:origCharCode
                    279:        originalCharSet:origCharSet
                    280:        repeat:isRepeat
                    281:        atTime:lastEventTime];
                    282: 
                    283:     // Set up key repeat operations here.
                    284:     return [self setRepeat:eventType forCode:keyCode];
                    285: }
                    286: 
                    287: - keyboardSpecialEvent:(unsigned)eventType
                    288:        flags:(unsigned)flags
                    289:        keyCode:(unsigned)keyCode
                    290:        specialty:(unsigned)flavor
                    291: // Description: See the description for keyboardEvent.
                    292: {
                    293:     [[self owner] keyboardSpecialEvent:eventType
                    294:        flags:(flags | deviceDependentFlags)
                    295:        keyCode :keyCode
                    296:        specialty:flavor
                    297:        atTime:lastEventTime];
                    298: 
                    299:     // Set up key repeat operations here.
                    300:     if (flavor != NX_KEYTYPE_CAPS_LOCK)
                    301:        return [self setRepeat:eventType forCode:keyCode];
                    302: }
                    303: 
                    304: - updateEventFlags:(unsigned)flags
                    305: // Description:        Process non-event-generating flag changes. Simply pass this
                    306: //             along to our owner.
                    307: {
                    308:     return [[self owner] updateEventFlags:flags];
                    309: }
                    310: 
                    311: - (unsigned)eventFlags
                    312: // Description:        Return global event flags In this world, there is only
                    313: //             one keyboard device so device flags == global flags.
                    314: {
                    315:     return eventFlags;
                    316: }
                    317: 
                    318: - (unsigned)deviceFlags
                    319: // Description: Return per-device event flags. In this world, there is only
                    320: //             one keyboard device so device flags == global flags.
                    321: {
                    322:     return eventFlags;
                    323: }
                    324: 
                    325: - setDeviceFlags:(unsigned)flags
                    326: // Description: Set device event flags. In this world, there is only
                    327: //             one keyboard device so device flags == global flags.
                    328: {
                    329:     eventFlags = flags;
                    330:     return self;
                    331: }
                    332: 
                    333: - (BOOL)alphaLock
                    334: // Description: Return current alpha-lock state. This is a state tracking
                    335: //             callback used by the KeyMap object.
                    336: {
                    337:     return alphaLock;
                    338: }
                    339: 
                    340: - setAlphaLock:(BOOL)val
                    341: // Description: Set current alpha-lock state This is a state tracking
                    342: //             callback used by the KeyMap object.
                    343: {
                    344:     alphaLock = val;
                    345:     [kbdDevice setAlphaLockFeedback:val];
                    346:     return self;
                    347: }
                    348: 
                    349: - (BOOL)charKeyActive
                    350: // Description: Return YES If a character generating key down This is a state
                    351: //             tracking callback used by the KeyMap object.
                    352: {
                    353:     return charKeyActive;
                    354: }
                    355: 
                    356: - setCharKeyActive:(BOOL)val
                    357: // Description: Note whether a char generating key is down. This is a state
                    358: //             tracking callback used by the KeyMap object.
                    359: {
                    360:     charKeyActive = val;
                    361:     return self;
                    362: }
                    363: //
                    364: // END:                Implementation of the KeyMapDelegate protocol
                    365: //
                    366: 
                    367: 
                    368: //
                    369: // BEGIN:      Implementation of PCKeyboardImported protocol
                    370: //
                    371: - (void)dispatchKeyboardEvent:(PCKeyboardEvent *)event
                    372: // Description:        This method is the heart of event dispatching. The underlying
                    373: //             PCKeyboard object invokes this method with each event. We then
                    374: //             get the event xlated and dispatched using a keyMap instance.
                    375: //             The event structure passed in by reference should not be freed.
                    376: {
                    377:     unsigned keyMask;
                    378: 
                    379:     lastEventTime = event->timeStamp;
                    380: 
                    381:     switch (event->keyCode) {
                    382:        case ADBK_SHIFT:     keyMask = NX_NEXTLSHIFTKEYMASK; break;
                    383:        case ADBK_SHIFT_R:   keyMask = NX_NEXTRSHIFTKEYMASK; break;
                    384:        case ADBK_OPTION:    keyMask = NX_NEXTLALTKEYMASK; break;
                    385:        case ADBK_OPTION_R:  keyMask = NX_NEXTRALTKEYMASK; break;
                    386:        case ADBK_CONTROL:   keyMask = NX_NEXTCTLKEYMASK; break;
                    387:        case ADBK_CONTROL_R: keyMask = NX_NEXTCTLKEYMASK; break;
                    388:        default:             keyMask = 0; break;
                    389:     }
                    390: 
                    391:     if (event->goingDown)
                    392:        deviceDependentFlags |= keyMask;
                    393:     else
                    394:        deviceDependentFlags &= ~keyMask;
                    395: 
                    396:     [deviceLock lock];
                    397: 
                    398:     if( (event->keyCode == ADBK_CAPSLOCK)) {                   // Send a capslock toggle
                    399:        if( event->goingDown != alphaLock ) {
                    400:            [keyMap doKeyboardEvent:ADBK_CAPSLOCK
                    401:                direction:YES
                    402:                keyBits:keyState];
                    403:            [keyMap doKeyboardEvent:ADBK_CAPSLOCK
                    404:                direction:NO
                    405:                keyBits:keyState];
                    406:        }
                    407:     } else {
                    408:        [keyMap doKeyboardEvent:event->keyCode
                    409:            direction:event->goingDown
                    410:            keyBits:keyState];
                    411:     }
                    412:     [deviceLock unlock];
                    413: }
                    414: 
                    415: - (IOReturn)relinquishOwnershipRequest : device
                    416: {
                    417:     IOReturn r;
                    418: 
                    419:     [[self ownerLock] lock];
                    420:     if ( [self owner] == nil )
                    421:     {
                    422:        ownDevice = NO;
                    423:        r = IO_R_SUCCESS;
                    424:     }
                    425:     else
                    426:        r = IO_R_BUSY;
                    427:     
                    428:     [[self ownerLock] unlock];
                    429:     return r; 
                    430: }
                    431: 
                    432: - (IOReturn)canBecomeOwner : device
                    433: {
                    434:     IOReturn drtn;
                    435:     drtn = [device becomeOwner: self];
                    436:     if(drtn)
                    437:     {
                    438:        IOLog("%s: becomeOwner of %s failed (%s)\n",
                    439:            [self name],
                    440:            [device name],
                    441:            [self stringFromReturn:drtn]);
                    442:     }
                    443:     else
                    444:     {
                    445:        ownDevice = YES;
                    446:     }
                    447:     return( drtn);
                    448: }
                    449: //
                    450: // END:                Implementation of PCKeyboardImported protocol
                    451: //
                    452: 
                    453: 
                    454: //
                    455: // BEGIN:      Implementation of Exported EventSrcPCKeyoard methods
                    456: //
                    457: - init
                    458: // Description:        Initialize an EventSrcPCKeyboard
                    459: {
                    460:     [deviceLock lock];
                    461:     [super init];
                    462:     if ( keyMap != nil )
                    463:        [keyMap free];
                    464:     // Set up default keymapping
                    465: 
                    466:     keyMap = [[KeyMap alloc] initFromKeyMapping:PPCDefaultKeymap
                    467:        length:sizeof PPCDefaultKeymap
                    468:        canFree:NO];
                    469: 
                    470:     [keyMap setDelegate:self];
                    471:     [self initKeyboard];
                    472:     keyRepeat = EV_DEFAULTKEYREPEAT;
                    473:     initialKeyRepeat = EV_DEFAULTINITIALREPEAT;
                    474:     [deviceLock unlock];
                    475:     return self;
                    476: }
                    477: 
                    478: + probe
                    479: // Description:        This is our factory method. It is the IODevice probe
                    480: //             routine for psuedo drivers.
                    481: {
                    482:     if ( instance != nil )
                    483:        return instance;
                    484: 
                    485:     instance = [self alloc];
                    486: 
                    487:     instance->deviceLock = [NXLock new];
                    488:     [instance setName:"EventSrcPCKeyboard0"];
                    489:     [instance setDeviceKind:"EventSrcPCKeyboard"];
                    490:     
                    491:     if ( [instance init] == nil )
                    492:        [instance free];        // No devices.  Go away
                    493:     return instance;
                    494: }
                    495: 
                    496: - free
                    497: // Description:        Go Away. Be careful when freeing the lock.
                    498: {
                    499:     id lock;
                    500:     
                    501:     lock = deviceLock;
                    502:     [lock lock];
                    503:     instance = nil;
                    504:     deviceLock = nil;
                    505:     if ( keyMap != nil )
                    506:        [keyMap free];
                    507:     // Release keyboard device, so we won't get any more events
                    508:     if ( kbdDevice != nil )
                    509:        [kbdDevice relinquishOwnership:self];
                    510:     [lock unlock];
                    511:     [lock free];
                    512:     return [super free];
                    513: }
                    514: 
                    515: - (IOReturn)getIntValues:(unsigned *)parameterArray
                    516:        forParameter:(IOParameterName)parameterName
                    517:        count:(unsigned int *)count
                    518: {
                    519:     IOReturn r = IO_R_INVALID_ARG;
                    520:     NXEventSystemDevice *dp;
                    521:     unsigned maxCount = *count;
                    522:     unsigned *returnedCount = count;
                    523: 
                    524:     if ( strcmp( parameterName, EVSIOCKR ) == 0 )      // Current Key Repeat
                    525:     {
                    526:        if ( maxCount >= EVSIOCKR_SIZE )
                    527:        {
                    528:            *returnedCount = EVSIOCKR_SIZE;
                    529:            [deviceLock lock];
                    530:            nsecs_to_packed_ns(
                    531:                &initialKeyRepeat, &parameterArray[EVSIOCKR_INITIAL]);
                    532:            nsecs_to_packed_ns(
                    533:                &keyRepeat, &parameterArray[EVSIOCKR_BETWEEN]);
                    534:            [deviceLock unlock];
                    535:            r = IO_R_SUCCESS;
                    536:        }
                    537:     }
                    538:     else if ( strcmp( parameterName, EVSIOCKML ) == 0 )        // Current Keymap len.
                    539:     {
                    540:        if ( maxCount >= EVSIOCKML_SIZE )
                    541:        {
                    542:            *returnedCount = EVSIOCKML_SIZE;
                    543:            [deviceLock lock];
                    544:            if ( keyMap == nil )
                    545:                parameterArray[0] = 0;
                    546:            else
                    547:                parameterArray[0] = [keyMap keyMappingLength];
                    548:            [deviceLock unlock];
                    549:            r = IO_R_SUCCESS;
                    550:        }
                    551:     }
                    552:     else if ( strcmp( parameterName, EVSIOINFO ) == 0 )        // Device info
                    553:     {  
                    554:        dp = (NXEventSystemDevice *)&parameterArray[0];
                    555:        *returnedCount = 0;
                    556:        // No need to lock device since we're not even reading the structure.
                    557:        dp->interface = [kbdDevice interfaceId]; 
                    558:        dp->dev_type = NX_EVS_DEVICE_TYPE_KEYBOARD;
                    559:        dp->interface_addr = 0;
                    560:        dp->id = [kbdDevice handlerId];  //Right now ID is for ADB keyboard
                    561: //This line shows up very late in bootup, around time LOGIN is happening on screen
                    562: //   I think this may be the code that maps international key maps.  A.W. 12/21/98
                    563: //   Now I will call USB method to retrieve USB keyboard attached, if any.  The
                    564: //   USB method will return the same 16 + ADB ID that is in the various .keyboard
                    565: //   files in /System/Library/Keyboards/*
                    566:        
                    567:        if (usb_UIM_object != 0)
                    568:        {       
                    569:                int     adb_id;
                    570: 
                    571:                adb_id = [usb_UIM_object    getADBKeyboardID];
                    572:                if (adb_id != 0)
                    573:                {
                    574:                        dp->id = adb_id;        //converted from USB land
                    575:                        //kprintf("ADB: keyboard converted from USB is %d decimal\n", adb_id);
                    576:                }
                    577:        }
                    578: 
                    579: 
                    580:        *returnedCount = sizeof(NXEventSystemDevice) / sizeof(int);
                    581:        r = IO_R_SUCCESS;
                    582:     }
                    583:     else if ( strcmp( parameterName, EVSIOGKEYS ) == 0 )       // Key state
                    584:     {
                    585:        if( maxCount == EVK_NUNITS) {
                    586:            [deviceLock lock];
                    587:            bcopy( &keyState, parameterArray, EVK_NUNITS * sizeof( int));
                    588:            [deviceLock unlock];
                    589:            r = IO_R_SUCCESS;
                    590:        }
                    591:     }
                    592:     else
                    593:     {
                    594:        r = [super getIntValues:parameterArray
                    595:                        forParameter:parameterName
                    596:                        count:count];
                    597:        if (r == IO_R_UNSUPPORTED)
                    598:            r = IO_R_INVALID_ARG;
                    599:     }
                    600:     return r;
                    601: }
                    602: 
                    603: - (IOReturn)getCharValues:(unsigned char *)parameterArray
                    604:        forParameter:(IOParameterName)parameterName
                    605:        count:(unsigned int *)count
                    606: {
                    607:     IOReturn r = IO_R_INVALID_ARG;
                    608:     int cnt;
                    609:     unsigned maxCount = *count;
                    610:     unsigned *returnedCount = count;
                    611: 
                    612:     if ( strcmp( parameterName, EVSIOCKM ) == 0 )      // Current KeyMap
                    613:     {
                    614:        [deviceLock lock];
                    615:        if ( keyMap != nil )
                    616:        {
                    617:            cnt = [keyMap keyMappingLength];
                    618:            cnt = (cnt < maxCount) ? cnt : maxCount;
                    619:            *returnedCount = cnt;
                    620:            bcopy( [keyMap keyMapping:(int *)0], parameterArray, cnt );
                    621:            r = IO_R_SUCCESS;
                    622:        }
                    623:        else
                    624:            r = IO_R_NOT_ATTACHED;
                    625:        [deviceLock unlock];
                    626:     }
                    627:     else
                    628:     {
                    629:        r = [super getCharValues:parameterArray
                    630:                        forParameter:parameterName
                    631:                        count:count];
                    632:        if (r == IO_R_UNSUPPORTED)
                    633:            r = IO_R_INVALID_ARG;
                    634:     }
                    635:     return r;
                    636: }
                    637:                        
                    638: - (IOReturn)setIntValues:(unsigned *)parameterArray
                    639:        forParameter:(IOParameterName)parameterName
                    640:        count:(unsigned int)count
                    641: {
                    642:     IOReturn r = IO_R_INVALID_ARG;
                    643: 
                    644:     if ( strcmp( parameterName, EVSIOSKR ) == 0 )      // Set Key Repeat
                    645:     {
                    646:        if ( count == EVSIOSKR_SIZE )
                    647:        {
                    648:            [deviceLock lock];
                    649:            packed_nsecs_to_nsecs(parameterArray, &keyRepeat);
                    650:            if ( keyRepeat < EV_MINKEYREPEAT )
                    651:                    keyRepeat = EV_MINKEYREPEAT;
                    652:            [deviceLock unlock];
                    653:            r = IO_R_SUCCESS;
                    654:        }
                    655:     }
                    656:     else if ( strcmp( parameterName, EVSIOSIKR ) == 0 )        // Set Init Key Repeat
                    657:     {
                    658:        if ( count == EVSIOSIKR_SIZE )
                    659:        {
                    660:            [deviceLock lock];
                    661:            packed_nsecs_to_nsecs(parameterArray, &initialKeyRepeat);
                    662:            if ( initialKeyRepeat < EV_MINKEYREPEAT )
                    663:                    initialKeyRepeat = EV_MINKEYREPEAT;
                    664:            [deviceLock unlock];
                    665:            r = IO_R_SUCCESS;
                    666:        }
                    667:     }
                    668:     else if ( strcmp( parameterName, EVSIORKBD ) == 0 )        // Reset keyboard
                    669:     {
                    670:        [self resetKeyboard];
                    671:        r = IO_R_SUCCESS;
                    672:     }
                    673:     else
                    674:     {
                    675:        r = [super setIntValues:parameterArray
                    676:                   forParameter:parameterName
                    677:                   count : count];
                    678:        if (r == IO_R_UNSUPPORTED)
                    679:            r = IO_R_INVALID_ARG;
                    680:     }
                    681:     return r;
                    682: }
                    683: 
                    684: - (IOReturn)setCharValues:(unsigned char *)parameterArray
                    685:        forParameter:(IOParameterName)parameterName
                    686:        count:(unsigned int)count
                    687: {
                    688:     IOReturn r = IO_R_INVALID_ARG;
                    689:     unsigned char *map;
                    690:     id oldMap;
                    691: 
                    692:     if ( strcmp( parameterName, EVSIOSKM ) == 0 )      // Set KeyMap
                    693:     {
                    694:        map = (unsigned char *)IOMalloc( count );
                    695:        bcopy( parameterArray, map, count );
                    696:        [deviceLock lock];
                    697:        oldMap = keyMap;
                    698:        keyMap = [[KeyMap alloc] initFromKeyMapping:map
                    699:            length:count
                    700:            canFree:YES];
                    701:        if ( keyMap != nil )
                    702:        {
                    703:            if ( oldMap != nil )
                    704:                [oldMap free];
                    705:            [keyMap setDelegate:self];
                    706:            r = IO_R_SUCCESS;
                    707:        }
                    708:        else
                    709:        {
                    710:            keyMap = oldMap;
                    711:            r = IO_R_INVALID_ARG;
                    712:        } 
                    713:        [deviceLock unlock];
                    714:     }
                    715:     else
                    716:     {
                    717:        r = [super setCharValues:parameterArray
                    718:                   forParameter:parameterName
                    719:                   count : count];
                    720:        if (r == IO_R_UNSUPPORTED)
                    721:            r = IO_R_INVALID_ARG;
                    722:     }
                    723:     return r;
                    724: }
                    725: //
                    726: // END:                Implementation of Exported EventSrcPCKeyoard methods
                    727: //
                    728: 
                    729: 
                    730: 
                    731: //
                    732: // BEGIN:      Implementation of EventSrcExported protocol
                    733: //
                    734: //
                    735: - (IOReturn)relinquishOwnership:(id)client
                    736: {
                    737:        IOReturn r;
                    738: 
                    739:        // kill autorepeat task
                    740:        downRepeatTime = 0ULL;
                    741:        codeToRepeat = -1;
                    742:        [self scheduleAutoRepeat];
                    743:        // clear modifiers to avoid stuck keys
                    744:        [self setAlphaLock:NO];
                    745:        [[self owner] updateEventFlags:0];
                    746:        deviceDependentFlags = 0;
                    747:        eventFlags = 0;
                    748:        bzero( keyState, sizeof( kbdBitVector));
                    749: 
                    750:        r = [super relinquishOwnership:client];
                    751:        [[self ownerLock] lock];
                    752:        // If nobody took over this EventSrc, release attached keyboards
                    753:        wserver_on = 0;
                    754:        if ( r == IO_R_SUCCESS && [self owner] == nil )
                    755:        {
                    756:            if ( [kbdDevice relinquishOwnership:self] == IO_R_SUCCESS )
                    757:                ownDevice = NO;
                    758:        }
                    759:        [[self ownerLock] unlock];
                    760:        return r;
                    761: }
                    762: 
                    763: - (IOReturn) becomeOwner:(id)client
                    764: {
                    765:        IOReturn r;
                    766: 
                    767:        r = [super becomeOwner:client];
                    768:        [[self ownerLock] lock];
                    769:        if ( r == IO_R_SUCCESS && ownDevice == NO )
                    770:        {
                    771:            if ( [kbdDevice becomeOwner:self] == IO_R_SUCCESS )
                    772:            {
                    773:                ownDevice = YES;
                    774:                wserver_on = 1;
                    775: // FIXME: Nasty hack to reinit mouse on server startup
                    776:                [_my_Mouse mouseInit];
                    777:            }
                    778:            else if ( [kbdDevice desireOwnership:self] != IO_R_SUCCESS )
                    779:            {
                    780:                [super relinquishOwnership:client];
                    781:                r = IO_R_BUSY;
                    782:            }
                    783:        }
                    784:        [[self ownerLock] unlock];
                    785:        return r;
                    786: }
                    787: //
                    788: // END:                Implementation of EventSrcExported protocol
                    789: //
                    790: 
                    791: @end

unix.superglobalmegacorp.com

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