Annotation of XNU/iokit/Families/IOHIDSystem/IOHIPointing.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * 17 July 1998 sdouglas
                     24:  */
                     25: 
                     26: #include <IOKit/IOLib.h>
                     27: #include <IOKit/assert.h>
                     28: #include <IOKit/hidsystem/IOHIPointing.h>
                     29: #include <IOKit/hidsystem/IOHIDParameter.h>
                     30: 
                     31: #ifndef abs
                     32: #define abs(_a)        ((_a >= 0) ? _a : -_a)
                     33: #endif
                     34: 
                     35: #define super IOHIDevice
                     36: OSDefineMetaClassAndStructors(IOHIPointing, IOHIDevice);
                     37: 
                     38: bool IOHIPointing::init(OSDictionary * properties)
                     39: {
                     40:   if (!super::init(properties))  return false;
                     41: 
                     42:   /*
                     43:    * Initialize minimal state.
                     44:    */
                     45: 
                     46:   _fractX      = 0;
                     47:   _fractY      = 0;
                     48:   _acceleration        = -1;
                     49:   _convertAbsoluteToRelative = false;
                     50:   _contactToMove = false;
                     51:   _hadContact = false;
                     52:   _pressureThresholdToClick = 128;
                     53:   _previousLocation.x = 0;
                     54:   _previousLocation.y = 0;
                     55: 
                     56:   _deviceLock = IOLockAlloc();
                     57: 
                     58:   if (!_deviceLock)  return false;
                     59: 
                     60:   IOLockInit(_deviceLock);
                     61: 
                     62:   return true;
                     63: }
                     64: 
                     65: bool IOHIPointing::start(IOService * provider)
                     66: {
                     67:   if (!super::start(provider))  return false;
                     68: 
                     69:   /*
                     70:    * IOHIPointing serves both as a service and a nub (we lead a double
                     71:    * life).  Register ourselves as a nub to kick off matching.
                     72:    */
                     73: 
                     74:   registerService();
                     75: 
                     76:   return true;
                     77: }
                     78: 
                     79: void IOHIPointing::free()
                     80: // Description:        Go Away. Be careful when freeing the lock.
                     81: {
                     82:     if (_deviceLock)
                     83:     {
                     84:        IOLock * lock;
                     85: 
                     86:        IOTakeLock(_deviceLock);
                     87: 
                     88:        lock = _deviceLock;
                     89:        _deviceLock = NULL;
                     90: 
                     91:        IOUnlock(lock);
                     92:        IOLockFree(lock);
                     93:     }
                     94:     super::free();
                     95: }
                     96: 
                     97: bool IOHIPointing::open(IOService *                client,
                     98:                        IOOptionBits               options,
                     99:                         RelativePointerEventAction rpeAction,
                    100:                         AbsolutePointerEventAction apeAction,
                    101:                         ScrollWheelEventAction     sweAction)
                    102: {
                    103:   if ( (-1 == _acceleration) && (!resetPointer()))  return false;
                    104: 
                    105:   if (super::open(client, options))
                    106:   {
                    107:     // Note: client object is already retained by superclass' open()
                    108:     _relativePointerEventTarget = client;
                    109:     _relativePointerEventAction = rpeAction;
                    110:     _absolutePointerEventTarget = client;
                    111:     _absolutePointerEventAction = apeAction;
                    112:     _scrollWheelEventTarget = client;
                    113:     _scrollWheelEventAction = sweAction;
                    114:     return true;
                    115:   }
                    116: 
                    117:   return false;
                    118: }
                    119: 
                    120: void IOHIPointing::close(IOService * client, IOOptionBits)
                    121: {
                    122:   _relativePointerEventAction = NULL;
                    123:   _relativePointerEventTarget = 0;
                    124:   _absolutePointerEventAction = NULL;
                    125:   _absolutePointerEventTarget = 0;
                    126: 
                    127:   super::close(client);
                    128: } 
                    129: 
                    130: IOHIDKind IOHIPointing::hidKind()
                    131: {
                    132:   return kHIRelativePointingDevice;
                    133: }
                    134: 
                    135: void IOHIPointing::scalePointer(int * dxp, int * dyp)
                    136: // Description:        Perform pointer acceleration computations here.
                    137: //             Given the resolution, dx, dy, and time, compute the velocity
                    138: //             of the pointer over a Manhatten distance in inches/second.
                    139: //             Using this velocity, do a lookup in the pointerScaling table
                    140: //             to select a scaling factor. Scale dx and dy up as appropriate.
                    141: // Preconditions:
                    142: // *   _deviceLock should be held on entry
                    143: {
                    144:     int dx, dy;
                    145:     int absDx, absDy;
                    146:     unsigned delta;
                    147: 
                    148:     dx = *dxp;
                    149:     dy = *dyp;
                    150:     absDx = (dx < 0) ? -dx : dx;
                    151:     absDy = (dy < 0) ? -dy : dy;
                    152: 
                    153: #if 1
                    154:     if( absDx > absDy)
                    155:        delta = (absDx + (absDy / 2));
                    156:     else
                    157:        delta = (absDy + (absDx / 2));
                    158: #else
                    159:     delta = absDx + absDy;
                    160: #endif
                    161: 
                    162:     // scale
                    163:     if( delta > (MAXMAG - 1))
                    164:        delta = MAXMAG - 1;
                    165:     dx = IOFixedMultiply( dx << 16, _scaleValues[delta]);
                    166:     dy = IOFixedMultiply( dy << 16, _scaleValues[delta]);
                    167: 
                    168:     // if no direction changes add fract parts
                    169:     if( (dx ^ _fractX) >= 0)
                    170:        dx += _fractX;
                    171:     if( (dy ^ _fractY) >= 0)
                    172:        dy += _fractY;
                    173: 
                    174:     *dxp = dx / 65536;
                    175:     *dyp = dy / 65536;
                    176: 
                    177:     // get fractional part with sign extend
                    178:     if( dx >= 0)
                    179:        _fractX = dx & 0xffff;
                    180:     else
                    181:        _fractX = dx | 0xffff0000;
                    182:     if( dy >= 0)
                    183:        _fractY = dy & 0xffff;
                    184:     else
                    185:        _fractY = dy | 0xffff0000;
                    186: }
                    187: 
                    188: 
                    189: void IOHIPointing::setupForAcceleration(IOFixed accl)
                    190: {
                    191:     int                                slope = 0, i, j = 0;
                    192:     int                                x;
                    193:     int                        devSpeed, crsrSpeed;
                    194:     int                        lastCrsrSpeed = 0, nextCrsrSpeed;
                    195:     int                        lastDeviceSpeed = 0, nextDeviceSpeed;
                    196:     IOHIAccelerationPoint *    table;
                    197:     IOItemCount                        numEntries;
                    198:     IOFixed                     res = resolution();
                    199: 
                    200:     assert(res);
                    201: 
                    202:     accelerationTable(&table, &numEntries);
                    203: 
                    204:     if( accl > (1 << 16))
                    205:        accl = (1 << 16);
                    206: 
                    207:     // scale for device speed
                    208:     // no vbl sync, so 90 autopolls /s
                    209:     devSpeed = IOFixedDivide( 90 << 16, res );
                    210:     // scale for cursor speed
                    211:     // screen is assumed 72 dpi, like MacOS
                    212:     crsrSpeed = IOFixedDivide( 72 << 16, res );
                    213: 
                    214:     nextCrsrSpeed = 0;
                    215:     nextDeviceSpeed = 0;
                    216: 
                    217:     // Precalculate fixed point scales. Not as accurate as MacOS,
                    218:     // but no IOFixedDivide() in handler
                    219:     for ( i = 1; i < MAXMAG; i++ )
                    220:     {
                    221:         x = IOFixedMultiply( i << 16, devSpeed );
                    222:         if( x > table[j].deviceSpeed) {
                    223:             lastCrsrSpeed = nextCrsrSpeed;
                    224:             lastDeviceSpeed = nextDeviceSpeed;
                    225:             j++;
                    226:             nextDeviceSpeed = table[j].deviceSpeed;
                    227:             // Interpolate by accl between y=x and y=acclTable(x)
                    228:            //  to get nextCrsrSpeed
                    229:             {
                    230:                 int factorCursor;
                    231:                 int factorDevice;
                    232:                 if( table[j].cursorSpeed < nextDeviceSpeed) {
                    233:                     factorDevice = accl;
                    234:                     factorCursor = (0x10000 - accl);
                    235:                 } else {
                    236:                     factorCursor = accl;
                    237:                     factorDevice = (0x10000 - accl);
                    238:                 }
                    239:                 nextCrsrSpeed = IOFixedMultiply( factorCursor, table[j].cursorSpeed)
                    240:                              + IOFixedMultiply( factorDevice, nextDeviceSpeed);
                    241:             }
                    242:             slope = IOFixedDivide( nextCrsrSpeed - lastCrsrSpeed,
                    243:                        nextDeviceSpeed - lastDeviceSpeed);
                    244:         }
                    245:         _scaleValues[i] = IOFixedDivide( IOFixedMultiply( crsrSpeed,
                    246:                     IOFixedMultiply( slope, x - lastDeviceSpeed ) + lastCrsrSpeed), x);
                    247:     }
                    248:     _scaleValues[0] = _scaleValues[1];
                    249:     _fractX = _fractY = 0;
                    250:     _acceleration = accl;
                    251: }
                    252: 
                    253: bool IOHIPointing::resetPointer()
                    254: {
                    255:     IOTakeLock( _deviceLock);
                    256: 
                    257:     _buttonMode = NX_OneButton;
                    258: 
                    259:     setupForAcceleration(0x8000);
                    260:     updateProperties();
                    261: 
                    262:     IOUnlock( _deviceLock);
                    263:     return true;
                    264: }
                    265: 
                    266: void IOHIPointing::dispatchAbsolutePointerEvent(Point *                newLoc,
                    267:                                                 Bounds *       bounds,
                    268:                                                 UInt32         buttonState,
                    269:                                                 bool           proximity,
                    270:                                                 int            pressure,
                    271:                                                 int            pressureMin,
                    272:                                                 int            pressureMax,
                    273:                                                 int            stylusAngle,
                    274:                                                 AbsoluteTime   ts)
                    275: {
                    276:     int buttons = 0;
                    277:     int dx, dy;
                    278:     
                    279:     IOTakeLock(_deviceLock);
                    280: 
                    281:     if (buttonState & 1) {
                    282:         buttons |= EV_LB;
                    283:     }
                    284: 
                    285:     if (buttonCount() > 1) {
                    286:         if (buttonState & -2) {        // any other buttons
                    287:             buttons |= EV_RB;
                    288:         }
                    289:     }
                    290: 
                    291:     if ((_pressureThresholdToClick < 255) && ((pressure - pressureMin) > ((pressureMax - pressureMin) * _pressureThresholdToClick / 256))) {
                    292:         buttons |= EV_LB;
                    293:     }
                    294: 
                    295:     if (_buttonMode == NX_OneButton) {
                    296:         if ((buttons & (EV_LB|EV_RB)) != 0) {
                    297:             buttons = EV_LB;
                    298:         }
                    299:     }
                    300: 
                    301:     if (_convertAbsoluteToRelative) {
                    302:         dx = newLoc->x - _previousLocation.x;
                    303:         dy = newLoc->y - _previousLocation.y;
                    304:         
                    305:         if ((_contactToMove && !_hadContact && (pressure > pressureMin)) || (abs(dx) > ((bounds->maxx - bounds->minx) / 20)) || (abs(dy) > ((bounds->maxy - bounds->miny) / 20))) {
                    306:             dx = 0;
                    307:             dy = 0;
                    308:         } else {
                    309:             scalePointer(&dx, &dy);
                    310:         }
                    311:         
                    312:         _previousLocation.x = newLoc->x;
                    313:         _previousLocation.y = newLoc->y;
                    314:     }
                    315: 
                    316:     IOUnlock(_deviceLock);
                    317: 
                    318:     _hadContact = (pressure > pressureMin);
                    319: 
                    320:     if (!_contactToMove || (pressure > pressureMin)) {
                    321:         pressure -= pressureMin;
                    322:         if (pressure > 255) {
                    323:             pressure = 255;
                    324:         }
                    325:         if (_convertAbsoluteToRelative) {
                    326:             if (_relativePointerEventAction && _relativePointerEventTarget) {
                    327:                 (*_relativePointerEventAction)(_relativePointerEventTarget,
                    328:                                               buttons,
                    329:                                               dx,
                    330:                                               dy,
                    331:                                               ts);
                    332:             }
                    333:         } else {
                    334:             if (_absolutePointerEventAction && _absolutePointerEventTarget) {
                    335:                 (*_absolutePointerEventAction)(_absolutePointerEventTarget,
                    336:                                               buttons,
                    337:                                               newLoc,
                    338:                                               bounds,
                    339:                                               proximity,
                    340:                                               pressure,
                    341:                                               stylusAngle,
                    342:                                               ts);
                    343:             }
                    344:         }
                    345:     }
                    346: 
                    347:     return;
                    348: }
                    349: 
                    350: void IOHIPointing::dispatchRelativePointerEvent(int        dx,
                    351:                                                 int        dy,
                    352:                                                 UInt32     buttonState,
                    353:                                                 AbsoluteTime ts)
                    354: {
                    355:     int buttons;
                    356: 
                    357:     IOTakeLock( _deviceLock);
                    358: 
                    359:     buttons = 0;
                    360: 
                    361:     if( buttonState & 1)
                    362:         buttons |= EV_LB;
                    363: 
                    364:     if( buttonCount() > 1) {
                    365:        if( buttonState & -2)   // any others down
                    366:            buttons |= EV_RB;
                    367:     }
                    368: 
                    369:     // Perform pointer acceleration computations
                    370:     scalePointer(&dx, &dy);
                    371: 
                    372:     // Perform button tying and mapping.  This
                    373:     // stuff applies to relative posn devices (mice) only.
                    374:     if ( _buttonMode == NX_OneButton )
                    375:     {
                    376:        if ( (buttons & (EV_LB|EV_RB)) != 0 )
                    377:            buttons = EV_LB;
                    378:     }
                    379:     else if ( (buttonCount() > 1) && (_buttonMode == NX_LeftButton) )  
                    380:     // Menus on left button. Swap!
                    381:     {
                    382:        int temp = 0;
                    383:        if ( buttons & EV_LB )
                    384:            temp = EV_RB;
                    385:        if ( buttons & EV_RB )
                    386:            temp |= EV_LB;
                    387:        buttons = temp;
                    388:     }
                    389:     IOUnlock( _deviceLock);
                    390: 
                    391:     if (_relativePointerEventAction)          /* upstream call */
                    392:     {
                    393:       (*_relativePointerEventAction)(_relativePointerEventTarget,
                    394:                        /* buttons */ buttons,
                    395:                        /* deltaX */  dx,
                    396:                        /* deltaY */  dy,
                    397:                        /* atTime */  ts);
                    398:     }
                    399: }
                    400: 
                    401: void IOHIPointing::dispatchScrollWheelEvent(short deltaAxis1,
                    402:                                             short deltaAxis2,
                    403:                                             short deltaAxis3,
                    404:                                             AbsoluteTime ts)
                    405: {
                    406:     if (_scrollWheelEventAction) {
                    407:         (*_scrollWheelEventAction)(_scrollWheelEventTarget,
                    408:                                    deltaAxis1,
                    409:                                    deltaAxis2,
                    410:                                    deltaAxis3,
                    411:                                    ts);
                    412:     }
                    413: }
                    414: 
                    415: bool IOHIPointing::updateProperties( void )
                    416: {
                    417:     bool       ok;
                    418:     UInt32     res = resolution();
                    419: 
                    420:     ok = setProperty( kIOHIDPointerResolutionKey, &res, sizeof( res))
                    421:     &    setProperty( kIOHIDPointerAccelerationKey, &_acceleration,
                    422:                         sizeof( _acceleration))
                    423:     &    setProperty( kIOHIDPointerConvertAbsoluteKey, &_convertAbsoluteToRelative,
                    424:                         sizeof( _convertAbsoluteToRelative))
                    425:     &    setProperty( kIOHIDPointerContactToMoveKey, &_contactToMove,
                    426:                         sizeof( _contactToMove));
                    427: 
                    428:     return( ok & super::updateProperties() );
                    429: }
                    430: 
                    431: IOReturn IOHIPointing::setParamProperties( OSDictionary * dict )
                    432: {
                    433:     OSData *   data;
                    434:     IOReturn   err = kIOReturnSuccess;
                    435:     bool       updated = false;
                    436:     UInt8 *    bytes;
                    437: 
                    438:     IOTakeLock( _deviceLock);
                    439:     if( (data = OSDynamicCast( OSData,
                    440:                dict->getObject(kIOHIDPointerAccelerationKey)))) {
                    441: 
                    442:        setupForAcceleration( *((IOFixed *)data->getBytesNoCopy()) );
                    443:        updated = true;
                    444:     }
                    445:     IOUnlock( _deviceLock);
                    446: 
                    447:     if( dict->getObject(kIOHIDResetPointerKey))
                    448:        resetPointer();
                    449: 
                    450:     if ((data = OSDynamicCast(OSData,
                    451:                               dict->getObject(kIOHIDPointerConvertAbsoluteKey)))) {
                    452:         bytes = (UInt8 *) data->getBytesNoCopy();
                    453:         _convertAbsoluteToRelative = (bytes[0] != 0) ? true : false;
                    454:         updated = true;
                    455:     }
                    456: 
                    457:     if ((data = OSDynamicCast(OSData,
                    458:                               dict->getObject(kIOHIDPointerContactToMoveKey)))) {
                    459:         bytes = (UInt8 *) data->getBytesNoCopy();
                    460:         _contactToMove = (bytes[0] != 0) ? true : false;
                    461:         updated = true;
                    462:     }
                    463: 
                    464:     if( updated )
                    465:         updateProperties();
                    466: 
                    467:     return( err );
                    468: }
                    469: 
                    470: // subclasses override
                    471: 
                    472: IOItemCount IOHIPointing::buttonCount()
                    473: {
                    474:     return (1);
                    475: }
                    476: 
                    477: IOFixed IOHIPointing::resolution()
                    478: {
                    479:     return (100 << 16);
                    480: }
                    481: 
                    482: void IOHIPointing::accelerationTable(IOHIAccelerationPoint ** table,
                    483:                                     IOItemCount * numEntries)
                    484: {
                    485:     static IOHIAccelerationPoint defaultTable[] = {
                    486:        { 0x000000, 0x000000 },
                    487:        { 0x7ffffff, 0x0960000 }
                    488:     };
                    489: 
                    490:     *table = defaultTable;
                    491:     *numEntries = sizeof( defaultTable) / sizeof( defaultTable[0]);
                    492: }

unix.superglobalmegacorp.com

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