Annotation of XNU/iokit/Families/IOHIDSystem/IOHIDSystem.cpp, revision 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.