Annotation of XNU/iokit/Families/IOHIDSystem/IOHIDSystem.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: /*     Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved. 
                     23:  *
                     24:  * EventDriver.m - Event System module, ObjC implementation.
                     25:  *
                     26:  *             The EventDriver is a pseudo-device driver.
                     27:  *
                     28:  * HISTORY
                     29:  * 31-Mar-92    Mike Paquette at NeXT 
                     30:  *      Created. 
                     31:  * 4  Aug 1993   Erik Kay at NeXT
                     32:  *     minor API cleanup
                     33:  */
                     34: 
                     35: #include <IOKit/system.h>
                     36: #include <IOKit/assert.h>
                     37: 
                     38: #include <libkern/c++/OSContainers.h>
                     39: #include <libkern/c++/OSCollectionIterator.h>
                     40: #include <IOKit/IOTimerEventSource.h>
                     41: #include <IOKit/IOCommandQueue.h>
                     42: #include <IOKit/IOMessage.h>
                     43: #include <IOKit/IOWorkLoop.h>
                     44: #include <IOKit/hidsystem/IOHIDevice.h>
                     45: #include <IOKit/hidsystem/IOHIDShared.h>
                     46: #include <IOKit/hidsystem/IOHIDSystem.h>
                     47: #include <IOKit/hidsystem/IOHIKeyboard.h>
                     48: #include <IOKit/hidsystem/IOHIPointing.h>
                     49: #include <IOKit/hidsystem/IOHIDParameter.h>
                     50: #include <IOKit/audio/IOAudioManager.h>
                     51: 
                     52: #include <IOKit/hidsystem/ev_private.h>        /* Per-machine configuration info */ 
                     53: #include "IOHIDUserClient.h"
                     54: 
                     55: bool displayWranglerUp( OSObject *, void *, IOService * );
                     56: 
                     57: static IOHIDSystem * evInstance = 0;
                     58: 
                     59: 
                     60: #define xpr_ev_cursor(x, a, b, c, d, e)
                     61: #define PtInRect(ptp,rp) \
                     62:        ((ptp)->x >= (rp)->minx && (ptp)->x <  (rp)->maxx && \
                     63:        (ptp)->y >= (rp)->miny && (ptp)->y <  (rp)->maxy)
                     64: 
                     65: 
                     66: 
                     67: static inline unsigned AbsoluteTimeToTick( AbsoluteTime * ts )
                     68: {
                     69:     UInt64     nano;
                     70:     absolutetime_to_nanoseconds(*ts, &nano);
                     71:     return( nano >> 24 );
                     72: }
                     73: 
                     74: static inline void TickToAbsoluteTime( unsigned tick, AbsoluteTime * ts )
                     75: {
                     76:     UInt64     nano = ((UInt64) tick) << 24;
                     77:     nanoseconds_to_absolutetime(nano, ts);
                     78: }
                     79: 
                     80: #define EV_NS_TO_TICK(ns)      AbsoluteTimeToTick(ns)
                     81: #define EV_TICK_TO_NS(tick,ns) TickToAbsoluteTime(tick,ns)
                     82: 
                     83: 
                     84: #define super IOService
                     85: OSDefineMetaClassAndStructors(IOHIDSystem, IOService);
                     86: 
                     87: /* Return the current instance of the EventDriver, or 0 if none. */
                     88: IOHIDSystem * IOHIDSystem::instance()
                     89: {
                     90:   return evInstance;
                     91: }
                     92: 
                     93: bool IOHIDSystem::init(OSDictionary * properties)
                     94: {
                     95:   if (!super::init(properties))  return false;
                     96: 
                     97:   /*
                     98:    * Initialize minimal state.
                     99:    */
                    100: 
                    101:   driverLock       = NULL;
                    102:   kickConsumerLock = NULL;
                    103:   evScreen         = NULL;
                    104:   timerES          = 0;
                    105:   cmdQ             = 0;
                    106:   workLoop         = 0;
                    107: 
                    108:   return true;
                    109: }
                    110: 
                    111: IOHIDSystem * IOHIDSystem::probe(IOService *   provider,
                    112:                                 SInt32 *       score)
                    113: {
                    114:   if (!super::probe(provider,score))  return 0;
                    115: 
                    116:   return this;
                    117: }
                    118: 
                    119: /*
                    120:  * Perform reusable initialization actions here.
                    121:  */
                    122: IOWorkLoop * IOHIDSystem::getWorkLoop() const
                    123: {
                    124:     return workLoop;
                    125: }
                    126: 
                    127: bool IOHIDSystem::start(IOService * provider)
                    128: {
                    129:   bool iWasStarted = false;
                    130: 
                    131:   do {
                    132:     if (!super::start(provider))  break;
                    133: 
                    134:     evInstance = this;
                    135: 
                    136:     driverLock = IOLockAlloc();        // Event driver data protection lock
                    137:     kickConsumerLock = IOLockAlloc();
                    138: 
                    139:     /* A few details to be set up... */
                    140:     pointerLoc.x = INIT_CURSOR_X;
                    141:     pointerLoc.y = INIT_CURSOR_Y;
                    142: 
                    143:     pointerDelta.x = 0;
                    144:     pointerDelta.y = 0;
                    145: 
                    146:     evScreenSize = sizeof(EvScreen) * 6;       // FIX
                    147:     evScreen = (void *) IOMalloc(evScreenSize);
                    148: 
                    149:     if (!driverLock       ||
                    150:         !kickConsumerLock ||
                    151:         !evScreenSize)  break;
                    152: 
                    153:     IOLockInit(driverLock);
                    154:     IOLockInit(kickConsumerLock);
                    155:     bzero(evScreen, evScreenSize);
                    156: 
                    157:     /*
                    158:      * Start up the work loop
                    159:      */
                    160:     workLoop = IOWorkLoop::workLoop();
                    161:     cmdQ = IOCommandQueue::commandQueue
                    162:         (this, (IOCommandQueueAction) &_doPerformInIOThread );
                    163:     timerES = IOTimerEventSource::timerEventSource
                    164:         (this, (IOTimerEventSource::Action) &_periodicEvents );
                    165: 
                    166:     if (!workLoop || !cmdQ || !timerES)
                    167:         break;
                    168: 
                    169:     if (workLoop->addEventSource(cmdQ)    != kIOReturnSuccess
                    170:     ||  workLoop->addEventSource(timerES) != kIOReturnSuccess)
                    171:         break;
                    172: 
                    173:     publishNotify = addNotification(
                    174:         gIOPublishNotification, serviceMatching("IOHIDevice"),
                    175:         (IOServiceNotificationHandler) &publishNotificationHandler,
                    176:         this, 0 );
                    177: 
                    178:     if (!publishNotify) break;
                    179: 
                    180:     /*
                    181:      * IOHIDSystem serves both as a service and a nub (we lead a double
                    182:      * life).  Register ourselves as a nub to kick off matching.
                    183:      */
                    184: 
                    185:     registerService();
                    186: 
                    187:     addNotification( gIOPublishNotification,serviceMatching("IODisplayWrangler"),      // look for the display wrangler
                    188:                      (IOServiceNotificationHandler)displayWranglerUp, this, 0 );
                    189: 
                    190:     iWasStarted = true;
                    191:   } while(false);
                    192: 
                    193:   if (!iWasStarted)  evInstance = 0;
                    194: 
                    195:   return iWasStarted;
                    196: }
                    197: 
                    198: // **********************************************************************************
                    199: // displayWranglerUp
                    200: //
                    201: // The Display Wrangler has appeared.  We will be calling its
                    202: // activityTickle method when there is user activity.
                    203: // **********************************************************************************
                    204: bool displayWranglerUp( OSObject * us, void * ref, IOService * yourDevice )
                    205: {
                    206:   if ( yourDevice != NULL ) {
                    207:       ((IOHIDSystem *)us)->displayManager = yourDevice;
                    208:   }
                    209:   return true;
                    210: }
                    211: 
                    212: 
                    213: bool IOHIDSystem::publishNotificationHandler(
                    214:                        IOHIDSystem * self,
                    215:                        void * /* ref */,
                    216:                        IOService * newService )
                    217: {
                    218:     self->attach( newService );
                    219: 
                    220: //    IOTakeLock( self->driverLock);
                    221:     if( self->eventsOpen
                    222:        && OSDynamicCast(IOHIDevice, newService)) {
                    223:                self->registerEventSource((IOHIDevice *) newService);
                    224:     }
                    225: //    IOUnlock( self->driverLock);
                    226: 
                    227:     return true;
                    228: }
                    229: 
                    230: 
                    231: /*
                    232:  * Free locally allocated resources, and then ourselves.
                    233:  */
                    234: void IOHIDSystem::free()
                    235: {
                    236:     /* Initiates a normal close if open & inited */
                    237:     if( driverLock)
                    238:         evClose();
                    239: 
                    240:     if (evScreen) IOFree( (void *)evScreen, evScreenSize );
                    241:     evScreen = (void *)0;
                    242:     evScreenSize = 0;
                    243: 
                    244:     if (timerES)       timerES->release();
                    245:     if (cmdQ)          cmdQ->release();
                    246:     if (workLoop)      workLoop->release();
                    247:     if (publishNotify)         publishNotify->release();
                    248: 
                    249:     /* Release locally allocated resources */
                    250:     if (kickConsumerLock) IOLockFree( kickConsumerLock);
                    251:     if (driverLock)       IOLockFree( driverLock);
                    252: 
                    253:     super::free();
                    254: }
                    255: 
                    256: 
                    257: 
                    258: /*
                    259:  * Open the driver for business.  This call must be made before
                    260:  * any other calls to the Event driver.  We can only be opened by
                    261:  * one user at a time.
                    262:  */
                    263: IOReturn IOHIDSystem::evOpen(void)
                    264: {
                    265:        IOReturn r = kIOReturnSuccess;
                    266:        
                    267:        if ( evOpenCalled == true )
                    268:        {
                    269:                r = kIOReturnBusy;
                    270:                goto done;
                    271:        }
                    272:        evOpenCalled = true;
                    273: 
                    274:        if (!evInitialized)
                    275:        {
                    276:            evInitialized = true;
                    277:            curBright = EV_SCREEN_MAX_BRIGHTNESS; // FIXME: Set from NVRAM?
                    278:            curVolume = EV_AUDIO_MAX_VOLUME / 2; // FIXME: Set from NVRAM?
                    279:            // Put code here that is to run on the first open ONLY.
                    280:        }
                    281: 
                    282: done:
                    283:        return r;
                    284: }
                    285: 
                    286: IOReturn IOHIDSystem::evClose(void)
                    287: {
                    288:        IOTakeLock( driverLock);
                    289:        if ( evOpenCalled == false )
                    290:        {
                    291:                IOUnlock( driverLock);
                    292:                return kIOReturnBadArgument;
                    293:        }
                    294:        // Early close actions here
                    295:        forceAutoDimState(false);
                    296:        if( cursorEnabled)
                    297:             hideCursor();
                    298:        cursorStarted = false;
                    299:        cursorEnabled = false;
                    300:        IOUnlock( driverLock);
                    301: 
                    302:        // Release the input devices.
                    303:        detachEventSources();
                    304: 
                    305:        // Tear down the shared memory area if set up
                    306: //     if ( eventsOpen == true )
                    307: //         unmapEventShmem(eventPort);
                    308: 
                    309:        IOTakeLock( driverLock);
                    310:        // Clear screens registry and related data
                    311:        if ( evScreen != (void *)0 )
                    312:        {
                    313:            screens = 0;
                    314:            lastShmemPtr = (void *)0;
                    315:        }
                    316:        // Remove port notification for the eventPort and clear the port out
                    317:        setEventPort(MACH_PORT_NULL);
                    318: //     ipc_port_release_send(event_port);
                    319: 
                    320:        // Clear local state to shutdown
                    321:        evOpenCalled = false;
                    322:        eventsOpen = false;
                    323: 
                    324:        IOUnlock( driverLock);
                    325: 
                    326:        return kIOReturnSuccess;
                    327: }
                    328: 
                    329: //
                    330: // Dispatch state to screens registered with the Event Driver
                    331: // Pending state changes for a device may be coalesced.
                    332: //
                    333: //
                    334: // On entry, the  driverLock should be set.
                    335: //
                    336: void IOHIDSystem::evDispatch(int   screen,
                    337:                /* command */ EvCmd evcmd)
                    338: {
                    339:     Point p;
                    340:     EvScreen *esp = &((EvScreen*)evScreen)[screen];
                    341: 
                    342:     if ( !eventsOpen || (screen < 0) )
                    343:        return;
                    344: 
                    345:     p.x = evg->cursorLoc.x;    // Copy from shmem.
                    346:     p.y = evg->cursorLoc.y;
                    347:     if ( esp->instance )
                    348:     {
                    349:        switch ( evcmd )
                    350:        {
                    351:            case EVMOVE:
                    352:                esp->instance->moveCursor(&p, evg->frame);
                    353:                break;
                    354: 
                    355:            case EVSHOW:
                    356:                esp->instance->showCursor(&p, evg->frame);
                    357:                break;
                    358: 
                    359:            case EVHIDE:
                    360:                esp->instance->hideCursor();
                    361:                break;
                    362: 
                    363:            case EVLEVEL:
                    364:                esp->instance->setBrightness(currentBrightness());
                    365:                break;
                    366:               
                    367:            case EVNOP:
                    368:                /* lets keep that compiler happy */
                    369:                break;
                    370:        }
                    371:     }
                    372: }
                    373: 
                    374: //
                    375: // Dispatch mechanism for special key press.  If a port has been registered,
                    376: // a message is built to be sent out to that port notifying that the key has
                    377: // changed state.  A level in the range 0-64 is provided for convenience.
                    378: //
                    379: void IOHIDSystem::evSpecialKeyMsg(unsigned key,
                    380:                  /* direction */ unsigned dir,
                    381:                  /* flags */     unsigned f,
                    382:                  /* level */     unsigned l)
                    383: {
                    384:        mach_port_t dst_port;
                    385:        struct evioSpecialKeyMsg *msg;
                    386: 
                    387:        static const struct evioSpecialKeyMsg init_msg =
                    388:         { { MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,    // mach3xxx, is the right?
                    389:                         MACH_MSG_TYPE_MAKE_SEND),      // mach_msg_bits_t      msgh_bits;
                    390:             sizeof (struct evioSpecialKeyMsg),                 // mach_msg_size_t      msgh_size;
                    391:             MACH_PORT_NULL,                            // mach_port_t  msgh_remote_port;
                    392:             MACH_PORT_NULL,                            // mach_port_t  msgh_local_port;
                    393:             0,                                         // mach_msg_size_t msgh_reserved;
                    394:             EV_SPECIAL_KEY_MSG_ID                      // mach_msg_id_t        msgh_id;
                    395:             },
                    396:             0, /* key */
                    397:             0, /* direction */
                    398:             0, /* flags */
                    399:             0  /* level */
                    400:         };
                    401: 
                    402:        if ( (dst_port = specialKeyPort(key)) == MACH_PORT_NULL )
                    403:                return;
                    404:        msg = (struct evioSpecialKeyMsg *) IOMalloc(
                    405:                                sizeof (struct evioSpecialKeyMsg) );
                    406:        if ( msg == NULL )
                    407:                return;
                    408:        
                    409:        // Initialize the message.
                    410:        bcopy( &init_msg, msg, sizeof (struct evioSpecialKeyMsg) );
                    411:        msg->Head.msgh_remote_port = dst_port;
                    412:        msg->key = key;
                    413:        msg->direction = dir;
                    414:        msg->flags = f;
                    415:        msg->level = l;
                    416: 
                    417:        // Send the message out from the I/O thread.
                    418:         sendWorkLoopCommand(this,(IOHIDAction)_performSpecialKeyMsg,(void*)msg);
                    419: }
                    420: 
                    421: //
                    422: // Reset instance variables to their default state for mice/pointers
                    423: //
                    424: void IOHIDSystem::_resetMouseParameters()
                    425: {
                    426: 
                    427:        IOTakeLock( driverLock);
                    428:        if ( eventsOpen == false )
                    429:        {
                    430:            IOUnlock( driverLock);
                    431:            return;
                    432:        }
                    433:         nanoseconds_to_absolutetime( EV_DCLICKTIME, &clickTimeThresh);
                    434:        clickSpaceThresh.x = clickSpaceThresh.y = EV_DCLICKSPACE;
                    435:         AbsoluteTime_to_scalar( &clickTime) = 0;
                    436:        clickLoc.x = clickLoc.y = -EV_DCLICKSPACE;
                    437:        clickState = 1;
                    438:         nanoseconds_to_absolutetime( DAUTODIMPERIOD, &autoDimPeriod);
                    439:         clock_get_uptime( &autoDimTime);
                    440:         ADD_ABSOLUTETIME( &autoDimTime, &autoDimPeriod);
                    441:         dimmedBrightness = DDIMBRIGHTNESS;
                    442: 
                    443:        IOUnlock( driverLock);
                    444: }
                    445: 
                    446: void IOHIDSystem::_resetKeyboardParameters()
                    447: {
                    448: }
                    449: 
                    450: /*
                    451:  * Methods exported by the EventDriver.
                    452:  *
                    453:  *     The screenRegister protocol is used by frame buffer drivers to register
                    454:  *     themselves with the Event Driver.  These methods are called in response
                    455:  *     to a registerSelf or unregisterSelf message received from the Event
                    456:  *     Driver.
                    457:  */
                    458: 
                    459: int IOHIDSystem::registerScreen(IOGraphicsDevice * instance,
                    460:                /* bounds */    Bounds * bp)
                    461: //             /* shmem */     void **  addr,
                    462: //             /* size */      int *    size)
                    463: {
                    464:     EvScreen *esp;
                    465: 
                    466: 
                    467: 
                    468:     if ( eventsOpen == false )
                    469:     {
                    470: //     *addr = (void *)0;
                    471: //     *size = 0;
                    472:        return -1;
                    473:     }
                    474:     if ( lastShmemPtr == (void *)0 )
                    475:        lastShmemPtr = evs;
                    476:     
                    477:     /* shmemSize and bounds already set */
                    478:     esp = &((EvScreen*)evScreen)[screens];
                    479:     esp->instance = instance;
                    480: #if 0
                    481:     /* If this driver wants private shmem, then set its shmemPtr */
                    482:     if (esp->shmemSize)
                    483:        esp->shmemPtr = lastShmemPtr;
                    484:     lastShmemPtr += esp->shmemSize;
                    485:     /* Fill in parameters for the requesting instance */
                    486:     *addr = esp->shmemPtr;
                    487:     *size = esp->shmemSize;
                    488:     bcopy( (char *)&esp->bounds, (char *)bp, sizeof (Bounds) );
                    489: #else
                    490:     esp->bounds = bp;
                    491:     // Update our idea of workSpace bounds
                    492:     if ( bp->minx < workSpace.minx )
                    493:        workSpace.minx = bp->minx;
                    494:     if ( bp->miny < workSpace.miny )
                    495:        workSpace.miny = bp->miny;
                    496:     if ( bp->maxx < workSpace.maxx )
                    497:        workSpace.maxx = bp->maxx;
                    498:     if ( esp->bounds->maxy < workSpace.maxy )
                    499:        workSpace.maxy = bp->maxy;
                    500: #endif
                    501:     return(SCREENTOKEN + screens++);
                    502: }
                    503: 
                    504: 
                    505: void IOHIDSystem::unregisterScreen(int index)
                    506: {
                    507:     int i;
                    508: 
                    509:     index -= SCREENTOKEN;
                    510: 
                    511:     IOTakeLock( driverLock);
                    512:     if ( eventsOpen == false || index < 0 || index >= screens )
                    513:     {
                    514:        IOUnlock( driverLock);
                    515:        return;
                    516:     }
                    517:     hideCursor();
                    518:     // clear the state for the screen
                    519:     ((EvScreen*)evScreen)[index].instance = 0;
                    520:     // Put the cursor someplace reasonable if it was on the destroyed screen
                    521:     if ( currentScreen == index )      // Uh oh...
                    522:     {
                    523:        for ( i = screens; --i != -1; ) // Pick a new currentScreen
                    524:        {
                    525:            if ( ((EvScreen*)evScreen)[i].instance != 0 )
                    526:            {
                    527:                currentScreen = i;
                    528:                break;
                    529:            }
                    530:        }
                    531:        // This will jump the cursor back on screen
                    532:        setCursorPosition((Point *)&evg->cursorLoc);
                    533:     }
                    534:     else
                    535:        showCursor();
                    536:     IOUnlock( driverLock);
                    537: }
                    538: 
                    539: /* Member of EventClient protocol 
                    540:  *
                    541:  * Absolute position input devices and some specialized output devices
                    542:  * may need to know the bounding rectangle for all attached displays.
                    543:  * The following method returns a Bounds* for the workspace.  Please note
                    544:  * that the bounds are kept as signed values, and that on a multi-display
                    545:  * system the minx and miny values may very well be negative.
                    546:  */
                    547: Bounds * IOHIDSystem::workspaceBounds()
                    548: {
                    549:        return &workSpace;
                    550: }
                    551: 
                    552: IOReturn IOHIDSystem::createShmem(void* p1, void*, void*, void*, void*, void*)
                    553: {                                                                    // IOMethod
                    554:     int                 shmemVersion = (int)p1;
                    555:     IOByteCount                size;
                    556: 
                    557:     if( shmemVersion != kIOHIDCurrentShmemVersion)
                    558:        return( kIOReturnUnsupported);
                    559: 
                    560:     IOTakeLock( driverLock);
                    561: 
                    562:     if( 0 == globalMemory) {
                    563: 
                    564:        // rounded up to avoid mapping nonshared data
                    565:         size = round_page(sizeof(EvOffsets) + sizeof(EvGlobals));
                    566:        globalMemory = IOBufferMemoryDescriptor::withCapacity( size,
                    567:                                kIODirectionNone, false);
                    568: 
                    569:         if( !globalMemory) {
                    570:             IOUnlock( driverLock);
                    571:             return( kIOReturnNoMemory );
                    572:        }
                    573:        globalMemory->setLength(size);
                    574:        shmem_addr = (vm_offset_t) globalMemory->getBytesNoCopy();
                    575:         shmem_size = size;
                    576:     }
                    577: 
                    578:     initShmem();
                    579:     IOUnlock( driverLock);
                    580: 
                    581:     return kIOReturnSuccess;
                    582: }
                    583: 
                    584: 
                    585: // Initialize the shared memory area.
                    586: //
                    587: // On entry, the driverLock should be set.
                    588: void IOHIDSystem::initShmem()
                    589: {
                    590:        int             i;
                    591:        EvOffsets       *eop;
                    592: 
                    593:        pointerLoc.x = INIT_CURSOR_X;
                    594:        pointerLoc.y = INIT_CURSOR_Y;
                    595: 
                    596:         pointerDelta.x = 0;
                    597:         pointerDelta.y = 0;
                    598: 
                    599:        /* top of sharedMem is EvOffsets structure */
                    600:        eop = (EvOffsets *) shmem_addr;
                    601: 
                    602:        bzero( (void*)shmem_addr, shmem_size);
                    603:        
                    604:        /* fill in EvOffsets structure */
                    605:        eop->evGlobalsOffset = sizeof(EvOffsets);
                    606:        eop->evShmemOffset = eop->evGlobalsOffset + sizeof(EvGlobals);
                    607:     
                    608:        /* find pointers to start of globals and private shmem region */
                    609:        evg = (EvGlobals *)((char *)shmem_addr + eop->evGlobalsOffset);
                    610:        evs = (void *)((char *)shmem_addr + eop->evShmemOffset);
                    611:     
                    612:        evg->version = kIOHIDCurrentShmemVersion;
                    613:        evg->structSize = sizeof( EvGlobals);
                    614: 
                    615:        /* Set default wait cursor parameters */
                    616:        evg->waitCursorEnabled = TRUE;
                    617:        evg->globalWaitCursorEnabled = TRUE;
                    618:        evg->waitThreshold = (12 * EV_TICKS_PER_SEC) / 10;
                    619:         clock_interval_to_absolutetime_interval(DefaultWCFrameRate, kNanosecondScale,
                    620:                                                 &waitFrameRate);
                    621:         clock_interval_to_absolutetime_interval(DefaultWCSustain, kNanosecondScale,
                    622:                                                 &waitSustain);
                    623:         AbsoluteTime_to_scalar(&waitSusTime) = 0;
                    624:         AbsoluteTime_to_scalar(&waitFrameTime) = 0;
                    625: 
                    626:        EV_TICK_TO_NS(10,&periodicEventDelta);
                    627: 
                    628:        /* Set up low-level queues */
                    629:        lleqSize = LLEQSIZE;
                    630:        for (i=lleqSize; --i != -1; ) {
                    631:            evg->lleq[i].event.type = 0;
                    632: #if EVENT_SYSTEM_VERSION > 1
                    633:             AbsoluteTime_to_scalar(&evg->lleq[i].event.time) = 0;
                    634: #else
                    635:             evg->lleq[i].event.time = 0;
                    636: #endif
                    637:             evg->lleq[i].event.flags = 0;
                    638:            ev_init_lock(&evg->lleq[i].sema);
                    639:            evg->lleq[i].next = i+1;
                    640:        }
                    641:        evg->LLELast = 0;
                    642:        evg->lleq[lleqSize-1].next = 0;
                    643:        evg->LLEHead =
                    644:            evg->lleq[evg->LLELast].next;
                    645:        evg->LLETail =
                    646:            evg->lleq[evg->LLELast].next;
                    647:        evg->buttons = 0;
                    648:        evg->eNum = INITEVENTNUM;
                    649:        evg->eventFlags = 0;
                    650: 
                    651:         AbsoluteTime   ts;
                    652:         unsigned       tick;
                    653:         clock_get_uptime( &ts);
                    654:         tick = EV_NS_TO_TICK(&ts);
                    655:         if ( tick == 0 )
                    656:                 tick = 1;      // No zero values allowed!
                    657:        evg->VertRetraceClock = tick;
                    658: 
                    659:         evg->cursorLoc.x = pointerLoc.x;
                    660:        evg->cursorLoc.y = pointerLoc.y;
                    661:        evg->dontCoalesce = 0;
                    662:        evg->dontWantCoalesce = 0;
                    663:        evg->wantPressure = 0;
                    664:        evg->wantPrecision = 0;
                    665:        evg->mouseRectValid = 0;
                    666:        evg->movedMask = 0;
                    667:        ev_init_lock( &evg->cursorSema );
                    668:        ev_init_lock( &evg->waitCursorSema );
                    669:        // Set eventsOpen last to avoid race conditions.
                    670:        eventsOpen = true;
                    671: }
                    672: 
                    673: //
                    674: // Set the event port.  The event port is both an ownership token
                    675: // and a live port we hold send rights on.  The port is owned by our client,
                    676: // the WindowServer.  We arrange to be notified on a port death so that
                    677: // we can tear down any active resources set up during this session.
                    678: // An argument of PORT_NULL will cause us to forget any port death
                    679: // notification that's set up.
                    680: //
                    681: // The driverLock should be held on entry.
                    682: //
                    683: void IOHIDSystem::setEventPort(mach_port_t port)
                    684: {
                    685:        static struct _eventMsg init_msg = { {
                    686:             // mach_msg_bits_t msgh_bits;
                    687:             MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,0),
                    688:             // mach_msg_size_t msgh_size;
                    689:             sizeof (struct _eventMsg),
                    690:             // mach_port_t     msgh_remote_port;
                    691:             MACH_PORT_NULL,
                    692:             // mach_port_t     msgh_local_port;
                    693:             MACH_PORT_NULL,
                    694:             // mach_msg_size_t         msgh_reserved;
                    695:             0,
                    696:             // mach_msg_id_t   msgh_id;
                    697:             0
                    698:         } };
                    699: 
                    700:        if ( eventMsg == NULL )
                    701:                eventMsg = IOMalloc( sizeof (struct _eventMsg) );
                    702:        eventPort = port;
                    703:        // Initialize the events available message.
                    704:        *((struct _eventMsg *)eventMsg) = init_msg;
                    705: 
                    706:        ((struct _eventMsg *)eventMsg)->h.msgh_remote_port = port;
                    707: }
                    708: 
                    709: //
                    710: // Set the port to be used for a special key notification.  This could be more
                    711: // robust about letting ports be set...
                    712: //
                    713: IOReturn IOHIDSystem::setSpecialKeyPort(
                    714:                         /* keyFlavor */ int         special_key,
                    715:                         /* keyPort */   mach_port_t key_port)
                    716: {
                    717:        if ( special_key >= 0 && special_key < NX_NUM_SCANNED_SPECIALKEYS )
                    718:                _specialKeyPort[special_key] = key_port;
                    719:        return kIOReturnSuccess;
                    720: }
                    721: 
                    722: mach_port_t IOHIDSystem::specialKeyPort(int special_key)
                    723: {
                    724:        if ( special_key >= 0 && special_key < NX_NUM_SCANNED_SPECIALKEYS )
                    725:                return _specialKeyPort[special_key];
                    726:        return MACH_PORT_NULL;
                    727: }
                    728: 
                    729: //
                    730: // Helper functions for postEvent
                    731: //
                    732: static inline int myAbs(int a) { return(a > 0 ? a : -a); }
                    733: 
                    734: short IOHIDSystem::getUniqueEventNum()
                    735: {
                    736:     while (++evg->eNum == NULLEVENTNUM)
                    737:        ; /* sic */
                    738:     return(evg->eNum);
                    739: }
                    740: 
                    741: // postEvent 
                    742: //
                    743: // This routine actually places events in the event queue which is in
                    744: // the EvGlobals structure.  It is called from all parts of the ev
                    745: // driver.
                    746: //
                    747: // On entry, the driverLock should be set.
                    748: //
                    749: 
                    750: void IOHIDSystem::postEvent(int           what,
                    751:              /* at */       Point *       location,
                    752:              /* atTime */   AbsoluteTime  ts,
                    753:              /* withData */ NXEventData * myData)
                    754: {
                    755:     NXEQElement        * theHead = (NXEQElement *) &evg->lleq[evg->LLEHead];
                    756:     NXEQElement        * theLast = (NXEQElement *) &evg->lleq[evg->LLELast];
                    757:     NXEQElement        * theTail = (NXEQElement *) &evg->lleq[evg->LLETail];
                    758:     int                  wereEvents;
                    759:     unsigned      theClock = EV_NS_TO_TICK(&ts);
                    760: 
                    761:     /* Some events affect screen dimming */
                    762:     if (EventCodeMask(what) & NX_UNDIMMASK) {
                    763:         autoDimTime = ts;
                    764:         ADD_ABSOLUTETIME( &autoDimTime, &autoDimPeriod);
                    765:        if (autoDimmed)
                    766:            undoAutoDim();
                    767:     }
                    768:     // Update the PS VertRetraceClock off of the timestamp if it looks sane
                    769:     if (   theClock > (unsigned)evg->VertRetraceClock
                    770:        && theClock < (unsigned)(evg->VertRetraceClock + (20 * EV_TICK_TIME)) )
                    771:        evg->VertRetraceClock = theClock;
                    772: 
                    773:     wereEvents = EventsInQueue();
                    774: 
                    775:     xpr_ev_post("postEvent: what %d, X %d Y %d Q %d, needKick %d\n",
                    776:                what,location->x,location->y,
                    777:                EventsInQueue(), needToKickEventConsumer);
                    778: 
                    779:     if ((!evg->dontCoalesce)   /* Coalescing enabled */
                    780:     && (theHead != theTail)
                    781:     && (theLast->event.type == what)
                    782:     && (EventCodeMask(what) & COALESCEEVENTMASK)
                    783:     && ev_try_lock(&theLast->sema)) {
                    784:     /* coalesce events */
                    785:        theLast->event.location.x = location->x;
                    786:        theLast->event.location.y = location->y;
                    787: #if EVENT_SYSTEM_VERSION > 1
                    788:         absolutetime_to_nanoseconds(ts, &theLast->event.time);
                    789: #else
                    790:         theLast->event.time = theClock;
                    791: #endif
                    792:         if (myData != NULL)
                    793:            theLast->event.data = *myData;
                    794:        ev_unlock(&theLast->sema);
                    795:     } else if (theTail->next != evg->LLEHead) {
                    796:        /* store event in tail */
                    797:        theTail->event.type = what;
                    798:        theTail->event.location.x = location->x;
                    799:        theTail->event.location.y = location->y;
                    800:        theTail->event.flags = evg->eventFlags;
                    801: #if EVENT_SYSTEM_VERSION > 1
                    802:         absolutetime_to_nanoseconds(ts, &theLast->event.time);
                    803: #else
                    804:         theLast->event.time = theClock;
                    805: #endif
                    806:        theTail->event.window = 0;
                    807:        if (myData != NULL)
                    808:            theTail->event.data = *myData;
                    809:        switch(what) {
                    810:        case NX_LMOUSEDOWN:
                    811:            theTail->event.data.mouse.eventNum =
                    812:                leftENum = getUniqueEventNum();
                    813:            break;
                    814:        case NX_RMOUSEDOWN:
                    815:            theTail->event.data.mouse.eventNum =
                    816:                rightENum = getUniqueEventNum();
                    817:            break;
                    818:        case NX_LMOUSEUP:
                    819:            theTail->event.data.mouse.eventNum = leftENum;
                    820:            leftENum = NULLEVENTNUM;
                    821:            break;
                    822:        case NX_RMOUSEUP:
                    823:            theTail->event.data.mouse.eventNum = rightENum;
                    824:            rightENum = NULLEVENTNUM;
                    825:            break;
                    826:        }
                    827:        if (EventCodeMask(what) & PRESSUREEVENTMASK) {
                    828:            theTail->event.data.mouse.pressure = lastPressure;
                    829:        }
                    830:        if (EventCodeMask(what) & MOUSEEVENTMASK) { /* Click state */
                    831:             AbsoluteTime delta = ts;
                    832:             SUB_ABSOLUTETIME( &delta, &clickTime);
                    833:             if ((CMP_ABSOLUTETIME(&delta, &clickTimeThresh) <= 0)
                    834:            && (myAbs(location->x - clickLoc.x) <= clickSpaceThresh.x)
                    835:            && (myAbs(location->y - clickLoc.y) <= clickSpaceThresh.y)) {
                    836:                 if ((what == NX_LMOUSEDOWN)||(what == NX_RMOUSEDOWN)) {
                    837:                     clickTime = ts;
                    838:                     theTail->event.data.mouse.click = ++clickState;
                    839:                 } else {
                    840:                     theTail->event.data.mouse.click = clickState;
                    841:                 }
                    842:            } else if ((what == NX_LMOUSEDOWN)||(what == NX_RMOUSEDOWN)) {
                    843:                clickLoc = *location;
                    844:                clickTime = ts;
                    845:                clickState = 1;
                    846:                theTail->event.data.mouse.click = clickState;
                    847:            } else
                    848:                theTail->event.data.mouse.click = 0;
                    849:        }
                    850: #if PMON
                    851:        pmon_log_event(PMON_SOURCE_EV,
                    852:                       KP_EV_POST_EVENT,
                    853:                       what,
                    854:                       evg->eventFlags,
                    855:                       theClock);
                    856: #endif
                    857:        evg->LLETail = theTail->next;
                    858:        evg->LLELast = theLast->next;
                    859:        if ( ! wereEvents )     // Events available, so wake event consumer
                    860:            kickEventConsumer();
                    861:     }
                    862:     else
                    863:     {
                    864:        /*
                    865:         * if queue is full, ignore event, too hard to take care of all cases 
                    866:         */
                    867:        IOLog("%s: postEvent LLEventQueue overflow.\n", getName());
                    868:        kickEventConsumer();
                    869: #if PMON
                    870:        pmon_log_event( PMON_SOURCE_EV,
                    871:                        KP_EV_QUEUE_FULL,
                    872:                        what,
                    873:                        evg->eventFlags,
                    874:                        theClock);
                    875: #endif
                    876:     }
                    877: }
                    878: 
                    879: /*
                    880:  * - kickEventConsumer
                    881:  *
                    882:  *     Try to send a message out to let the event consumer know that
                    883:  *     there are now events available for consumption.
                    884:  */
                    885: 
                    886: void IOHIDSystem::kickEventConsumer()
                    887: { 
                    888:        IOReturn        err;
                    889: 
                    890: #if 0
                    891:         _performKickEventConsumer(0)];
                    892: #else
                    893: 
                    894:        IOTakeLock( kickConsumerLock);
                    895:        xpr_ev_post("kickEventConsumer (need == %d)\n",
                    896:                needToKickEventConsumer,2,3,4,5);
                    897:        if ( needToKickEventConsumer == true )
                    898:        {
                    899:                IOUnlock( kickConsumerLock);
                    900:                return;         // Request is already pending
                    901:        }
                    902:        needToKickEventConsumer = true; // Posting a request now
                    903:        IOUnlock( kickConsumerLock);
                    904: 
                    905:         err = sendWorkLoopCommand(this, (IOHIDAction)_performKickEventConsumer,
                    906:                                   NULL);
                    907: 
                    908:        if( err)
                    909:            IOLog("%s: cmdQ fail %d\n", getName(), err);
                    910: #endif
                    911: }
                    912: 
                    913: /* 
                    914:  * Event sources may need to use an I/O thread from time to time.
                    915:  * Rather than have each instance running it's own thread, we provide
                    916:  * a callback mechanism to let all the instances share a common Event I/O
                    917:  * thread running in the IOTask space, and managed by the Event Driver.
                    918:  */
                    919: 
                    920: IOReturn IOHIDSystem::sendWorkLoopCommand(OSObject *  target,
                    921:                                           IOHIDAction action,
                    922:                                           void *      data)
                    923: {
                    924:        kern_return_t err;
                    925: 
                    926:         err = cmdQ->enqueueCommand( /* sleep  */ true,
                    927:                                     /* field0 */ target,
                    928:                                     /* field1 */ (void *) action,
                    929:                                     /* field2 */ data );
                    930: 
                    931:        return (err == KERN_SUCCESS) ? kIOReturnSuccess : kIOReturnNoMemory;
                    932: }
                    933: 
                    934: /*
                    935:  * The following methods are executed from the I/O thread only.
                    936:  */
                    937: 
                    938: /*
                    939:  * This routine is run within the I/O thread, on demand from the
                    940:  * sendWorkLoopCommand method above.  We attempt to dispatch a message
                    941:  * to the specified selector and instance.
                    942:  */
                    943: void IOHIDSystem::_doPerformInIOThread(void* self,
                    944:                                       void* target, /* IOCommandQueueAction */
                    945:                                        void* action,
                    946:                                        void* data,
                    947:                                        void* /* unused */)
                    948: {                                                    
                    949:   (*((IOHIDAction)action))((OSObject *)target, data);
                    950: }
                    951: 
                    952: /*
                    953:  * This is run in the I/O thread, to perform the actual message send operation.
                    954:  */
                    955: 
                    956: void IOHIDSystem::_performSpecialKeyMsg(IOHIDSystem * self,
                    957:                                        struct evioSpecialKeyMsg *msg)
                    958:                                                               /* IOHIDAction */
                    959: {
                    960:        kern_return_t r;
                    961: 
                    962:        xpr_ev_post("_performSpecialKeyMsg 0x%x\n", msg,2,3,4,5);
                    963: 
                    964: 
                    965:        /* FIXME: Don't block */
                    966:        r = mach_msg_send_from_kernel( &msg->Head, msg->Head.msgh_size);
                    967: 
                    968:        xpr_ev_post("_performSpecialKeyMsg: msg_send() == %d\n",r,2,3,4,5);
                    969:        if ( r != MACH_MSG_SUCCESS )
                    970:        {
                    971:                IOLog("%s: _performSpecialKeyMsg msg_send returned %d\n",
                    972:                        self->getName(), r);
                    973:        }
                    974:        if ( r == MACH_SEND_INVALID_DEST )      /* Invalidate the port */
                    975:        {
                    976:                self->setSpecialKeyPort(
                    977:                  /* keyFlavor */ msg->key,
                    978:                  /* keyPort   */ MACH_PORT_NULL);
                    979:        }
                    980:        IOFree( (void *)msg, sizeof (struct evioSpecialKeyMsg) );
                    981: }
                    982: 
                    983: /*
                    984:  * This is run in the I/O thread, to perform the actual message send operation.
                    985:  * Note that we perform a non-blocking send.  The Event port in the event
                    986:  * consumer has a queue depth of 1 message.  Once the consumer picks up that
                    987:  * message, it runs until the event queue is exhausted before trying to read
                    988:  * another message.  If a message is pending,there is no need to enqueue a
                    989:  * second one.  This also keeps us from blocking the I/O thread in a msg_send
                    990:  * which could result in a deadlock if the consumer were to make a call into
                    991:  * the event driver.
                    992:  */
                    993: void IOHIDSystem::_performKickEventConsumer(IOHIDSystem * self, void *)  /* IOHIDAction */
                    994: {
                    995:        kern_return_t r;
                    996:        mach_msg_header_t *msgh
                    997: 
                    998:        xpr_ev_post("_performKickEventConsumer\n", 1,2,3,4,5);
                    999:        IOTakeLock( self->kickConsumerLock);
                   1000:        self->needToKickEventConsumer = false;   // Request received and processed
                   1001:        IOUnlock( self->kickConsumerLock);
                   1002: 
                   1003:        msgh = (mach_msg_header_t *)self->eventMsg;
                   1004:        if( msgh) {
                   1005: 
                   1006:             r = mach_msg_send_from_kernel( msgh, msgh->msgh_size);
                   1007:             switch ( r )
                   1008:             {
                   1009:                 case MACH_SEND_TIMED_OUT:/* Already has a message posted */
                   1010:                 case MACH_MSG_SUCCESS: /* Message is posted */
                   1011:                     break;
                   1012:                 default:               /* Log the error */
                   1013:                     IOLog("%s: _performKickEventConsumer msg_send returned %d\n",
                   1014:                                self->getName(), r);
                   1015:                     break;
                   1016:             }
                   1017:        }
                   1018: }
                   1019: 
                   1020: //
                   1021: // Schedule the next periodic event to be run, based on the current state of
                   1022: // the event system.  We have to consider things here such as when the last
                   1023: // periodic event pass ran, if there is currently any mouse delta accumulated,
                   1024: // and how long it has been since the last event was consumed by an app (for
                   1025: // driving the wait cursor).
                   1026: //
                   1027: // This code should only be run from the periodicEvents method or
                   1028: // _setCursorPosition.
                   1029: //
                   1030: void IOHIDSystem::scheduleNextPeriodicEvent()
                   1031: {
                   1032:     if ( AbsoluteTime_to_scalar(&waitFrameTime) != 0)
                   1033:     {
                   1034:        AbsoluteTime time_for_next_run;
                   1035: 
                   1036:         clock_get_uptime(&time_for_next_run);
                   1037:         ADD_ABSOLUTETIME( &time_for_next_run, &periodicEventDelta);
                   1038: 
                   1039:         if (CMP_ABSOLUTETIME( &waitFrameTime, &time_for_next_run) < 0) {
                   1040:             timerES->wakeAtTime(waitFrameTime);
                   1041:             return;
                   1042:         }
                   1043:     }
                   1044: 
                   1045:     timerES->setTimeout(periodicEventDelta);
                   1046: }
                   1047: 
                   1048: // Periodic events are driven from this method.
                   1049: // After taking care of all pending work, the method
                   1050: // calls scheduleNextPeriodicEvent to compute and set the
                   1051: // next callout.
                   1052: //
                   1053: 
                   1054: void IOHIDSystem::_periodicEvents(IOHIDSystem * self,
                   1055:                                   IOTimerEventSource *timer)
                   1056: {
                   1057:     self->periodicEvents(timer);
                   1058: }
                   1059: 
                   1060: void IOHIDSystem::periodicEvents(IOTimerEventSource * /* timer */)
                   1061:                                 /* IOTimerEventSource::Action, IOHIDAction */
                   1062: {
                   1063:        unsigned int    tick;
                   1064: 
                   1065:        // If eventsOpen is false, then the driver shmem is
                   1066:        // no longer valid, and it is in the process of shutting down.
                   1067:        // We should give up without rescheduling.
                   1068:        IOTakeLock( driverLock);
                   1069:        if ( eventsOpen == false )
                   1070:        {
                   1071:                IOUnlock( driverLock);
                   1072:                return;
                   1073:        }
                   1074: 
                   1075:        // Increment event time stamp last
                   1076:         clock_get_uptime(&thisPeriodicRun);
                   1077: 
                   1078:        // Temporary hack til we wean CGS off of VertRetraceClock
                   1079:        tick = EV_NS_TO_TICK(&thisPeriodicRun);
                   1080:        if ( tick == 0 )
                   1081:                tick = 1;
                   1082:        evg->VertRetraceClock = tick;
                   1083: 
                   1084:        // Update cursor position if needed
                   1085:        if ( needSetCursorPosition == true )
                   1086:                _setCursorPosition(&pointerLoc);
                   1087: 
                   1088:        // WAITCURSOR ACTION
                   1089:        if ( ev_try_lock(&evg->waitCursorSema) )
                   1090:        {
                   1091:            if ( ev_try_lock(&evg->cursorSema) )
                   1092:            {
                   1093:                // See if the current context has timed out
                   1094:                if (   (evg->AALastEventSent != evg->AALastEventConsumed)
                   1095:                    && ((evg->VertRetraceClock - evg->AALastEventSent >
                   1096:                                        evg->waitThreshold)))
                   1097:                    evg->ctxtTimedOut = TRUE;
                   1098:                // If wait cursor enabled and context timed out, do waitcursor
                   1099:                if (evg->waitCursorEnabled && evg->globalWaitCursorEnabled &&
                   1100:                evg->ctxtTimedOut)
                   1101:                {
                   1102:                    /* WAIT CURSOR SHOULD BE ON */
                   1103:                    if (!evg->waitCursorUp)
                   1104:                        showWaitCursor();
                   1105:                } else
                   1106:                {
                   1107:                    /* WAIT CURSOR SHOULD BE OFF */
                   1108:                    if (evg->waitCursorUp &&
                   1109:                        CMP_ABSOLUTETIME(&waitSusTime, &thisPeriodicRun) <= 0)
                   1110:                        hideWaitCursor();
                   1111:                }
                   1112:                /* Animate cursor */
                   1113:                if (evg->waitCursorUp &&
                   1114:                        CMP_ABSOLUTETIME(&waitFrameTime, &thisPeriodicRun) <= 0)
                   1115:                        animateWaitCursor();
                   1116:                ev_unlock(&evg->cursorSema);
                   1117:                if ((CMP_ABSOLUTETIME(&thisPeriodicRun, &autoDimTime) > 0)
                   1118:                     && (!autoDimmed))
                   1119:                    doAutoDim();
                   1120:            }
                   1121:            ev_unlock(&evg->waitCursorSema);
                   1122:        }
                   1123: 
                   1124:        scheduleNextPeriodicEvent();
                   1125:        IOUnlock( driverLock);
                   1126: 
                   1127:        return;
                   1128: }
                   1129: 
                   1130: //
                   1131: // Start the cursor system running.  Invoked via setParameterInt:EVIOST from
                   1132: // the Window Server.
                   1133: //
                   1134: // At this point, the WindowServer is up, running, and ready to process events.
                   1135: // We will attach the keyboard and mouse, if none are available yet.
                   1136: //
                   1137: 
                   1138: bool IOHIDSystem::resetCursor()
                   1139: {
                   1140:     volatile Point * p;
                   1141: 
                   1142:     p = &evg->cursorLoc;
                   1143: 
                   1144:     cursorPin = *(((EvScreen*)evScreen)[currentScreen].bounds);
                   1145:     cursorPin.maxx--;  // Set the range the cursor is pinned
                   1146:     cursorPin.maxy--;  // to for this display [closed range]
                   1147: 
                   1148:     /* Pin new cursor position to cursorPin rect */
                   1149:     p->x = (p->x < cursorPin.minx) ?
                   1150:         cursorPin.minx : ((p->x > cursorPin.maxx) ?
                   1151:         cursorPin.maxx : p->x);
                   1152:     p->y = (p->y < cursorPin.miny) ?
                   1153:         cursorPin.miny : ((p->y > cursorPin.maxy) ?
                   1154:         cursorPin.maxy : p->y);
                   1155: 
                   1156:     return( true );
                   1157: }
                   1158: 
                   1159: bool IOHIDSystem::startCursor()
                   1160: {
                   1161:     bool               ok;
                   1162: 
                   1163:     if ( (currentScreen = pointToScreen((Point *) &evg->cursorLoc)) < 0 )
                   1164:         return( false);
                   1165: 
                   1166:     resetCursor();
                   1167:     setBrightness();
                   1168:     showCursor();
                   1169: //  attachDefaultEventSources();
                   1170: 
                   1171:     // Start the cursor control callouts
                   1172:     ok = (kIOReturnSuccess ==
                   1173:        sendWorkLoopCommand(this, (IOHIDAction)_periodicEvents, timerES));
                   1174: 
                   1175:     cursorStarted = ok;
                   1176:     return( ok );
                   1177: }
                   1178: 
                   1179: //
                   1180: // Wait Cursor machinery.  The driverLock should be held on entry to
                   1181: // these methods, and the shared memory area must be set up.
                   1182: //
                   1183: void IOHIDSystem::showWaitCursor()
                   1184: {
                   1185:        xpr_ev_cursor("showWaitCursor\n",1,2,3,4,5);
                   1186:        evg->waitCursorUp = true;
                   1187:        changeCursor(EV_WAITCURSOR);
                   1188:        // Set animation and sustain absolute times.
                   1189: 
                   1190:        waitSusTime = waitFrameTime = thisPeriodicRun;
                   1191:        ADD_ABSOLUTETIME( &waitFrameTime, &waitFrameRate);
                   1192:        ADD_ABSOLUTETIME( &waitSusTime, &waitSustain);
                   1193: }
                   1194: 
                   1195: void IOHIDSystem::hideWaitCursor()
                   1196: {
                   1197:        xpr_ev_cursor("hideWaitCursor\n",1,2,3,4,5);
                   1198:        evg->waitCursorUp = false;
                   1199:        changeCursor(EV_STD_CURSOR);
                   1200:         AbsoluteTime_to_scalar(&waitFrameTime) = 0;
                   1201:         AbsoluteTime_to_scalar(&waitSusTime ) = 0;
                   1202: }
                   1203: 
                   1204: void IOHIDSystem::animateWaitCursor()
                   1205: {
                   1206:        xpr_ev_cursor("animateWaitCursor\n",1,2,3,4,5);
                   1207:        changeCursor(evg->frame + 1);
                   1208:        // Set the next animation time.
                   1209:        waitFrameTime = thisPeriodicRun;
                   1210:        ADD_ABSOLUTETIME( &waitFrameTime, &waitFrameRate);
                   1211: }
                   1212: 
                   1213: void IOHIDSystem::changeCursor(int frame)
                   1214: { 
                   1215:        evg->frame =
                   1216:                (frame > EV_MAXCURSOR) ? EV_WAITCURSOR : frame;
                   1217:        xpr_ev_cursor("changeCursor %d\n",evg->frame,2,3,4,5);
                   1218:        moveCursor();
                   1219: }
                   1220: 
                   1221: //
                   1222: // Return the screen number in which point p lies.  Return -1 if the point
                   1223: // lies outside of all registered screens.
                   1224: //
                   1225: int IOHIDSystem::pointToScreen(Point * p)
                   1226: {
                   1227:     int i;
                   1228:     EvScreen *screen = (EvScreen *)evScreen;
                   1229:     for (i=screens; --i != -1; ) {
                   1230:        if (screen[i].instance != 0
                   1231:        && (p->x >= screen[i].bounds->minx)
                   1232:        && (p->x < screen[i].bounds->maxx)
                   1233:        && (p->y >= screen[i].bounds->miny)
                   1234:        && (p->y < screen[i].bounds->maxy))
                   1235:            return i;
                   1236:     }
                   1237:     return(-1);        /* Cursor outside of known screen boundary */
                   1238: }
                   1239: 
                   1240: //
                   1241: // API used to manipulate screen brightness
                   1242: //
                   1243: // On entry to each of these, the driverLock should be set.
                   1244: //
                   1245: // Set the current brightness
                   1246: void IOHIDSystem::setBrightness(int b)
                   1247: {
                   1248:        if ( b < EV_SCREEN_MIN_BRIGHTNESS )
                   1249:                b = EV_SCREEN_MIN_BRIGHTNESS;
                   1250:        else if ( b > EV_SCREEN_MAX_BRIGHTNESS )
                   1251:                b = EV_SCREEN_MAX_BRIGHTNESS;
                   1252:        if ( b != curBright )
                   1253:        {
                   1254:            curBright = b;
                   1255:            if ( autoDimmed == false )
                   1256:                setBrightness();
                   1257:        }
                   1258: }
                   1259: 
                   1260: int IOHIDSystem::brightness()
                   1261: {
                   1262:        return curBright;
                   1263: }
                   1264: 
                   1265: // Set the current brightness
                   1266: void IOHIDSystem::setAutoDimBrightness(int b)
                   1267: {
                   1268:        if ( b < EV_SCREEN_MIN_BRIGHTNESS )
                   1269:                b = EV_SCREEN_MIN_BRIGHTNESS;
                   1270:        else if ( b > EV_SCREEN_MAX_BRIGHTNESS )
                   1271:                b = EV_SCREEN_MAX_BRIGHTNESS;
                   1272:        if ( b != dimmedBrightness )
                   1273:        {
                   1274:            dimmedBrightness = b;
                   1275:            if ( autoDimmed == true )
                   1276:                setBrightness();
                   1277:        }
                   1278: }
                   1279: 
                   1280: int IOHIDSystem::autoDimBrightness()
                   1281: {
                   1282:        return dimmedBrightness;
                   1283: }
                   1284: 
                   1285: int IOHIDSystem::currentBrightness()           // Return the current brightness
                   1286: {
                   1287:        if ( autoDimmed == true && dimmedBrightness < curBright )
                   1288:                return dimmedBrightness;
                   1289:        else
                   1290:                return curBright;
                   1291: }
                   1292: 
                   1293: void IOHIDSystem::doAutoDim()
                   1294: {
                   1295:        autoDimmed = true;
                   1296:        setBrightness();
                   1297: }
                   1298: 
                   1299: // Return display brightness to normal
                   1300: void IOHIDSystem::undoAutoDim()
                   1301: {
                   1302:        autoDimmed = false;
                   1303:        setBrightness();
                   1304: }
                   1305: 
                   1306: void IOHIDSystem::forceAutoDimState(bool dim)
                   1307: {
                   1308:        if ( dim == true )
                   1309:        {
                   1310:            if ( autoDimmed == false )
                   1311:            {
                   1312:                if ( eventsOpen == true )
                   1313:                     clock_get_uptime( &autoDimTime);
                   1314:                doAutoDim();
                   1315:            }
                   1316:        }
                   1317:        else
                   1318:        {
                   1319:            if ( autoDimmed == true )
                   1320:            {
                   1321:                 if ( eventsOpen == true ) {
                   1322:                     clock_get_uptime( &autoDimTime);
                   1323:                     ADD_ABSOLUTETIME( &autoDimTime, &autoDimPeriod);
                   1324:                 }
                   1325:                undoAutoDim();
                   1326:            }
                   1327:        }
                   1328: }
                   1329: 
                   1330: //
                   1331: // API used to manipulate sound volume/attenuation
                   1332: //
                   1333: // Set the current brightness.
                   1334: void IOHIDSystem::setAudioVolume(int v)
                   1335: {
                   1336:        if ( v < EV_AUDIO_MIN_VOLUME )
                   1337:                v = EV_AUDIO_MIN_VOLUME;
                   1338:        else if ( v > EV_AUDIO_MAX_VOLUME )
                   1339:                v = EV_AUDIO_MAX_VOLUME;
                   1340:        curVolume = v;
                   1341: }
                   1342: 
                   1343: //
                   1344: // Volume set programatically, rather than from keyboard
                   1345: //
                   1346: void IOHIDSystem::setUserAudioVolume(int v)
                   1347: {
                   1348:        setAudioVolume(v);
                   1349:        // Let sound driver know about the change
                   1350:        evSpecialKeyMsg(        NX_KEYTYPE_SOUND_UP,
                   1351:                /* direction */ NX_KEYDOWN,
                   1352:                /* flags */     0,
                   1353:                /* level */     curVolume);
                   1354: }
                   1355: 
                   1356: int IOHIDSystem::audioVolume()
                   1357: {
                   1358:        return curVolume;
                   1359: }
                   1360: 
                   1361: //
                   1362: // API used to drive event state out to attached screens
                   1363: //
                   1364: // On entry to each of these, the driverLock should be set.
                   1365: //
                   1366: void IOHIDSystem::setBrightness()              // Propagate state out to screens
                   1367: {
                   1368:        int i;
                   1369:        for ( i = 0; i < screens; ++i )
                   1370:                evDispatch(i, /* command */ EVLEVEL);
                   1371: }
                   1372: void IOHIDSystem::showCursor()
                   1373: {
                   1374:        evDispatch(currentScreen, /* command */ EVSHOW);
                   1375: }
                   1376: void IOHIDSystem::hideCursor()
                   1377: {
                   1378:        evDispatch(currentScreen, /* command */ EVHIDE);
                   1379: }
                   1380: void IOHIDSystem::moveCursor()
                   1381: {
                   1382:        evDispatch(currentScreen, /* command */ EVMOVE);
                   1383: }
                   1384: 
                   1385: //
                   1386: // - attachDefaultEventSources
                   1387: //     Attach the default event sources.
                   1388: //
                   1389: void IOHIDSystem::attachDefaultEventSources()
                   1390: {
                   1391:        OSObject  *     source;
                   1392:        OSIterator *    sources;
                   1393: 
                   1394: 
                   1395:         sources = getProviderIterator();
                   1396: 
                   1397:         if (!sources)  return;
                   1398: 
                   1399:        while( (source = sources->getNextObject())) {
                   1400:            if (OSDynamicCast(IOHIDevice, source)) {
                   1401: 
                   1402:                registerEventSource((IOHIDevice *)source);
                   1403:           }
                   1404:        }
                   1405:         sources->release();
                   1406: }
                   1407: 
                   1408: //
                   1409: // - detachEventSources
                   1410: //     Detach all event sources
                   1411: //
                   1412: void IOHIDSystem::detachEventSources()
                   1413: {
                   1414:        OSIterator * iter;
                   1415:        IOHIDevice * srcInstance;
                   1416: 
                   1417:        iter = getOpenProviderIterator();
                   1418:        if( iter) {
                   1419:             while( (srcInstance = (IOHIDevice *) iter->getNextObject())) {
                   1420: #ifdef DEBUG
                   1421:                 kprintf("detachEventSource:%s\n", srcInstance->getName());
                   1422: #endif
                   1423:                 srcInstance->close(this);
                   1424:            }
                   1425:            iter->release();
                   1426:        }
                   1427: }
                   1428: 
                   1429: //
                   1430: // EventSrcClient implementation
                   1431: //
                   1432: 
                   1433: //
                   1434: // A new device instance desires to be added to our list.
                   1435: // Try to get ownership of the device. If we get it, add it to
                   1436: // the list.
                   1437: // 
                   1438: bool IOHIDSystem::registerEventSource(IOHIDevice * source)
                   1439: {
                   1440:        bool success = false;
                   1441: 
                   1442: #ifdef DEBUG
                   1443:         kprintf("registerEventSource:%s\n", ((IOHIDevice*)source)->getName());
                   1444: #endif
                   1445: 
                   1446:        if ( OSDynamicCast(IOHIKeyboard, source) ) {
                   1447:            success = ((IOHIKeyboard*)source)->open(this, kIOServiceSeize,
                   1448:                        (KeyboardEventAction)        _keyboardEvent, 
                   1449:                        (KeyboardSpecialEventAction) _keyboardSpecialEvent,
                   1450:                        (UpdateEventFlagsAction)     _updateEventFlags);
                   1451:        } else if ( OSDynamicCast(IOHIPointing, source) ) {
                   1452:            success = ((IOHIPointing*)source)->open(this, kIOServiceSeize,
                   1453:                        (RelativePointerEventAction) _relativePointerEvent,
                   1454:                        (AbsolutePointerEventAction) _absolutePointerEvent,
                   1455:                        (ScrollWheelEventAction)     _scrollWheelEvent);
                   1456:        }
                   1457: 
                   1458:        if ( success == false )
                   1459:             IOLog("%s: Sieze of %s failed.\n", getName(), source->getName());
                   1460: 
                   1461:        return success;
                   1462: }
                   1463: 
                   1464: IOReturn IOHIDSystem::message(UInt32 type, IOService * provider,
                   1465:                                void * argument)
                   1466: {
                   1467:   IOReturn     status = kIOReturnSuccess;
                   1468: 
                   1469:   switch (type)
                   1470:   {
                   1471:     case kIOMessageServiceIsTerminated:
                   1472: #ifdef DEBUG
                   1473:       kprintf("detachEventSource:%s\n", provider->getName());
                   1474: #endif
                   1475:       provider->close( this );
                   1476:     case kIOMessageServiceWasClosed:
                   1477:       break;
                   1478: 
                   1479:     default:
                   1480:       status = super::message(type, provider, argument);
                   1481:       break;
                   1482:   }
                   1483: 
                   1484:   return status;
                   1485: }
                   1486: 
                   1487: //
                   1488: // This will scale the point at location in the coordinate system represented by bounds
                   1489: // to the coordinate system of the current screen.
                   1490: // This is needed for absolute pointer events that come from devices with different bounds.
                   1491: //
                   1492: void IOHIDSystem::_scaleLocationToCurrentScreen(Point *location, Bounds *bounds)
                   1493: {
                   1494:     Bounds *screenBounds = ((EvScreen*)evScreen)[currentScreen].bounds;
                   1495: 
                   1496:     // We probably also need to look at current screen offsets as well
                   1497:     // but that shouldn't matter until we provide tablets with a way to
                   1498:     // switch screens...
                   1499:     location->x = ((location->x - bounds->minx) * (screenBounds->maxx - screenBounds->minx) / (bounds->maxx - bounds->minx)) + screenBounds->minx;
                   1500:     location->y = ((location->y - bounds->miny) * (screenBounds->maxy - screenBounds->miny) / (bounds->maxy - bounds->miny)) + screenBounds->miny;
                   1501: 
                   1502:     return;
                   1503: }
                   1504: 
                   1505: 
                   1506: //
                   1507: // Process a mouse status change.  The driver should sign extend
                   1508: // it's deltas and perform any bit flipping needed there.
                   1509: //
                   1510: // We take the state as presented and turn it into events.
                   1511: // 
                   1512: void IOHIDSystem::_relativePointerEvent(IOHIDSystem * self,
                   1513:                                    int        buttons,
                   1514:                        /* deltaX */ int        dx,
                   1515:                        /* deltaY */ int        dy,
                   1516:                        /* atTime */ AbsoluteTime ts)
                   1517: {
                   1518:        self->relativePointerEvent(buttons, dx, dy, ts);
                   1519: }
                   1520: 
                   1521: void IOHIDSystem::relativePointerEvent(int        buttons,
                   1522:                           /* deltaX */ int        dx,
                   1523:                           /* deltaY */ int        dy,
                   1524:                           /* atTime */ AbsoluteTime ts)
                   1525: {
                   1526:         if ( displayManager != NULL )          // if there is a display manager, tell
                   1527:             displayManager->activityTickle(0,0);       // it there is user activity
                   1528: 
                   1529:         IOTakeLock( driverLock);
                   1530:        if ( eventsOpen == false )
                   1531:        {
                   1532:                IOUnlock( driverLock);
                   1533:                return;
                   1534:        }
                   1535:        // Fake up pressure changes from button state changes
                   1536:        if ( (buttons & EV_LB) != (evg->buttons & EV_LB) )
                   1537:        {
                   1538:            if ( buttons & EV_LB )
                   1539:                lastPressure = MAXPRESSURE;
                   1540:            else
                   1541:                lastPressure = MINPRESSURE;
                   1542:        }
                   1543:        _setButtonState(buttons, /* atTime */ ts);
                   1544: 
                   1545: //IOLog("{%d,%d}\n\033M", dx,dy);
                   1546:        // figure cursor movement
                   1547:        if ( dx || dy )
                   1548:        {
                   1549:            pointerLoc.x += dx;
                   1550:            pointerLoc.y += dy;
                   1551:             pointerDelta.x += dx;
                   1552:             pointerDelta.y += dy;
                   1553:            _setCursorPosition(&pointerLoc);
                   1554:        }
                   1555:        IOUnlock( driverLock);
                   1556: }
                   1557: 
                   1558: void IOHIDSystem::_absolutePointerEvent(IOHIDSystem * self,
                   1559:                                       int        buttons,
                   1560:                  /* at */              Point *    newLoc,
                   1561:                  /* withBounds */      Bounds *   bounds,
                   1562:                  /* inProximity */     bool       proximity,
                   1563:                  /* withPressure */    int        pressure,
                   1564:                  /* withAngle */       int        stylusAngle,
                   1565:                  /* atTime */          AbsoluteTime ts)
                   1566: {
                   1567:        self->absolutePointerEvent(buttons, newLoc, bounds, proximity,
                   1568:                                        pressure, stylusAngle, ts);
                   1569: }
                   1570: 
                   1571: void IOHIDSystem::absolutePointerEvent(int        buttons,
                   1572:                     /* at */           Point *    newLoc,
                   1573:                     /* withBounds */   Bounds *   bounds,
                   1574:                     /* inProximity */  bool       proximity,
                   1575:                     /* withPressure */ int        pressure,
                   1576:                     /* withAngle */    int        /* stylusAngle */,
                   1577:                     /* atTime */       AbsoluteTime ts)
                   1578:                
                   1579: {
                   1580:   /*
                   1581:    * If you don't know what to pass for the following fields, pass the
                   1582:    * default values below:
                   1583:    *    pressure    = MINPRESSURE or MAXPRESSURE
                   1584:    *    stylusAngle = 90
                   1585:    */
                   1586: 
                   1587:        NXEventData outData;    /* dummy data */
                   1588: 
                   1589:         if ( displayManager != NULL ) {                        // if there is a display manager, tell
                   1590:             displayManager->activityTickle(0,0);               // it there is user activity
                   1591:         }
                   1592: 
                   1593:         IOTakeLock( driverLock);
                   1594:        if ( eventsOpen == false )
                   1595:        {
                   1596:                IOUnlock( driverLock);
                   1597:                return;
                   1598:        }
                   1599:        
                   1600:        lastPressure = pressure;
                   1601: 
                   1602:         _scaleLocationToCurrentScreen(newLoc, bounds);
                   1603:        if ( newLoc->x != pointerLoc.x || newLoc->y != pointerLoc.y )
                   1604:        {
                   1605:             pointerDelta.x += (newLoc->x - pointerLoc.x);
                   1606:             pointerDelta.y += (newLoc->y - pointerLoc.y);
                   1607:            pointerLoc = *newLoc;
                   1608:            _setCursorPosition(&pointerLoc);
                   1609:        }
                   1610:        if ( lastProximity != proximity && proximity == true )
                   1611:        {
                   1612:            evg->eventFlags |= NX_STYLUSPROXIMITYMASK;
                   1613:            bzero( (char *)&outData, sizeof outData );
                   1614:            postEvent(         NX_FLAGSCHANGED,
                   1615:                /* at */       (Point *)&pointerLoc,
                   1616:                /* atTime */   ts,
                   1617:                /* withData */ &outData);
                   1618:        }
                   1619:        if ( proximity == true )
                   1620:             _setButtonState(buttons, /* atTime */ ts);
                   1621:        if ( lastProximity != proximity && proximity == false )
                   1622:        {
                   1623:            evg->eventFlags &= ~NX_STYLUSPROXIMITYMASK;
                   1624:            bzero( (char *)&outData, sizeof outData );
                   1625:            postEvent(         NX_FLAGSCHANGED,
                   1626:                /* at */       (Point *)&pointerLoc,
                   1627:                /* atTime */   ts,
                   1628:                /* withData */ &outData);
                   1629:        }
                   1630:        lastProximity = proximity;
                   1631:        IOUnlock( driverLock);
                   1632: }
                   1633: 
                   1634: void IOHIDSystem::_scrollWheelEvent(IOHIDSystem * self,
                   1635:                                     short      deltaAxis1,
                   1636:                                     short      deltaAxis2,
                   1637:                                     short      deltaAxis3,
                   1638:                  /* atTime */       AbsoluteTime ts)
                   1639: {
                   1640:         self->scrollWheelEvent(deltaAxis1, deltaAxis2, deltaAxis3, ts);
                   1641: }
                   1642: 
                   1643: void IOHIDSystem::scrollWheelEvent(short       deltaAxis1,
                   1644:                                    short       deltaAxis2,
                   1645:                                    short       deltaAxis3,
                   1646:                     /* atTime */   AbsoluteTime ts)
                   1647: 
                   1648: {
                   1649:     NXEventData wheelData;
                   1650: 
                   1651:     if ((deltaAxis1 == 0) && (deltaAxis2 == 0) && (deltaAxis3 == 0)) {
                   1652:         return;
                   1653:     } 
                   1654: 
                   1655:     IOTakeLock( driverLock);
                   1656:     if (!eventsOpen)
                   1657:     {
                   1658:             IOUnlock(driverLock);
                   1659:             return;
                   1660:     }
                   1661: 
                   1662:     bzero((char *)&wheelData, sizeof wheelData);
                   1663:     wheelData.scrollWheel.deltaAxis1 = deltaAxis1;
                   1664:     wheelData.scrollWheel.deltaAxis2 = deltaAxis2;
                   1665:     wheelData.scrollWheel.deltaAxis3 = deltaAxis3;
                   1666:     
                   1667:     postEvent(             NX_SCROLLWHEELMOVED,
                   1668:             /* at */       (Point *)&evg->cursorLoc,
                   1669:             /* atTime */   ts,
                   1670:             /* withData */ &wheelData);
                   1671: 
                   1672:     IOUnlock(driverLock);
                   1673:     return;
                   1674: }
                   1675: 
                   1676: void IOHIDSystem::_tabletEvent(IOHIDSystem *self,
                   1677:                                NXEventData *tabletData,
                   1678:                                AbsoluteTime ts)
                   1679: {
                   1680:     self->tabletEvent(tabletData, ts);
                   1681: }
                   1682: 
                   1683: void IOHIDSystem::tabletEvent(NXEventData *tabletData,
                   1684:                               AbsoluteTime ts)
                   1685: {
                   1686:     IOTakeLock(driverLock);
                   1687:     
                   1688:     if (eventsOpen) {
                   1689:         postEvent(NX_TABLETPOINTER,
                   1690:                   (Point *)&evg->cursorLoc,
                   1691:                   ts,
                   1692:                   tabletData);
                   1693:     }
                   1694: 
                   1695:     IOUnlock(driverLock);
                   1696: 
                   1697:     return;
                   1698: }
                   1699: 
                   1700: void IOHIDSystem::_proximityEvent(IOHIDSystem *self,
                   1701:                                   NXEventData *proximityData,
                   1702:                                   AbsoluteTime ts)
                   1703: {
                   1704:     self->proximityEvent(proximityData, ts);
                   1705: }
                   1706: 
                   1707: void IOHIDSystem::proximityEvent(NXEventData *proximityData,
                   1708:                                  AbsoluteTime ts)
                   1709: {
                   1710:     IOTakeLock(driverLock);
                   1711: 
                   1712:     if (eventsOpen) {
                   1713:         postEvent(NX_TABLETPROXIMITY,
                   1714:                   (Point *)&evg->cursorLoc,
                   1715:                   ts,
                   1716:                   proximityData);
                   1717:     }
                   1718: 
                   1719:     IOUnlock(driverLock);
                   1720: 
                   1721:     return;
                   1722: }
                   1723: 
                   1724: //
                   1725: // Process a keyboard state change.
                   1726: // 
                   1727: void IOHIDSystem::_keyboardEvent(IOHIDSystem * self,
                   1728:                                unsigned   eventType,
                   1729:          /* flags */            unsigned   flags,
                   1730:          /* keyCode */          unsigned   key,
                   1731:          /* charCode */         unsigned   charCode,
                   1732:          /* charSet */          unsigned   charSet,
                   1733:          /* originalCharCode */ unsigned   origCharCode,
                   1734:          /* originalCharSet */  unsigned   origCharSet,
                   1735:          /* repeat */           bool       repeat,
                   1736:          /* atTime */           AbsoluteTime ts)
                   1737: {
                   1738:        self->keyboardEvent(eventType, flags, key, charCode, charSet,
                   1739:                                origCharCode, origCharSet, repeat, ts);
                   1740: }
                   1741: 
                   1742: void IOHIDSystem::keyboardEvent(unsigned   eventType,
                   1743:          /* flags */            unsigned   flags,
                   1744:          /* keyCode */          unsigned   key,
                   1745:          /* charCode */         unsigned   charCode,
                   1746:          /* charSet */          unsigned   charSet,
                   1747:          /* originalCharCode */ unsigned   origCharCode,
                   1748:          /* originalCharSet */  unsigned   origCharSet,
                   1749:          /* repeat */           bool       repeat,
                   1750:          /* atTime */           AbsoluteTime ts)
                   1751: {
                   1752:        NXEventData     outData;
                   1753: 
                   1754:         if ( displayManager != NULL ) {                        // if there is a display manager, tell
                   1755:             displayManager->activityTickle(0,0);               // it there is user activity
                   1756:         }
                   1757: 
                   1758:         outData.key.repeat = repeat;
                   1759:        outData.key.keyCode = key;
                   1760:        outData.key.charSet = charSet;
                   1761:        outData.key.charCode = charCode;
                   1762:        outData.key.origCharSet = origCharSet;
                   1763:        outData.key.origCharCode = origCharCode;
                   1764: 
                   1765:        IOTakeLock( driverLock);
                   1766:        if ( eventsOpen == false )
                   1767:        {
                   1768:                IOUnlock( driverLock);
                   1769:                return;
                   1770:        }
                   1771:        evg->eventFlags = (evg->eventFlags & ~KEYBOARD_FLAGSMASK)
                   1772:                        | (flags & KEYBOARD_FLAGSMASK);
                   1773: 
                   1774:        postEvent(             eventType,
                   1775:                /* at */       (Point *)&pointerLoc,
                   1776:                /* atTime */   ts,
                   1777:                /* withData */ &outData);
                   1778: 
                   1779:        IOUnlock( driverLock);
                   1780: }
                   1781: 
                   1782: void IOHIDSystem::_keyboardSpecialEvent(IOHIDSystem * self,
                   1783:                                        unsigned   eventType,
                   1784:                        /* flags */             unsigned   flags,
                   1785:                        /* keyCode  */          unsigned   key,
                   1786:                        /* specialty */         unsigned   flavor,
                   1787:                        /* atTime */            AbsoluteTime ts)
                   1788: {
                   1789:        self->keyboardSpecialEvent(eventType, flags, key, flavor, ts);
                   1790: }
                   1791: 
                   1792: 
                   1793: void IOHIDSystem::keyboardSpecialEvent(unsigned   eventType,
                   1794:                        /* flags */     unsigned   flags,
                   1795:                        /* keyCode  */  unsigned   /* key */,
                   1796:                        /* specialty */ unsigned   flavor,
                   1797:                        /* atTime */    AbsoluteTime ts)
                   1798: {
                   1799:        NXEventData     outData;
                   1800:        int             level = -1;
                   1801: 
                   1802:        bzero( (void *)&outData, sizeof outData );
                   1803: 
                   1804:        IOTakeLock( driverLock);
                   1805:        if ( eventsOpen == false )
                   1806:        {
                   1807:                IOUnlock( driverLock);
                   1808:                return;
                   1809:        }
                   1810:        // Update flags.
                   1811:        evg->eventFlags = (evg->eventFlags & ~KEYBOARD_FLAGSMASK)
                   1812:                        | (flags & KEYBOARD_FLAGSMASK);
                   1813:        // Most of these keys don't generate events.  Forcibly undo autodim.
                   1814:        if ( autoDimmed == true )
                   1815:                forceAutoDimState(false);
                   1816:        if ( eventType == NX_KEYDOWN )
                   1817:        {
                   1818:                switch ( flavor )
                   1819:                {
                   1820:                        case NX_KEYTYPE_SOUND_UP:
                   1821:                             if ( (flags & SPECIALKEYS_MODIFIER_MASK) == 0 ) {
                   1822:                                 level = IOAudioManager::sharedInstance()->incrementMasterVolume();
                   1823:                             }
                   1824:                            break;
                   1825:                        case NX_KEYTYPE_SOUND_DOWN:
                   1826:                             if ( (flags & SPECIALKEYS_MODIFIER_MASK) == 0 ) {
                   1827:                                 level = IOAudioManager::sharedInstance()->decrementMasterVolume();
                   1828:                             }
                   1829:                            break;
                   1830:                         case NX_KEYTYPE_MUTE:
                   1831:                             if ( (flags & SPECIALKEYS_MODIFIER_MASK) == 0 ) {
                   1832:                                 level = IOAudioManager::sharedInstance()->toggleMasterMute();
                   1833:                             }
                   1834:                             break;
                   1835:                        case NX_KEYTYPE_BRIGHTNESS_UP:
                   1836:                            if ( (flags & SPECIALKEYS_MODIFIER_MASK) == 0 )
                   1837:                                setBrightness(brightness() + 1);
                   1838:                            level = brightness();
                   1839:                            break;
                   1840:                        case NX_KEYTYPE_BRIGHTNESS_DOWN:
                   1841:                            if ( (flags & SPECIALKEYS_MODIFIER_MASK) == 0 )
                   1842:                                setBrightness(brightness() - 1);
                   1843:                            level = brightness();
                   1844:                            break;
                   1845:                        case NX_POWER_KEY:
                   1846:                                outData.compound.subType = 1;
                   1847:                                postEvent(             NX_SYSDEFINED,
                   1848:                                        /* at */       (Point *)&pointerLoc,
                   1849:                                        /* atTime */   ts,
                   1850:                                        /* withData */ &outData);
                   1851:                                break;
                   1852:                }
                   1853:        }
                   1854: #if 0  /* So far, nothing to do on keyup */
                   1855:        else if ( eventType == NX_KEYUP )
                   1856:        {
                   1857:                switch ( flavor )
                   1858:                {
                   1859:                        case NX_KEYTYPE_SOUND_UP:
                   1860:                                break;
                   1861:                        case NX_KEYTYPE_SOUND_DOWN:
                   1862:                                break;
                   1863:                        case NX_KEYTYPE_BRIGHTNESS_UP:
                   1864:                                break;
                   1865:                        case NX_KEYTYPE_BRIGHTNESS_DOWN:
                   1866:                                break;
                   1867:                        case NX_POWER_KEY:
                   1868:                                break;
                   1869:                }
                   1870:        }
                   1871: #endif
                   1872:        IOUnlock( driverLock);
                   1873:        if ( level != -1 )      // An interesting special key event occurred
                   1874:        {
                   1875:                evSpecialKeyMsg(        flavor,
                   1876:                        /* direction */ eventType,
                   1877:                        /* flags */     flags,
                   1878:                        /* level */     level);
                   1879:        }
                   1880: }
                   1881: 
                   1882: /*
                   1883:  * Update current event flags.  Restricted to keyboard flags only, this
                   1884:  * method is used to silently update the flags state for keys which both
                   1885:  * generate characters and flag changes.  The specs say we don't generate
                   1886:  * a flags-changed event for such keys.  This method is also used to clear
                   1887:  * the keyboard flags on a keyboard subsystem reset.
                   1888:  */
                   1889: void IOHIDSystem::_updateEventFlags(IOHIDSystem * self, unsigned flags)
                   1890: {
                   1891:     self->updateEventFlags(flags);
                   1892: }
                   1893: 
                   1894: void IOHIDSystem::updateEventFlags(unsigned flags)
                   1895: {
                   1896:        IOTakeLock( driverLock);
                   1897:        if ( eventsOpen )
                   1898:            evg->eventFlags = (evg->eventFlags & ~KEYBOARD_FLAGSMASK)
                   1899:                            | (flags & KEYBOARD_FLAGSMASK);
                   1900:        IOUnlock( driverLock);
                   1901: }
                   1902: 
                   1903: //
                   1904: // - _setButtonState:(int)buttons  atTime:(int)t
                   1905: //     Update the button state.  Generate button events as needed
                   1906: //
                   1907: void IOHIDSystem::_setButtonState(int buttons,
                   1908:                                   /* atTime */ AbsoluteTime ts)
                   1909: {
                   1910:        if ((evg->buttons & EV_LB) != (buttons & EV_LB))
                   1911:        {
                   1912:            if (buttons & EV_LB)
                   1913:            {
                   1914:                postEvent(             NX_LMOUSEDOWN,
                   1915:                        /* at */       (Point *)&evg->cursorLoc,
                   1916:                        /* atTime */   ts,
                   1917:                        /* withData */ NULL);
                   1918:                evg->buttons |= EV_LB;
                   1919:            }
                   1920:            else
                   1921:            {
                   1922:                postEvent(             NX_LMOUSEUP,
                   1923:                        /* at */       (Point *)&evg->cursorLoc,
                   1924:                        /* atTime */   ts,
                   1925:                        /* withData */ NULL);
                   1926:                evg->buttons &= ~EV_LB;
                   1927:            }
                   1928:            // After entering initial up/down event, set up
                   1929:            // coalescing state so drags will behave correctly
                   1930:            evg->dontCoalesce = evg->dontWantCoalesce;
                   1931:            if (evg->dontCoalesce)
                   1932:                evg->eventFlags |= NX_NONCOALSESCEDMASK;
                   1933:            else
                   1934:                evg->eventFlags &= ~NX_NONCOALSESCEDMASK;
                   1935:        }
                   1936:     
                   1937:        if ((evg->buttons & EV_RB) != (buttons & EV_RB)) {
                   1938:            if (buttons & EV_RB) {
                   1939:                postEvent(             NX_RMOUSEDOWN,
                   1940:                        /* at */       (Point *)&evg->cursorLoc,
                   1941:                        /* atTime */   ts,
                   1942:                        /* withData */ NULL);
                   1943:                evg->buttons |= EV_RB;
                   1944:            } else {
                   1945:                postEvent(             NX_RMOUSEUP,
                   1946:                        /* at */       (Point *)&evg->cursorLoc,
                   1947:                        /* atTime */   ts,
                   1948:                        /* withData */ NULL);
                   1949:                evg->buttons &= ~EV_RB;
                   1950:            }
                   1951:        }
                   1952: }
                   1953: //
                   1954: //  Sets the cursor position (evg->cursorLoc) to the new
                   1955: //  location.  The location is clipped against the cursor pin rectangle,
                   1956: //  mouse moved/dragged events are generated using the given event mask,
                   1957: //  and a mouse-exited event may be generated. The cursor image is
                   1958: //  moved.
                   1959: //  On entry, the driverLock should be set.
                   1960: //
                   1961: void IOHIDSystem::setCursorPosition(Point * newLoc)
                   1962: {
                   1963:        if ( eventsOpen == true )
                   1964:        {
                   1965:             pointerDelta.x += (newLoc->x - pointerLoc.x);
                   1966:             pointerDelta.y += (newLoc->y - pointerLoc.y);
                   1967:            pointerLoc = *newLoc;
                   1968:            _setCursorPosition(newLoc);
                   1969:        }
                   1970: }
                   1971: 
                   1972: //
                   1973: // This mechanism is used to update the cursor position, possibly generating
                   1974: // messages to registered frame buffer devices and posting drag, tracking, and
                   1975: // mouse motion events.
                   1976: //
                   1977: // On entry, the driverLock should be set.
                   1978: // This can be called from setCursorPosition:(Point *)newLoc to set the
                   1979: // position by a _IOSetParameterFromIntArray() call, directly from the absolute or
                   1980: // relative pointer device routines, or on a timed event callback.
                   1981: //
                   1982: void IOHIDSystem::_setCursorPosition(Point * newLoc)
                   1983: {
                   1984:        int newScreen = -1;
                   1985:     
                   1986:        if (!screens || !cursorEnabled)
                   1987:            return;
                   1988: 
                   1989:        if ( ev_try_lock(&evg->cursorSema) == 0 ) // host using shmem
                   1990:        {
                   1991:                needSetCursorPosition = true;     // try again later
                   1992: //             scheduleNextPeriodicEvent();
                   1993:                return;
                   1994:        }
                   1995:        // Past here we hold the cursorSema lock.  Make sure the lock is
                   1996:        // cleared before returning or the system will be wedged.
                   1997:        
                   1998:        needSetCursorPosition = false;    // We WILL succeed
                   1999: 
                   2000:        /* Check to see if cursor ventured outside of current screen bounds
                   2001:            before worrying about which screen it may have gone to. */
                   2002:     
                   2003:        if (!PtInRect(newLoc, ((EvScreen*)evScreen)[currentScreen].bounds)) {
                   2004:            /* At this point cursor has gone off screen.  Check to see if moved
                   2005:                to another screen.  If not, just clip it to current screen. */
                   2006:     
                   2007:            if ((newScreen = pointToScreen(newLoc)) < 0) {
                   2008:                /* Pin new cursor position to cursorPin rect */
                   2009:                newLoc->x = (newLoc->x < cursorPin.minx) ?
                   2010:                    cursorPin.minx : ((newLoc->x > cursorPin.maxx) ?
                   2011:                    cursorPin.maxx : newLoc->x);
                   2012:                newLoc->y = (newLoc->y < cursorPin.miny) ?
                   2013:                    cursorPin.miny : ((newLoc->y > cursorPin.maxy) ?
                   2014:                    cursorPin.maxy : newLoc->y);
                   2015:            }
                   2016:        }
                   2017: 
                   2018:        pointerLoc = *newLoc;   // Sync up pointer with clipped cursor
                   2019:        /* Catch the no-move case */
                   2020:        if (evg->cursorLoc.x == newLoc->x && evg->cursorLoc.y == newLoc->y)
                   2021:        {
                   2022:            ev_unlock(&evg->cursorSema);
                   2023:            return;
                   2024:        }    
                   2025:        evg->cursorLoc.x = newLoc->x;
                   2026:        evg->cursorLoc.y = newLoc->y;
                   2027: 
                   2028:        /* If newScreen is zero or positive, then cursor crossed screens */
                   2029:        if (newScreen >= 0) {
                   2030:            /* cursor changed screens */
                   2031:            hideCursor();       /* hide cursor on old screen */
                   2032:            currentScreen = newScreen;
                   2033:            cursorPin = *(((EvScreen*)evScreen)[currentScreen].bounds);
                   2034:            cursorPin.maxx--;   /* Make half-open rectangle */
                   2035:            cursorPin.maxy--;
                   2036:            showCursor();
                   2037:        } else {
                   2038:            /* cursor moved on same screen */
                   2039:            moveCursor();
                   2040:        }
                   2041: 
                   2042:         AbsoluteTime   ts;
                   2043:         clock_get_uptime(&ts);
                   2044:         
                   2045:        /* See if anybody wants the mouse moved or dragged events */
                   2046:        if (evg->movedMask) {
                   2047:            if ((evg->movedMask&NX_LMOUSEDRAGGEDMASK)&&(evg->buttons& EV_LB))
                   2048:                 _postMouseMoveEvent(NX_LMOUSEDRAGGED, newLoc, ts);
                   2049:            else
                   2050:                if ((evg->movedMask&NX_RMOUSEDRAGGEDMASK) &&
                   2051:                (evg->buttons & EV_RB))
                   2052:                     _postMouseMoveEvent(NX_RMOUSEDRAGGED, newLoc, ts);
                   2053:                else
                   2054:                    if (evg->movedMask & NX_MOUSEMOVEDMASK)
                   2055:                         _postMouseMoveEvent(NX_MOUSEMOVED, newLoc, ts);
                   2056:        }
                   2057:     
                   2058:        /* check new cursor position for leaving evg->mouseRect */
                   2059:        if (evg->mouseRectValid && (!PtInRect(newLoc, &evg->mouseRect)))
                   2060:        {
                   2061:            if (evg->mouseRectValid)
                   2062:            {
                   2063:                postEvent(             NX_MOUSEEXITED,
                   2064:                        /* at */       newLoc,
                   2065:                        /* atTime */   ts,
                   2066:                        /* withData */ NULL);
                   2067:                evg->mouseRectValid = 0;
                   2068:            }
                   2069:        }
                   2070:        ev_unlock(&evg->cursorSema);
                   2071: }
                   2072: 
                   2073: void IOHIDSystem::_postMouseMoveEvent(int          what,
                   2074:                                      Point *       location,
                   2075:                                      AbsoluteTime  ts)
                   2076: {
                   2077:     NXEventData data;
                   2078: 
                   2079: #if EVENT_SYSTEM_VERSION > 1
                   2080:     data.mouseMove.dx = pointerDelta.x;
                   2081:     data.mouseMove.dy = pointerDelta.y;
                   2082: #endif
                   2083:     pointerDelta.x = 0;
                   2084:     pointerDelta.y = 0;
                   2085: 
                   2086:     postEvent(what, location, ts, &data);
                   2087: }
                   2088: 
                   2089: /**
                   2090:  ** IOUserClient methods
                   2091:  **/
                   2092: 
                   2093: IOReturn IOHIDSystem::newUserClient(task_t         /* owningTask */,
                   2094:                     /* withToken */ void *         /* security_id */,
                   2095:                     /* ofType */    UInt32         type,
                   2096:                     /* client */    IOUserClient ** handler)
                   2097: {
                   2098:     IOUserClient *     newConnect = 0;
                   2099:     IOReturn           err = kIOReturnNoMemory;
                   2100: 
                   2101:     IOTakeLock( driverLock);
                   2102: 
                   2103:     do {
                   2104:        if( type == kIOHIDParamConnectType) {
                   2105:             if( paramConnect) {
                   2106:                 newConnect = paramConnect;
                   2107:                 newConnect->retain();
                   2108:             } else if( eventsOpen) {
                   2109:                 newConnect = new IOHIDParamUserClient;
                   2110:             } else {
                   2111:                 err = kIOReturnNotOpen;
                   2112:                continue;
                   2113:            }
                   2114: 
                   2115:         } else if( type == kIOHIDServerConnectType) {
                   2116:             newConnect = new IOHIDUserClient;
                   2117:        } else
                   2118:            err = kIOReturnUnsupported;
                   2119: 
                   2120:         if( !newConnect)
                   2121:             continue;
                   2122: 
                   2123:         // initialization is getting out of hand
                   2124: 
                   2125:         if( (newConnect != paramConnect) && (
                   2126:            (false == newConnect->init())
                   2127:         || (false == newConnect->attach( this ))
                   2128:         || (false == newConnect->start( this ))
                   2129:         || ((type == kIOHIDServerConnectType)
                   2130:                 && (err = evOpen()))
                   2131:         )) {
                   2132:             newConnect->detach( this );
                   2133:             newConnect->release();
                   2134:             newConnect = 0;
                   2135:            continue;
                   2136:         }
                   2137:         if( type == kIOHIDParamConnectType)
                   2138:             paramConnect = newConnect;
                   2139:        err = kIOReturnSuccess;
                   2140: 
                   2141:     } while( false );
                   2142: 
                   2143:     IOUnlock( driverLock);
                   2144: 
                   2145:     *handler = newConnect;
                   2146:     return( err );
                   2147: }
                   2148: 
                   2149: 
                   2150: IOReturn IOHIDSystem::setEventsEnable(void*p1,void*,void*,void*,void*,void*)
                   2151: {                                                                    // IOMethod
                   2152:     bool enable = (bool)p1;
                   2153: 
                   2154:     if( enable) {
                   2155:         attachDefaultEventSources();
                   2156:         _resetMouseParameters();
                   2157:         _resetKeyboardParameters();
                   2158:     }
                   2159:     return( kIOReturnSuccess);
                   2160: }
                   2161: 
                   2162: IOReturn IOHIDSystem::setCursorEnable(void*p1,void*,void*,void*,void*,void*)
                   2163: {                                                                    // IOMethod
                   2164:     bool               enable = (bool)p1;
                   2165:     IOReturn           err = kIOReturnSuccess;
                   2166: 
                   2167:     IOTakeLock( driverLock);
                   2168:     if ( eventsOpen == false ) {
                   2169:         IOUnlock( driverLock);
                   2170:         return( kIOReturnNotOpen );
                   2171:     }
                   2172: 
                   2173:     if( 0 == screens) {                // Should be at least 1!
                   2174:         IOUnlock( driverLock);
                   2175:         return( kIOReturnNoDevice );
                   2176:     }
                   2177: 
                   2178:     if( enable) {
                   2179:        if( cursorStarted)
                   2180:             cursorEnabled = resetCursor();
                   2181:        else
                   2182:             cursorEnabled = startCursor();
                   2183:     } else
                   2184:         cursorEnabled = enable;
                   2185: 
                   2186:     IOUnlock( driverLock);
                   2187: 
                   2188:     return( err);
                   2189: }
                   2190: 
                   2191: IOReturn IOHIDSystem::extPostEvent(void*p1,void*,void*,void*,void*,void*)
                   2192: {                                                                    // IOMethod
                   2193:     struct evioLLEvent * event = (struct evioLLEvent *)p1;
                   2194: 
                   2195:     IOTakeLock( driverLock);
                   2196: 
                   2197:     if( event->setCursor)
                   2198:         setCursorPosition(&event->location);
                   2199: 
                   2200:     if( event->setFlags)
                   2201:         evg->eventFlags = (evg->eventFlags & ~KEYBOARD_FLAGSMASK)
                   2202:                         | (event->flags & KEYBOARD_FLAGSMASK);
                   2203: 
                   2204:     AbsoluteTime       ts;
                   2205:     clock_get_uptime(&ts);
                   2206:     postEvent(             event->type,
                   2207:             /* at */       &event->location,
                   2208:             /* atTime */   ts,
                   2209:             /* withData */ &event->data);
                   2210: 
                   2211:     IOUnlock( driverLock);
                   2212:     return( kIOReturnSuccess);
                   2213: }
                   2214: 
                   2215: IOReturn IOHIDSystem::extSetMouseLocation(void*p1,void*,void*,void*,void*,void*)
                   2216: {                                                                    // IOMethod
                   2217:     Point * loc = (Point *)p1;
                   2218: 
                   2219:     IOTakeLock( driverLock);
                   2220:     setCursorPosition(loc);
                   2221:     IOUnlock( driverLock);
                   2222:     return( kIOReturnSuccess);
                   2223: }
                   2224: 
                   2225: IOReturn IOHIDSystem::extGetButtonEventNum(void*p1,void*p2,void*,void*,void*,void*)
                   2226: {                                                                    // IOMethod
                   2227:     NXMouseButton button   = (NXMouseButton)(int)p1;
                   2228:     int *         eventNum = (int *)p2;
                   2229:     IOReturn      err      = kIOReturnSuccess;
                   2230: 
                   2231:     IOTakeLock( driverLock);
                   2232:     switch( button) {
                   2233:        case NX_LeftButton:
                   2234:             *eventNum = leftENum;
                   2235:            break;
                   2236:        case NX_RightButton:
                   2237:             *eventNum = rightENum;
                   2238:            break;
                   2239:        default:
                   2240:            err = kIOReturnBadArgument;
                   2241:     }
                   2242: 
                   2243:     IOUnlock( driverLock);
                   2244:     return( err);
                   2245: }
                   2246: 
                   2247: bool IOHIDSystem::updateProperties( void )
                   2248: {
                   2249:     UInt64             clickTimeThreshNano;
                   2250:     UInt64             autoDimThresholdNano;
                   2251:     UInt64             autoDimTimeNano;
                   2252:     UInt64             idleTimeNano;
                   2253:     AbsoluteTime       time1, time2;
                   2254:     bool               ok;
                   2255: 
                   2256:     absolutetime_to_nanoseconds( clickTimeThresh, &clickTimeThreshNano);
                   2257:     absolutetime_to_nanoseconds( autoDimPeriod, &autoDimThresholdNano);
                   2258:     if( eventsOpen) {
                   2259:         clock_get_uptime( &time1);
                   2260:         if( autoDimmed) {
                   2261:             autoDimTimeNano = 0;
                   2262:             // now - (autoDimTime - autoDimPeriod)
                   2263:             SUB_ABSOLUTETIME( &time1, &autoDimTime);
                   2264:             ADD_ABSOLUTETIME( &time1, &autoDimPeriod);
                   2265:             absolutetime_to_nanoseconds( time1, &idleTimeNano);
                   2266:         } else {
                   2267:             // autoDimTime - now
                   2268:             time2 = autoDimTime;
                   2269:             SUB_ABSOLUTETIME( &time2, &time1);
                   2270:             absolutetime_to_nanoseconds( time2, &autoDimTimeNano);
                   2271:             // autoDimPeriod - (autoDimTime - evg->VertRetraceClock)
                   2272:             time1 = autoDimPeriod;
                   2273:             SUB_ABSOLUTETIME( &time1, &time2);
                   2274:             absolutetime_to_nanoseconds( time1, &idleTimeNano);
                   2275:        }
                   2276:     } else {
                   2277:         absolutetime_to_nanoseconds( autoDimPeriod, &autoDimTimeNano);
                   2278:         idleTimeNano = 0;       // user is active
                   2279:     }
                   2280: 
                   2281:     ok = setProperty( kIOHIDClickTimeKey, &clickTimeThreshNano,
                   2282:                 sizeof( UInt64))
                   2283:     &    setProperty( kIOHIDClickSpaceKey, &clickSpaceThresh,
                   2284:                       sizeof( clickSpaceThresh))
                   2285:     &    setProperty( kIOHIDAutoDimThresholdKey, &autoDimThresholdNano,
                   2286:                       sizeof( UInt64))
                   2287:     &    setProperty( kIOHIDAutoDimTimeKey, &autoDimTimeNano,
                   2288:                       sizeof( UInt64))
                   2289:     &    setProperty( kIOHIDIdleTimeKey, &idleTimeNano,
                   2290:                       sizeof( UInt64))
                   2291:     &    setProperty( kIOHIDAutoDimStateKey, &autoDimmed,
                   2292:                       sizeof( autoDimmed))
                   2293:     &    setProperty( kIOHIDBrightnessKey, &curBright,
                   2294:                       sizeof( curBright))
                   2295:     &    setProperty( kIOHIDAutoDimBrightnessKey, &dimmedBrightness,
                   2296:                       sizeof( dimmedBrightness));
                   2297: 
                   2298:     return( ok );
                   2299: }
                   2300: 
                   2301: bool IOHIDSystem::serializeProperties( OSSerialize * s ) const
                   2302: {
                   2303:     ((IOHIDSystem *) this)->updateProperties();
                   2304: 
                   2305:     return( super::serializeProperties( s ));
                   2306: }
                   2307: 
                   2308: IOReturn IOHIDSystem::setParamProperties( OSDictionary * dict )
                   2309: {
                   2310:     OSData *   data;
                   2311:     IOReturn   err = kIOReturnSuccess;
                   2312: 
                   2313:     IOTakeLock( driverLock);
                   2314:     if( (data = OSDynamicCast( OSData, dict->getObject(kIOHIDClickTimeKey))))
                   2315:     {
                   2316:         UInt64         nano = *((UInt64 *)(data->getBytesNoCopy()));
                   2317:         nanoseconds_to_absolutetime(nano, &clickTimeThresh);
                   2318:     }
                   2319:     if( (data = OSDynamicCast( OSData,
                   2320:                dict->getObject(kIOHIDClickSpaceKey)))) {
                   2321:         clickSpaceThresh.x = ((UInt32 *) (data->getBytesNoCopy()))[EVSIOSCS_X];
                   2322:         clickSpaceThresh.y = ((UInt32 *) (data->getBytesNoCopy()))[EVSIOSCS_Y];
                   2323:     }
                   2324: 
                   2325:     if( (data = OSDynamicCast( OSData, dict->getObject(kIOHIDAutoDimThresholdKey)))) {
                   2326:         AbsoluteTime   oldPeriod = autoDimPeriod;
                   2327:         UInt64         nano = *((UInt64 *)(data->getBytesNoCopy()));
                   2328:         nanoseconds_to_absolutetime(nano, &autoDimPeriod);
                   2329:         // autoDimTime = autoDimTime - oldPeriod + autoDimPeriod;
                   2330:         SUB_ABSOLUTETIME( &autoDimTime, &oldPeriod);
                   2331:         ADD_ABSOLUTETIME( &autoDimTime, &autoDimPeriod);
                   2332:     }
                   2333: 
                   2334:     if( (data = OSDynamicCast( OSData, dict->getObject(kIOHIDAutoDimStateKey))))
                   2335:         forceAutoDimState( 0 != *((SInt32 *) (data->getBytesNoCopy())));
                   2336: 
                   2337:     if( (data = OSDynamicCast( OSData, dict->getObject(kIOHIDBrightnessKey))))
                   2338:         setBrightness( *((SInt32 *) (data->getBytesNoCopy())));
                   2339: 
                   2340:     if( (data = OSDynamicCast( OSData, dict->getObject(kIOHIDAutoDimBrightnessKey))))
                   2341:         setAutoDimBrightness( *((SInt32 *) (data->getBytesNoCopy())));
                   2342: 
                   2343:     IOUnlock( driverLock);
                   2344: 
                   2345:     return( err );
                   2346: }
                   2347: 

unix.superglobalmegacorp.com

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