Annotation of kernel/bsd/dev/ppc/EventSrcPCPointer.m, revision 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:  * EventSrcPCPointer.m - PC Pointer EventSrc subclass implementation
        !            28:  *
        !            29:  * HISTORY
        !            30:  * 28 Aug 1992    Joe Pasqua
        !            31:  *      Created. 
        !            32:  * 11 April 1997  Simon Douglas
        !            33:  *      ADB version for PPC.
        !            34:  */
        !            35: 
        !            36: // TO DO:
        !            37: // * VBL sync'ing
        !            38: // * Real Mac scaling & acceleration & move to device
        !            39: // * Better FixDiv/Mul
        !            40: //
        !            41: // NOTES:
        !            42: // * The EventSrcExported protocol is implemented completely by our superclass.
        !            43: //   At this point there is no need for this subclass to override anything.
        !            44: // * In the current system the EventDriver instance is always the owner
        !            45: //   of this EventSrc.
        !            46: // * To find things that need to be fixed, search for FIX, to find questions
        !            47: //   to be resolved, search for ASK, to find stuff that still needs to be
        !            48: //   done, search for TO DO.
        !            49: //
        !            50: 
        !            51: #import <driverkit/generalFuncs.h>
        !            52: #import <machkit/NXLock.h>
        !            53: #import <bsd/dev/evsio.h>
        !            54: #import <bsd/dev/ppc/EventSrcPCPointer.h> 
        !            55: 
        !            56: #define MACSCALE       1
        !            57: 
        !            58: #if MACSCALE
        !            59: #define MAXMAG 128
        !            60: static int scaleValues[MAXMAG];
        !            61: static int fractX,fractY;
        !            62: #endif
        !            63: 
        !            64: #define        PC_PTR_DFLT_DELTA_T     2
        !            65: 
        !            66: // Default pointer acceleration or scaling table
        !            67: static const unsigned int dfltPointerScaling[] =
        !            68: {
        !            69:        2,      2,      // Threshold and scaling pairs
        !            70:        3,      3,
        !            71:        4,      5,
        !            72:        5,      7,
        !            73:        6,      10
        !            74: };
        !            75: 
        !            76: static EventSrcPCPointer *instance = (EventSrcPCPointer *)0;
        !            77: 
        !            78: @implementation EventSrcPCPointer: IOEventSource
        !            79: 
        !            80: int
        !            81: FixMul( int a, int b)
        !            82: {
        !            83:     union {
        !            84:            long long   result;
        !            85:            int         word[2];
        !            86:     } big;
        !            87: 
        !            88:     big.result = ((long long) a) * ((long long) b) * 65536;
        !            89:     return( big.word[0] );
        !            90: }
        !            91: 
        !            92: int
        !            93: FixDiv( int a, int b)
        !            94: {
        !            95:     return( (((long long) a) * 65536) / ((long long) b));
        !            96: }
        !            97: 
        !            98: 
        !            99: //
        !           100: // BEGIN:      Implementation of Private EventSrcPCPointer methods
        !           101: //
        !           102: - scalePointerInX:(int *)dxp
        !           103:     andY:(int *)dyp
        !           104:     over:(unsigned)dt
        !           105:     atRes:(unsigned)res
        !           106: // Description:        Perform pointer acceleration computations here.
        !           107: //             Given the resolution, dx, dy, and time, compute the velocity
        !           108: //             of the pointer over a Manhatten distance in inches/second.
        !           109: //             Using this velocity, do a lookup in the pointerScaling table
        !           110: //             to select a scaling factor. Scale dx and dy up as appropriate.
        !           111: // Preconditions:
        !           112: // *   deviceLock should be held on entry
        !           113: {
        !           114:     int dx, dy;
        !           115:     int absDx, absDy;
        !           116:     unsigned delta, velocity;
        !           117:     int index;
        !           118: 
        !           119:     dx = *dxp;
        !           120:     dy = *dyp;
        !           121:     absDx = (dx < 0) ? -dx : dx;
        !           122:     absDy = (dy < 0) ? -dy : dy;
        !           123: 
        !           124: #if MACSCALE
        !           125: 
        !           126: #if 1
        !           127:     if( absDx > absDy)
        !           128:        delta = (absDx + (absDy / 2));
        !           129:     else
        !           130:        delta = (absDy + (absDx / 2));
        !           131: #else
        !           132:     delta = absDx + absDy;
        !           133: #endif
        !           134: 
        !           135:     // scale
        !           136:     if( delta > (MAXMAG - 1))
        !           137:        delta = MAXMAG - 1;
        !           138:     dx = FixMul( dx << 16, scaleValues[delta]);
        !           139:     dy = FixMul( dy << 16, scaleValues[delta]);
        !           140: 
        !           141:     // if no direction changes add fract parts
        !           142:     if( (dx ^ fractX) >= 0)
        !           143:        dx += fractX;
        !           144:     if( (dy ^ fractY) >= 0)
        !           145:        dy += fractY;
        !           146: 
        !           147:     *dxp = dx / 65536;
        !           148:     *dyp = dy / 65536;
        !           149: 
        !           150:     // get fractional part with sign extend
        !           151:     if( dx >= 0)
        !           152:        fractX = dx & 0xffff;
        !           153:     else
        !           154:        fractX = dx | 0xffff0000;
        !           155:     if( dy >= 0)
        !           156:        fractY = dy & 0xffff;
        !           157:     else
        !           158:        fractY = dy | 0xffff0000;
        !           159: 
        !           160: #else
        !           161: 
        !           162:     // Take the sum of the X and Y distances as the delta to compute
        !           163:     // the velocity. (Manhatten distance)
        !           164:     delta = absDx + absDy;
        !           165:     if ( dt == 0 )
        !           166:            dt = PC_PTR_DFLT_DELTA_T;
        !           167:     //
        !           168:     // Velocity in IPS = (delta in Dots * ticks/sec)/(res in DPI * dT)
        !           169:     //
        !           170:     // This is a bit heavyweight, and could probably be approximated
        !           171:     // with considerable savings.
        !           172:     //
        !           173:     velocity =  (delta * EV_TICKS_PER_SEC) / (res * dt);
        !           174: 
        !           175:     // Look through the scalings for the first threshold greater than
        !           176:     // or equal to our velocity, and back off by one.
        !           177:     if ( velocity > pointerScaling.scaleThresholds[0] )
        !           178:     {
        !           179:        for ( index = 1; index < pointerScaling.numScaleLevels; ++index )
        !           180:        {
        !           181:            if ( velocity <= pointerScaling.scaleThresholds[index] )
        !           182:                break;
        !           183:        }
        !           184:        --index;        // Back off to get index covering our velocity.
        !           185:        *dxp = dx * pointerScaling.scaleFactors[index];
        !           186:        *dyp = dy * pointerScaling.scaleFactors[index];
        !           187:     }
        !           188: 
        !           189: #endif
        !           190: 
        !           191:     return self;
        !           192: }
        !           193: 
        !           194: IOReturn ReadNVRAM( unsigned int offset, unsigned int length, unsigned char * buffer );
        !           195: 
        !           196: - setPointerScaling:(unsigned)numScalings data:(unsigned const *)scaleData
        !           197: // Description:        Set the pointer scaling factors and thresholds from the int 
        !           198: //             array and count passed in here. There should be 2*numScaling
        !           199: //             ints in the scaleData array, packed with a threshold followed
        !           200: //             by a scaling factor.
        !           201: // Preconditions:
        !           202: // *   deviceLock must not be held on entry
        !           203: {
        !           204:     int i;
        !           205:     if ( numScalings > NX_MAXMOUSESCALINGS )
        !           206:        numScalings = NX_MAXMOUSESCALINGS;      // Clamp range
        !           207: 
        !           208:     [deviceLock lock];
        !           209: 
        !           210: #if MACSCALE
        !           211: // a pale imitation of CrsrDev.a
        !           212:     {
        !           213:        static int deviceSpeed[] = { 0x000000, 0x00713b, 0x010000, 0x044ec5, 0x0c0000, 0x16ec4f, 0x1d3b14, 0x227627, 0x7ffffff };
        !           214:        static int cursorSpeed[] = { 0x000000, 0x006000, 0x010000, 0x108000, 0x5f0000, 0x8b0000, 0x948000, 0x960000, 0x0960000 };
        !           215: 
        !           216:        int     slope,j = 0;
        !           217:        int     x;
        !           218:        int     devSpeed, crsrSpeed;
        !           219:        int     lastCrsrSpeed, nextCrsrSpeed;
        !           220:        int     lastDeviceSpeed, nextDeviceSpeed;
        !           221:        int     accl = 0x008000;
        !           222: 
        !           223: #if 0
        !           224:        static int pram2Fixed[] =  { 0x000000, 0x002000, 0x005000, 0x008000, 0x00b000, 0x00e000, 0x010000, 0x010000 };
        !           225:        unsigned char abyte;
        !           226:        if( 0 == ReadNVRAM( 0x1300 + 8, 1, &abyte )) {
        !           227:            abyte = 7 & (abyte >> 3);
        !           228:            accl = pram2Fixed[ abyte ];
        !           229:        }
        !           230: #else
        !           231:        int nxMax = (*(scaleData + (2 * numScalings) - 1)) - 1;
        !           232:        if( nxMax > 18)
        !           233:            nxMax = 18;
        !           234:        accl = FixDiv( nxMax << 16, 18 << 16 );
        !           235: #endif
        !           236: kprintf( "Mouse acceleration = 0x%x\n", accl);
        !           237: 
        !           238:        // scale for device speed
        !           239:        devSpeed = FixDiv( 90 << 16, resolution << 16 );                        // no vbl sync, so 90 autopolls /s
        !           240:        // scale for cursor speed
        !           241:        crsrSpeed = FixDiv( 72 << 16, resolution << 16 );                       // screen is 72 dpi
        !           242: 
        !           243:        nextCrsrSpeed = 0;
        !           244:        nextDeviceSpeed = 0;
        !           245: 
        !           246:        // Precalculate fixed point scales. Not as accurate as MacOS, but no FixDiv() in handler
        !           247:        for ( i = 1; i < MAXMAG; i++ )
        !           248:        {
        !           249:            x = FixMul( i << 16, devSpeed );
        !           250:            if( x > deviceSpeed[j]) {
        !           251:                lastCrsrSpeed = nextCrsrSpeed;
        !           252:                lastDeviceSpeed = nextDeviceSpeed;
        !           253:                j++;
        !           254:                nextDeviceSpeed = deviceSpeed[j];
        !           255:                // Interpolate by accl between y=x and y=acclTable(x) to get nextCrsrSpeed
        !           256:                {
        !           257:                    int factorCursor;
        !           258:                    int factorDevice;
        !           259:                    if( cursorSpeed[j] < nextDeviceSpeed) {
        !           260:                        factorDevice = accl;
        !           261:                        factorCursor = (0x10000 - accl);
        !           262:                    } else {
        !           263:                        factorCursor = accl;
        !           264:                        factorDevice = (0x10000 - accl);
        !           265:                    }
        !           266:                    nextCrsrSpeed = FixMul( factorCursor, cursorSpeed[j] ) + FixMul( factorDevice, nextDeviceSpeed);
        !           267:                }
        !           268:                slope = FixDiv( nextCrsrSpeed - lastCrsrSpeed, nextDeviceSpeed - lastDeviceSpeed );
        !           269:            }
        !           270:            scaleValues[i] = FixDiv( FixMul( crsrSpeed, FixMul( slope, x - lastDeviceSpeed ) + lastCrsrSpeed), x);
        !           271:        }
        !           272:        scaleValues[0] = scaleValues[1];
        !           273:        fractX = fractY = 0;
        !           274:     }
        !           275: #endif
        !           276: 
        !           277:     pointerScaling.numScaleLevels = numScalings;
        !           278:     for ( i = 0; i < numScalings; ++i )
        !           279:     {
        !           280:        pointerScaling.scaleThresholds[i] = *scaleData++;
        !           281:        pointerScaling.scaleFactors[i] = *scaleData++;
        !           282:     }
        !           283: 
        !           284:     [deviceLock unlock];
        !           285:     return self;
        !           286: }
        !           287: 
        !           288: - pointerScaling:(unsigned *)numScalings data:(unsigned *)scaleData
        !           289: // Description:        Return the pointer scaling factors and thresholds using the int 
        !           290: //             array and count passed in here. On entry, *numScalings should
        !           291: //             reflect the max number of scaling entries scaleData can hold.
        !           292: {
        !           293:     int i;
        !           294: 
        !           295:     [deviceLock lock];
        !           296:     if ( *numScalings > pointerScaling.numScaleLevels )
        !           297:        *numScalings = pointerScaling.numScaleLevels;   // Clamp range
        !           298: 
        !           299:     for ( i = 0; i < *numScalings; ++i )
        !           300:     {
        !           301:        *scaleData++ = pointerScaling.scaleThresholds[i];
        !           302:        *scaleData++ = pointerScaling.scaleFactors[i];
        !           303:     }
        !           304:     [deviceLock unlock];
        !           305:     return self;
        !           306: }
        !           307: 
        !           308: - initPointer
        !           309: // Description:        Perform setup work needed to find and configure our
        !           310: //             PCPointer device. We have to tell it to send events to us.
        !           311: // Preconditions:
        !           312: // *   deviceLock must be held on entry
        !           313: {
        !           314:     if ((pointerDevice = [PCPointer activePointerDevice]) == nil) {
        !           315:        IOLog("initPointer: Can't find active pointer device\n");
        !           316:        return nil;
        !           317:     }
        !           318:     if ( [pointerDevice respondsTo:@selector(setEventTarget:)] )
        !           319:        [pointerDevice setEventTarget: self];
        !           320:     else {
        !           321:        IOLog("initPointer: PCPointer0 does not respond to setEventTarget:\n");
        !           322:        return nil;
        !           323:     }
        !           324:     [pointerDevice setEventTarget: self];
        !           325:     return self;
        !           326: }
        !           327: 
        !           328: - resetPointer
        !           329: {
        !           330:     [deviceLock lock];
        !           331:     buttonMode = NX_OneButton;
        !           332:     [deviceLock unlock];
        !           333:     // setPointerScaling will try to acquire deviceLock, so release it first.
        !           334:     [self setPointerScaling:
        !           335:        ((sizeof dfltPointerScaling/sizeof dfltPointerScaling[0])/2)
        !           336:        data:dfltPointerScaling];
        !           337:     return self;
        !           338: }
        !           339: //
        !           340: // END:                Implementation of Private EventSrcPCPointer methods
        !           341: //
        !           342: 
        !           343: 
        !           344: //
        !           345: // BEGIN:      Implementation of PCPointerTarget protocol
        !           346: //
        !           347: - (void)dispatchPointerEvent:(PointerEvent *)event
        !           348: // Description:        This method is the heart of event dispatching. The underlying
        !           349: //             PCPointer object invokes this method with each event.
        !           350: //             The event structure passed in by reference should not be freed.
        !           351: {
        !           352:     int buttons;
        !           353:     int dx;
        !           354:     int dy;
        !           355:     unsigned tick;
        !           356:     unsigned delta_t;
        !           357:     int menuButton;
        !           358: 
        !           359:     [deviceLock lock];
        !           360: 
        !           361:     menuButton = (event->buttonCount > 1);
        !           362:     buttons = 0;
        !           363: 
        !           364:     if (event->b0 == 0)
        !           365:         buttons |= EV_LB;
        !           366: 
        !           367:     if( menuButton) {
        !           368:        if ((event->b1 || event->b2 || event->b3) == 0)         // either down
        !           369:            buttons |= EV_RB;
        !           370:     }
        !           371: 
        !           372:     dx = event->dx;
        !           373:     dy = event->dy;
        !           374: 
        !           375:     // Convert the nanosecond time into a tick time since boot.
        !           376:     tick = EV_NS_TO_TICK(event->timeStamp);
        !           377: 
        !           378:     // Perform pointer acceleration computations
        !           379:     if ( lastPointerEvent == 0 )
        !           380:        delta_t = PC_PTR_DFLT_DELTA_T;
        !           381:     else
        !           382:        delta_t = tick - lastPointerEvent;
        !           383: 
        !           384:     [self scalePointerInX:&dx
        !           385:        andY:&dy
        !           386:        over:delta_t
        !           387:        atRes:resolution];
        !           388:     lastPointerEvent = tick;
        !           389: 
        !           390:     // Perform button tying and mapping.  This
        !           391:     // stuff applies to relative posn devices (mice) only.
        !           392:     if ( buttonMode == NX_OneButton )
        !           393:     {
        !           394:        if ( (buttons & (EV_LB|EV_RB)) != 0 )
        !           395:            buttons = EV_LB;
        !           396:     }
        !           397:     else if ( menuButton && (buttonMode == NX_LeftButton) )    // Menus on left button. Swap!
        !           398:     {
        !           399:        int temp = 0;
        !           400:        if ( buttons & EV_LB )
        !           401:            temp = EV_RB;
        !           402:        if ( buttons & EV_RB )
        !           403:            temp |= EV_LB;
        !           404:        buttons = temp;
        !           405:     }
        !           406:     [deviceLock unlock];
        !           407: 
        !           408:     [[self owner] relativePointerEvent:buttons
        !           409:        deltaX:dx
        !           410:        deltaY:dy
        !           411:        atTime:event->timeStamp];
        !           412: }
        !           413: //
        !           414: // END:                Implementation of PCPointerTarget protocol
        !           415: //
        !           416: 
        !           417: 
        !           418: //
        !           419: // BEGIN:      Implementation of Exported EventSrcPCPointer methods
        !           420: //
        !           421: - init
        !           422: // Description:        Basic initialization stuff.
        !           423: // Preconditions:
        !           424: // *   deviceLock must not be held on entry
        !           425: {
        !           426:     id rtn;
        !           427: 
        !           428:     if ( deviceLock == nil )
        !           429:            deviceLock = [NXLock new];
        !           430:     [deviceLock lock];
        !           431:     [super init];
        !           432:     pointerDevice = nil;
        !           433:     buttonMode = NX_OneButton;
        !           434: 
        !           435:     rtn = [self initPointer];
        !           436:     resolution = [pointerDevice getResolution];
        !           437: 
        !           438:     [deviceLock unlock];
        !           439:     // setPointerScaling will try to acquire deviceLock, so release it first.
        !           440:     [self setPointerScaling:
        !           441:        ((sizeof dfltPointerScaling/sizeof dfltPointerScaling[0])/2)
        !           442:        data:dfltPointerScaling];
        !           443:     return rtn;
        !           444: }
        !           445: 
        !           446: + probe
        !           447: // Description:        This is our factory method. It is the IODevice probe
        !           448: //             routine for psuedo drivers.
        !           449: {
        !           450:     if ( instance != nil )
        !           451:        return instance;
        !           452: 
        !           453:     instance = [self alloc];
        !           454: 
        !           455:     [instance setName:"EventSrcPCPointer0"];
        !           456:     [instance setDeviceKind:"EventSrcPCPointer"];
        !           457:     
        !           458:     if ( [instance init] == nil )
        !           459:        [instance free];        // Zaps 'instance' on the way out
        !           460: 
        !           461:     return instance;
        !           462: }
        !           463: 
        !           464: - free
        !           465: // Description:        Go Away. Be careful when freeing the lock.
        !           466: {
        !           467:     id lock;
        !           468: 
        !           469:     [deviceLock lock];
        !           470:     instance = nil;
        !           471:     lock = deviceLock;
        !           472:     deviceLock = nil;
        !           473:     // Release pointer device, so we won't get any more events
        !           474:     if ( pointerDevice != nil )
        !           475:        [pointerDevice setEventTarget:nil];
        !           476:     [lock unlock];
        !           477:     [lock free];
        !           478:     return [super free];
        !           479: }
        !           480: 
        !           481: 
        !           482: - (IOReturn)getIntValues:(unsigned *)parameterArray
        !           483:        forParameter:(IOParameterName)parameterName
        !           484:        count:(unsigned int *)count
        !           485: {
        !           486:     IOReturn r = IO_R_INVALID_ARG;
        !           487:     NXEventSystemDevice *dp;
        !           488:     unsigned maxCount = *count;
        !           489:     unsigned *returnedCount = count;
        !           490:     
        !           491:     if ( strcmp( parameterName, EVSIOCMS ) == 0 )      // Pointer Scaling
        !           492:     {
        !           493:        parameterArray[EVSIOSMS_NSCALINGS] = (maxCount - 1)/2;
        !           494:        [self pointerScaling:&parameterArray[EVSIOSMS_NSCALINGS]
        !           495:            data:&parameterArray[EVSIOSMS_DATA]];
        !           496:        *returnedCount = (parameterArray[EVSIOSMS_NSCALINGS] * 2) + 1;
        !           497:        r = IO_R_SUCCESS;
        !           498:     }
        !           499:     else if ( strcmp( parameterName, EVSIOCMH ) == 0 ) // Pointer Handedness
        !           500:     {
        !           501:        if ( maxCount >= EVSIOCMH_SIZE )
        !           502:        {
        !           503:            *returnedCount = EVSIOCMH_SIZE;
        !           504:            [deviceLock lock];
        !           505:            parameterArray[0] = buttonMode;
        !           506:            [deviceLock unlock];
        !           507:            r = IO_R_SUCCESS;
        !           508:        }
        !           509:     }
        !           510:     else if ( strcmp( parameterName, EVSIOINFO ) == 0 )        // Device info
        !           511:     {
        !           512:        dp = (NXEventSystemDevice *) &parameterArray[0];
        !           513:        *returnedCount = 0;
        !           514:        // No need to lock device since we're not even reading the structure.
        !           515:        dp->interface = NX_EVS_DEVICE_INTERFACE_SERIAL_ACE;
        !           516:        dp->dev_type = NX_EVS_DEVICE_TYPE_MOUSE;
        !           517:        dp->interface_addr = 0;
        !           518:        dp->id = 0;
        !           519:        *returnedCount = sizeof (NXEventSystemDevice) / sizeof (int);
        !           520:        r = IO_R_SUCCESS;
        !           521:     }
        !           522:     else
        !           523:     {
        !           524:        r = [super getIntValues:parameterArray
        !           525:                   forParameter: parameterName
        !           526:                   count : count];
        !           527:        if (r == IO_R_UNSUPPORTED)
        !           528:            r = IO_R_INVALID_ARG;
        !           529:     }
        !           530:     return r;
        !           531: }
        !           532: 
        !           533: - (IOReturn)getCharValues:(unsigned char *)parameterArray
        !           534:        forParameter:(IOParameterName)parameterName
        !           535:        count:(unsigned int *)count
        !           536: {
        !           537:     return IO_R_INVALID_ARG;
        !           538: }
        !           539: 
        !           540: - (IOReturn)setIntValues:(unsigned *)parameterArray
        !           541:        forParameter:(IOParameterName)parameterName
        !           542:        count:(unsigned int)count
        !           543: {
        !           544:     IOReturn r = IO_R_INVALID_ARG;
        !           545:     int cnt;
        !           546: 
        !           547:     if ( strcmp( parameterName, EVSIOSMS ) == 0 )      // Pointer Scaling
        !           548:     {
        !           549:        cnt = (parameterArray[EVSIOSMS_NSCALINGS] * 2) + 1;
        !           550:        if ( count <= EVSIOSMS_SIZE && cnt <= count )
        !           551:        {
        !           552:            [self setPointerScaling:parameterArray[EVSIOSMS_NSCALINGS]
        !           553:                data:&parameterArray[EVSIOSMS_DATA]];
        !           554:            r = IO_R_SUCCESS;
        !           555:        }
        !           556:     }
        !           557:     else if ( strcmp( parameterName, EVSIOSMH ) == 0 ) // Pointer Handedness
        !           558:     {
        !           559:        if ( count == EVSIOSMH_SIZE )
        !           560:        {
        !           561:            [deviceLock lock];
        !           562:            buttonMode = parameterArray[0];
        !           563:            [deviceLock unlock];
        !           564:            r = IO_R_SUCCESS;
        !           565:        }
        !           566:     }
        !           567:     else if ( strcmp( parameterName, EVSIORMS ) == 0 )
        !           568:     {
        !           569:        r = IO_R_SUCCESS;
        !           570:     }
        !           571:     else
        !           572:     {
        !           573:        r = [super setIntValues:parameterArray
        !           574:                   forParameter:parameterName
        !           575:                   count : count];
        !           576:        if (r == IO_R_UNSUPPORTED)
        !           577:            r = IO_R_INVALID_ARG;
        !           578:     }
        !           579:     return r;
        !           580: }
        !           581: //
        !           582: // END:                Implementation of Exported EventSrcPCPointer methods
        !           583: //
        !           584: @end

unix.superglobalmegacorp.com

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