Changeset 9894

Show
Ignore:
Timestamp:
03/11/09 11:34:04 (6 years ago)
Author:
robert
Message:

From Stephan Huber, "refactored the code and moved
some stuff out into DarwinUtils?.h/.mm so both implementations can share
some of the code. There's even a bugfix for GraphicsWindowCarbon?, which
fixes some issues with multiple windows on different screens."

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgViewer/GraphicsWindowCarbon.cpp

    r9369 r9894  
    1212*/ 
    1313 
    14 #ifdef __APPLE__ 
     14#if defined (__APPLE__) && (!__LP64__) 
     15 
    1516#include <osg/observer_ptr> 
    1617 
     
    2526#include <iostream> 
    2627 
     28#include "DarwinUtils.h" 
     29 
    2730using namespace osgViewer; 
     31using namespace osgDarwin; 
    2832 
    2933 
     
    6670                        GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &bounds ); 
    6771                         
    68                         w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); 
    69                         w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime()); 
     72                        w->adaptResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); 
    7073                        w->requestRedraw(); 
    7174                        result = noErr; 
     
    7578                        InvalWindowRect(window, GetWindowPortBounds(window, &bounds)); 
    7679                        GetWindowBounds(window, kWindowContentRgn, &bounds); 
    77                         w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); 
    78                         w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime()); 
     80                        w->adaptResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); 
    7981                        result = noErr; 
    8082                        break; 
     
    136138// small helper class which maps the raw key codes to osgGA::GUIEventAdapter::Keys 
    137139 
    138 class OSXKeyboardMap { 
     140class CarbonKeyboardMap { 
    139141 
    140142    public: 
    141         OSXKeyboardMap() 
     143        CarbonKeyboardMap() 
    142144        { 
    143145            _keymap[53                ] =  osgGA::GUIEventAdapter::KEY_Escape; 
     
    188190        } 
    189191         
    190         ~OSXKeyboardMap() { 
     192        ~CarbonKeyboardMap() { 
    191193        } 
    192194         
     
    203205 
    204206/** remaps a native os x keycode to a GUIEventAdapter-keycode */ 
    205 static unsigned int remapOSXKey(unsigned int key, unsigned int rawkey) 
    206 { 
    207     static OSXKeyboardMap s_OSXKeyboardMap; 
    208     return s_OSXKeyboardMap.remapKey(key,rawkey); 
    209 } 
    210  
    211  
    212  
    213  
    214 #pragma mark * * * MenubarController * * *  
    215  
    216 /** the MenubarController class checks all open windows if they intersect with the menubar / dock and hide the menubar/dock if necessary */ 
    217 class MenubarController : public osg::Referenced  
    218 { 
    219  
    220     public: 
    221         MenubarController() :  
    222             osg::Referenced(),  
    223             _list(),  
    224             _menubarShown(false), 
    225             _mutex()  
    226         { 
    227             // the following code will query the system for the available rect on the main-display (typically the displaying showing the menubar + the dock 
    228  
    229             GDHandle mainScreenDevice; 
    230              
    231             DMGetGDeviceByDisplayID((DisplayIDType) CGMainDisplayID(), &mainScreenDevice, true); 
    232             GetAvailableWindowPositioningBounds (mainScreenDevice, &_availRect); 
    233              
    234             // now we need the rect of the main-display including the menubar and the dock 
    235             _mainScreenBounds = CGDisplayBounds( CGMainDisplayID() ); 
    236              
    237             // hide the menubar initially 
    238             SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); 
    239         } 
    240          
    241         static MenubarController* instance(); 
    242          
    243         void attachWindow(GraphicsWindowCarbon* win); 
    244         void update(); 
    245         void detachWindow(GraphicsWindowCarbon* win); 
    246          
    247     private:  
    248         typedef std::list< osg::observer_ptr< GraphicsWindowCarbon > > WindowList; 
    249         WindowList            _list; 
    250         bool                _menubarShown; 
    251         Rect                _availRect; 
    252         CGRect                _mainScreenBounds; 
    253         OpenThreads::Mutex    _mutex; 
    254          
     207static unsigned int remapCarbonKey(unsigned int key, unsigned int rawkey) 
     208{ 
     209    static CarbonKeyboardMap s_CarbonKeyboardMap; 
     210    return s_CarbonKeyboardMap.remapKey(key,rawkey); 
     211} 
     212 
     213 
     214class CarbonWindowAdapter : public MenubarController::WindowAdapter { 
     215public: 
     216    CarbonWindowAdapter(GraphicsWindowCarbon* win) : MenubarController::WindowAdapter(), _win(win) {} 
     217    virtual bool valid() {return (_win.valid() && _win->valid()); } 
     218    virtual void getWindowBounds(CGRect& rect)  
     219    { 
     220        Rect windowBounds; 
     221        OSErr error = GetWindowBounds(_win->getNativeWindowRef(), kWindowStructureRgn, &windowBounds); 
     222        rect.origin.x = windowBounds.left; 
     223        rect.origin.y = windowBounds.top; 
     224        rect.size.width = windowBounds.right - windowBounds.left; 
     225        rect.size.height = windowBounds.bottom - windowBounds.top; 
     226    } 
     227         
     228    osgViewer::GraphicsWindow* getWindow()  { return _win.get(); } 
     229private:  
     230    osg::observer_ptr<GraphicsWindowCarbon> _win; 
    255231}; 
    256  
    257  
    258 MenubarController* MenubarController::instance()  
    259 { 
    260     static osg::ref_ptr<MenubarController> s_menubar_controller = new MenubarController(); 
    261     return s_menubar_controller.get(); 
    262 } 
    263  
    264  
    265 void MenubarController::attachWindow(GraphicsWindowCarbon* win) 
    266 { 
    267     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
    268     _list.push_back(win); 
    269     update(); 
    270 } 
    271  
    272  
    273 void MenubarController::detachWindow(GraphicsWindowCarbon* win)  
    274 { 
    275     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
    276     for(WindowList::iterator i = _list.begin(); i != _list.end(); ) { 
    277         if ((*i).get() == win) 
    278             i = _list.erase(i); 
    279         else  
    280             ++i; 
    281     } 
    282     update(); 
    283 } 
    284  
    285 // iterate through all open windows and check, if they intersect the area occupied by the menubar/dock, and if so, hide the menubar/dock 
    286  
    287 void MenubarController::update()  
    288 { 
    289     OSErr error(noErr); 
    290     unsigned int windowsCoveringMenubarArea = 0;     
    291     unsigned int windowsIntersectingMainScreen = 0; 
    292     for(WindowList::iterator i = _list.begin(); i != _list.end(); ) { 
    293         if ((*i).valid()) { 
    294             GraphicsWindowCarbon* w = (*i).get(); 
    295             Rect windowBounds; 
    296             error = GetWindowBounds(w->getNativeWindowRef(), kWindowStructureRgn, &windowBounds); 
    297              
    298             bool intersect = !( (_mainScreenBounds.origin.x > windowBounds.right) || 
    299                                 (_mainScreenBounds.origin.x + _mainScreenBounds.size.width < windowBounds.left) || 
    300                                 (_mainScreenBounds.origin.y > windowBounds.bottom) || 
    301                                 (_mainScreenBounds.origin.y + _mainScreenBounds.size.height < windowBounds.top)); 
    302             if (intersect && !error) 
    303             { 
    304                 ++windowsIntersectingMainScreen; 
    305                  
    306                 // the window intersects the main-screen, does it intersect with the menubar/dock? 
    307                 if (((_availRect.top > _mainScreenBounds.origin.y) && (_availRect.top > windowBounds.top)) || 
    308                     ((_availRect.left > _mainScreenBounds.origin.x) && (_availRect.left > windowBounds.left)) ||  
    309                     ((_availRect.right < _mainScreenBounds.origin.x + _mainScreenBounds.size.width) && (_availRect.right < windowBounds.right)) ||  
    310                     ((_availRect.bottom < _mainScreenBounds.origin.y + _mainScreenBounds.size.height) && (_availRect.bottom < windowBounds.bottom) )) 
    311                 { 
    312                     ++windowsCoveringMenubarArea; 
    313                 } 
    314             } 
    315              
    316             ++i; 
    317         } 
    318         else 
    319             i= _list.erase(i); 
    320     } 
    321      
    322     // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar 
    323          
    324     if (windowsCoveringMenubarArea && _menubarShown) 
    325         error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); 
    326      
    327     if (!windowsCoveringMenubarArea && !_menubarShown) 
    328         error = SetSystemUIMode(kUIModeNormal, 0); 
    329         _menubarShown = !windowsCoveringMenubarArea; 
    330      
    331     // osg::notify(osg::DEBUG_INFO) << "MenubarController:: " << windowsCoveringMenubarArea << " windows covering the menubar/dock area, " << windowsIntersectingMainScreen << " intersecting mainscreen" << std::endl; 
    332 } 
    333  
    334  
    335 #pragma mark * * * OSXWindowingSystemInterface * * *  
    336  
    337 struct OSXCarbonWindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface 
    338 { 
    339      
    340     /** ctor, get a list of all attached displays */ 
    341     OSXCarbonWindowingSystemInterface() : 
    342         _displayCount(0), 
    343         _displayIds(NULL) 
    344     { 
    345         ProcessSerialNumber sn = { 0, kCurrentProcess }; 
    346         TransformProcessType(&sn,kProcessTransformToForegroundApplication); 
    347         SetFrontProcess(&sn); 
    348          
    349         if( CGGetActiveDisplayList( 0, NULL, &_displayCount ) != CGDisplayNoErr ) 
    350             osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: could not get # of screens" << std::endl; 
    351              
    352         _displayIds = new CGDirectDisplayID[_displayCount]; 
    353         if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr ) 
    354             osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl; 
    355          
    356         // register application event handler and AppleEventHandler to get quit-events: 
    357         static const EventTypeSpec menueventSpec = {kEventClassCommand, kEventCommandProcess}; 
    358         OSErr status = InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(ApplicationEventHandler), 1, &menueventSpec, 0, NULL); 
    359         status = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false); 
    360     } 
    361      
    362     /** dtor */ 
    363     ~OSXCarbonWindowingSystemInterface() 
    364     { 
    365         if (osg::Referenced::getDeleteHandler()) 
    366         { 
    367             osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0); 
    368             osg::Referenced::getDeleteHandler()->flushAll(); 
    369         } 
    370  
    371         if (_displayIds) delete[] _displayIds; 
    372         _displayIds = NULL; 
    373     } 
    374      
    375     /** @return a CGDirectDisplayID for a ScreenIdentifier */ 
    376     inline CGDirectDisplayID getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) { 
    377         if (si.screenNum < _displayCount) 
    378             return _displayIds[si.screenNum]; 
    379         else { 
    380             osg::notify(osg::WARN) << "GraphicsWindowCarbon :: invalid screen # " << si.screenNum << ", returning main-screen instead" << std::endl; 
    381             return _displayIds[0]; 
    382         } 
    383     } 
    384  
    385     /** @return count of attached screens */ 
    386     virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)  
    387     { 
    388         return _displayCount; 
    389     } 
    390  
    391     /** returns the resolution of a specific display */ 
    392     virtual void getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution) 
    393     { 
    394         CGDirectDisplayID id = getDisplayID(si); 
    395         resolution.width = CGDisplayPixelsWide(id); 
    396         resolution.height = CGDisplayPixelsHigh(id); 
    397         resolution.colorDepth = CGDisplayBitsPerPixel(id); 
    398         resolution.refreshRate = getDictDouble (CGDisplayCurrentMode(id), kCGDisplayRefreshRate);        // Not tested 
    399         if (resolution.refreshRate<0) resolution.refreshRate = 0; 
    400     } 
    401  
    402     /** return the top left coord of a specific screen in global screen space */ 
    403     void getScreenTopLeft(const osg::GraphicsContext::ScreenIdentifier& si, int& x, int& y) { 
    404         CGRect bounds = CGDisplayBounds( getDisplayID(si) ); 
    405         x = static_cast<int>(bounds.origin.x); 
    406         y = static_cast<int>(bounds.origin.y); 
    407          
    408         // osg::notify(osg::DEBUG_INFO) << "topleft of screen " << si.screenNum <<" " << bounds.origin.x << "/" << bounds.origin.y << std::endl; 
    409     } 
    410      
    411     /** Helper method to get a double value out of a CFDictionary */ 
    412     static double getDictDouble (CFDictionaryRef refDict, CFStringRef key) 
    413     { 
    414         double value; 
    415         CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key); 
    416         if (!number_value) // if can't get a number for the dictionary 
    417             return -1;  // fail 
    418         if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &value)) // or if cant convert it 
    419             return -1; // fail 
    420         return value; // otherwise return the long value 
    421     } 
    422  
    423     /** Helper method to get a long value out of a CFDictionary */ 
    424     static long getDictLong(CFDictionaryRef refDict, CFStringRef key)        // const void* key? 
    425     { 
    426         long value = 0; 
    427         CFNumberRef number_value = (CFNumberRef)CFDictionaryGetValue(refDict, key);  
    428         if (!number_value) // if can't get a number for the dictionary 
    429             return -1;  // fail 
    430         if (!CFNumberGetValue(number_value, kCFNumberLongType, &value)) // or if cant convert it 
    431             return -1; // fail 
    432         return value; 
    433     } 
    434  
    435     /** implementation of setScreenSettings */ 
    436     virtual bool setScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, const osg::GraphicsContext::ScreenSettings & resolution)  
    437     {  
    438         CGDirectDisplayID displayID = getDisplayID(screenIdentifier); 
    439          
    440         CGRefreshRate refresh = resolution.refreshRate>0 ? resolution.refreshRate : getDictDouble (CGDisplayCurrentMode(displayID), kCGDisplayRefreshRate);   
    441         size_t depth = resolution.colorDepth>0 ? resolution.colorDepth : CGDisplayBitsPerPixel(displayID); 
    442         CFDictionaryRef display_mode_values = 
    443             CGDisplayBestModeForParametersAndRefreshRate( 
    444                             displayID,  
    445                             depth, 
    446                             resolution.width, resolution.height, 
    447                             refresh,   
    448                             NULL); 
    449  
    450  
    451         CGDisplaySwitchToMode(displayID, display_mode_values);     
    452         return true;  
    453     } 
    454  
    455     virtual void enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList) { 
    456         // Warning! This method has not been tested. 
    457         resolutionList.clear(); 
    458  
    459         CGDirectDisplayID displayID = getDisplayID(screenIdentifier); 
    460         CFArrayRef availableModes = CGDisplayAvailableModes(displayID); 
    461         unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes); 
    462         for (unsigned int i=0; i<numberOfAvailableModes; ++i) { 
    463             // look at each mode in the available list 
    464             CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, i); 
    465             osg::GraphicsContext::ScreenSettings tmpSR; 
    466  
    467             long width = getDictLong(mode, kCGDisplayWidth); 
    468             tmpSR.width = width<=0 ? 0 : width; 
    469             long height = getDictLong(mode, kCGDisplayHeight); 
    470             tmpSR.height = height<=0 ? 0 : height; 
    471             long rate = getDictLong(mode, kCGDisplayRefreshRate); 
    472             tmpSR.refreshRate = rate<=0 ? 0 : rate; 
    473             long depth = getDictLong(mode, kCGDisplayBitsPerPixel); 
    474             tmpSR.colorDepth = depth<=0 ? 0 : depth; 
    475  
    476             resolutionList.push_back(tmpSR); 
    477         } 
    478     } 
    479  
    480     virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits) 
    481     { 
    482         if (traits->pbuffer) 
    483         { 
    484             osg::ref_ptr<osgViewer::PixelBufferCarbon> pbuffer = new PixelBufferCarbon(traits); 
    485             if (pbuffer->valid()) return pbuffer.release(); 
    486             else return 0; 
    487         } 
    488         else 
    489         { 
    490             osg::ref_ptr<osgViewer::GraphicsWindowCarbon> window = new GraphicsWindowCarbon(traits); 
    491             if (window->valid()) return window.release(); 
    492             else return 0; 
    493         } 
    494     } 
    495      
    496      
    497      
    498     private: 
    499         CGDisplayCount        _displayCount; 
    500         CGDirectDisplayID*    _displayIds; 
    501 }; 
    502  
    503 } 
    504  
    505  
    506 #pragma mark * * * GraphicsWindowCarbon * * * 
    507  
    508232 
    509233 
     
    631355 
    632356    // move the window to the right screen 
    633     OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
     357    DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
    634358    int screenLeft(0), screenTop(0); 
    635     if (wsi) { 
    636          
     359    if (wsi)  
     360    { 
    637361        wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); 
    638         _traits->y += screenTop; 
    639         _traits->x += screenLeft; 
    640362    } 
    641363     
     
    647369         
    648370        // create the window 
    649         Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width}; 
     371        Rect bounds = {_traits->y + screenTop, _traits->x + screenLeft, _traits->y + _traits->height + screenTop, _traits->x + _traits->width + screenLeft}; 
    650372        OSStatus err = 0; 
    651373        WindowAttributes attr = computeWindowAttributes(_useWindowDecoration, _traits->supportsResize); 
     
    704426        aglSetDrawable(_context, GetWindowPort(_window));  
    705427        ShowWindow(_window);  
    706         MenubarController::instance()->attachWindow(this); 
     428        MenubarController::instance()->attachWindow( new CarbonWindowAdapter(this) ); 
    707429    } 
    708430     
     
    806528    aglUpdateContext(_context); 
    807529    MenubarController::instance()->update(); 
     530     
     531    getEventQueue()->windowResize(x,y,width, height, getEventQueue()->getTime()); 
    808532} 
    809533 
     
    1033757    GetEventParameter( theEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize, NULL, (void*)uniChars ); 
    1034758     
    1035     unsigned int keychar = remapOSXKey(static_cast<unsigned long>(uniChars[0]), rawkey); 
     759    unsigned int keychar = remapCarbonKey(static_cast<unsigned long>(uniChars[0]), rawkey); 
    1036760     
    1037761    switch(GetEventKind(theEvent)) 
     
    1174898bool GraphicsWindowCarbon::setWindowRectangleImplementation(int x, int y, int width, int height) 
    1175899{ 
    1176     Rect bounds = {y, x, y + height, x + width}; 
     900    int screenLeft(0), screenTop(0); 
     901    DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
     902   if (wsi)  
     903    { 
     904        wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); 
     905    } 
     906     
     907    Rect bounds = {y + screenTop, x + screenLeft, y + height + screenTop, x + width + screenLeft}; 
    1177908    SetWindowBounds(getNativeWindowRef(), kWindowContentRgn, &bounds); 
    1178909    aglUpdateContext(_context); 
     
    1181912} 
    1182913 
     914 
     915 
     916void GraphicsWindowCarbon::adaptResize(int x, int y, int w, int h) 
     917{ 
     918    DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
     919    int screenLeft(0), screenTop(0); 
     920    if (wsi) { 
     921         
     922        // get the screen containing the window 
     923        unsigned int screenNdx = wsi->getScreenContaining(x,y,w,h); 
     924         
     925        // update traits 
     926        _traits->screenNum = screenNdx; 
     927         
     928        // get top left of screen 
     929        wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); 
     930    } 
     931     
     932    resized(x-screenLeft,y-screenTop,w,h); 
     933} 
     934 
     935 
     936 
    1183937void GraphicsWindowCarbon::grabFocus() 
    1184938{ 
     
    1200954    if (_traits.valid()) 
    1201955        _traits->useCursor = cursorOn; 
    1202     OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
     956    DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
    1203957    if (wsi == NULL) { 
    1204958        osg::notify(osg::WARN) << "GraphicsWindowCarbon::useCursor :: could not get OSXCarbonWindowingSystemInterface" << std::endl; 
     
    12751029{ 
    12761030 
    1277     OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
     1031    DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
    12781032    if (wsi == NULL) { 
    12791033        osg::notify(osg::WARN) << "GraphicsWindowCarbon::useCursor :: could not get OSXCarbonWindowingSystemInterface" << std::endl; 
     
    13021056} 
    13031057 
    1304  
    1305  
    1306  
    1307  
    1308  
    1309 struct RegisterWindowingSystemInterfaceProxy 
    1310 { 
    1311     RegisterWindowingSystemInterfaceProxy() 
    1312     { 
    1313         osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::OSXCarbonWindowingSystemInterface()); 
    1314     } 
    1315  
    1316     ~RegisterWindowingSystemInterfaceProxy() 
    1317     { 
    1318         if (osg::Referenced::getDeleteHandler()) 
    1319         { 
    1320             osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0); 
    1321             osg::Referenced::getDeleteHandler()->flushAll(); 
    1322         } 
    1323  
    1324         osg::GraphicsContext::setWindowingSystemInterface(0); 
     1058class CarbonWindowingSystemInterface : public  DarwinWindowingSystemInterface { 
     1059public: 
     1060    CarbonWindowingSystemInterface() 
     1061    :    DarwinWindowingSystemInterface() 
     1062    { 
     1063        // register application event handler and AppleEventHandler to get quit-events: 
     1064        static const EventTypeSpec menueventSpec = {kEventClassCommand, kEventCommandProcess}; 
     1065        OSErr status = InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(ApplicationEventHandler), 1, &menueventSpec, 0, NULL); 
     1066        status = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false); 
     1067    } 
     1068     
     1069    virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits)  
     1070    { 
     1071        return createGraphicsContextImplementation<PixelBufferCarbon, GraphicsWindowCarbon>(traits); 
    13251072    } 
    13261073}; 
    13271074 
    1328 RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; 
     1075 
     1076} 
     1077 
     1078#ifdef USE_DARWIN_CARBON_IMPLEMENTATION 
     1079RegisterWindowingSystemInterfaceProxy<CarbonWindowingSystemInterface> createWindowingSystemInterfaceProxy; 
     1080#endif 
     1081 
    13291082 
    13301083// declare C entry point for static compilation. 
    13311084extern "C" void graphicswindow_Carbon(void) 
    13321085{ 
    1333     osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::OSXCarbonWindowingSystemInterface()); 
     1086    osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::CarbonWindowingSystemInterface()); 
    13341087} 
    13351088