Changeset 6706

Show
Ignore:
Timestamp:
05/20/07 15:42:41
Author:
robert
Message:

From Stephan Huber, "attached you'll find some modifications and enhancements to the carbon's
implementation of GraphicsWindow?:

- usage of WindowData?, you can specify an existing window to use via
osg::Traits
- implementation of setScreenResolution and setScreenRefreshRate
- implementation of setWindowDecoration when window is already created.

There seems to be a bug regarding multiple threads and closing windows,
see my other mail on osg-users.
"

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • OpenSceneGraph/trunk/include/osgViewer/api/Carbon/GraphicsWindowCarbon

    r6678 r6706  
    104104 
    105105        /** WindowData is used to pass in the Carbon window handle attached the GraphicsContext::Traits structure. */ 
    106         struct WindowData : public osg::Referenced 
     106        class WindowData : public osg::Referenced 
    107107        { 
    108             WindowData(WindowRef window): 
    109                 _window(window) {} 
     108            public: 
     109                WindowData(WindowRef window): 
     110                    _window(window), _installEventHandler(false) {} 
    110111                 
    111             WindowRef   _window; 
     112                WindowRef getNativeWindowRef() { return _window; } 
     113                void setInstallEventHandler(bool flag) { _installEventHandler = flag; } 
     114                bool installEventHandler() { return _installEventHandler; } 
     115             
     116            private: 
     117                WindowRef   _window; 
     118                bool        _installEventHandler; 
     119             
    112120        }; 
     121         
     122        /// install the standard os-eventhandler 
     123        void installEventHandler(); 
    113124 
    114125    protected: 
     
    119130         
    120131        AGLContext& getAGLContext() { return _context; } 
     132         
     133 
    121134 
    122135        bool            _valid; 
     
    130143        AGLPixelFormat  _pixelFormat; 
    131144         
    132         int             _windowTitleHeight; 
     145        int             _windowTitleHeight;     
     146    private:         
     147        /// computes the window attributes 
     148        WindowAttributes computeWindowAttributes(bool useWindowDecoration, bool supportsResize); 
    133149     
    134     private:         
     150         
    135151        bool _closeRequested; 
    136152}; 
  • OpenSceneGraph/trunk/src/osgViewer/GraphicsWindowCarbon.cpp

    r6678 r6706  
    501501        // osg::notify(osg::DEBUG_INFO) << "topleft of screen " << si.screenNum <<" " << bounds.origin.x << "/" << bounds.origin.y << std::endl; 
    502502    } 
     503     
     504    /** helper method to get a value out of a CFDictionary */ 
     505    static double getDictDouble (CFDictionaryRef refDict, CFStringRef key) 
     506    { 
     507       double double_value; 
     508       CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key); 
     509       if (!number_value) // if can't get a number for the dictionary 
     510           return -1;  // fail 
     511       if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it 
     512            return -1; // fail 
     513        return double_value; // otherwise return the long value 
     514    } 
     515 
     516     
     517    /** implementation of setScreenResolution */ 
     518    virtual bool setScreenResolution(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height)  
     519    {  
     520        CGDirectDisplayID displayID = getDisplayID(screenIdentifier); 
     521         
     522        // add next line and on following line replace hard coded depth and refresh rate 
     523        CGRefreshRate refresh =  getDictDouble (CGDisplayCurrentMode(displayID), kCGDisplayRefreshRate);   
     524        CFDictionaryRef display_mode_values = 
     525            CGDisplayBestModeForParametersAndRefreshRate( 
     526                            displayID,  
     527                            CGDisplayBitsPerPixel(displayID),  
     528                            width, height,   
     529                            refresh,   
     530                            NULL); 
     531 
     532                                           
     533        CGDisplaySwitchToMode(displayID, display_mode_values);     
     534        return true;  
     535    } 
     536     
     537    /** implementation of setScreenRefreshRate */ 
     538    virtual bool setScreenRefreshRate(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) {  
     539         
     540        boolean_t  success(false); 
     541        unsigned width, height; 
     542        getScreenResolution(screenIdentifier, width, height); 
     543         
     544        CGDirectDisplayID displayID = getDisplayID(screenIdentifier); 
     545         
     546        // add next line and on following line replace hard coded depth and refresh rate 
     547        CFDictionaryRef display_mode_values = 
     548            CGDisplayBestModeForParametersAndRefreshRate( 
     549                            displayID,  
     550                            CGDisplayBitsPerPixel(displayID),  
     551                            width, height,   
     552                            refreshRate,   
     553                            &success); 
     554 
     555                                           
     556        if (success) 
     557            CGDisplaySwitchToMode(displayID, display_mode_values);     
     558             
     559        return (success != 0); 
     560    } 
     561 
    503562         
    504563     
     
    532591 
    533592 
    534 void GraphicsWindowCarbon::setWindowDecoration(bool flag) 
    535 
    536    _useWindowDecoration = flag; 
    537 
     593 
    538594 
    539595void GraphicsWindowCarbon::init() 
     
    541597    _windowTitleHeight = 0; 
    542598    _closeRequested = false; 
     599    _ownsWindow = false; 
    543600    _context = NULL; 
    544601    _window = NULL; 
     
    550607} 
    551608 
    552  
    553  
    554 bool GraphicsWindowCarbon::realizeImplementation() 
    555 
    556      
    557     if (!_initialized) init(); 
    558     if (!_initialized) return false; 
    559     if (!_traits) return false; 
    560      
    561     setWindowDecoration(_traits->windowDecoration); 
    562      
    563     // move the window to the right screen 
    564  
    565     OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
    566     int screenLeft(0), screenTop(0); 
    567     if (wsi) { 
    568          
    569         wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); 
    570         _traits->y += screenTop; 
    571         _traits->x += screenLeft; 
    572     } 
    573      
    574     // create the window 
    575     Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width}; 
    576     OSStatus err = 0; 
    577     WindowAttributes attr; 
    578      
    579     if (_useWindowDecoration)  
    580     { 
    581         if (_traits->supportsResize) 
     609void GraphicsWindowCarbon::setWindowDecoration(bool flag) 
     610
     611    _useWindowDecoration = flag; 
     612    if (_realized) { 
     613        OSErr err = noErr; 
     614        Rect bounds; 
     615        GetWindowBounds(getNativeWindowRef(), kWindowContentRgn, &bounds); 
     616 
     617        if (_useWindowDecoration) { 
     618            err = ChangeWindowAttributes(getNativeWindowRef(),  kWindowStandardDocumentAttributes,  kWindowNoTitleBarAttribute | kWindowNoShadowAttribute); 
     619            SetWindowBounds(getNativeWindowRef(), kWindowContentRgn, &bounds); 
     620        } else { 
     621            err = ChangeWindowAttributes(getNativeWindowRef(), kWindowNoTitleBarAttribute | kWindowNoShadowAttribute, kWindowStandardDocumentAttributes); 
     622        } 
     623 
     624        if (err != noErr) { 
     625            osg::notify(osg::WARN) << "GraphicsWindowCarbon::setWindowDecoration failed with " << err << std::endl; 
     626        } 
     627    } 
     628
     629 
     630WindowAttributes GraphicsWindowCarbon::computeWindowAttributes(bool useWindowDecoration, bool supportsResize) { 
     631    WindowAttributes attr;  
     632     
     633    if (useWindowDecoration)  
     634    { 
     635        if (supportsResize) 
    582636            attr = (kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute); 
    583637        else 
     
    587641    { 
    588642        attr = kWindowNoTitleBarAttribute | kWindowNoShadowAttribute | kWindowStandardHandlerAttribute; 
    589         if (_traits->supportsResize) 
     643        if (supportsResize) 
    590644            attr |= kWindowResizableAttribute; 
    591645    } 
    592      
    593     err = CreateNewWindow(kDocumentWindowClass, attr, &bounds, &_window); 
    594  
    595     if (err) { 
    596         osg::notify(osg::WARN) << "GraphicsWindowCarbon::realizeImplementation() failed creating a window: " << err << std::endl; 
    597         return false; 
    598     } else { 
    599         osg::notify(osg::INFO) << "GraphicsWindowCarbon::realizeImplementation() - window created with bounds(" << bounds.top << ", " << bounds.left << ", " << bounds.bottom << ", " << bounds.right << ")" << std::endl; 
    600     } 
    601      
    602     Rect titleRect; 
    603     GetWindowBounds(_window, kWindowTitleBarRgn, &titleRect); 
    604     _windowTitleHeight = abs(titleRect.top); 
    605      
     646    return attr; 
     647
     648 
     649void GraphicsWindowCarbon::installEventHandler() { 
     650 
    606651    // register window event handler to receive resize-events 
    607652    EventTypeSpec   windEventList[] = { 
     
    623668    }; 
    624669     
     670 
    625671    InstallWindowEventHandler(_window, NewEventHandlerUPP(GraphicsWindowEventHandler),  GetEventTypeCount(windEventList), windEventList, this, NULL); 
     672} 
     673 
     674 
     675bool GraphicsWindowCarbon::realizeImplementation() 
     676{ 
     677     
     678    if (!_initialized) init(); 
     679    if (!_initialized) return false; 
     680    if (!_traits) return false; 
     681     
     682    setWindowDecoration(_traits->windowDecoration); 
     683     
     684    // move the window to the right screen 
     685 
     686    OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); 
     687    int screenLeft(0), screenTop(0); 
     688    if (wsi) { 
     689         
     690        wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); 
     691        _traits->y += screenTop; 
     692        _traits->x += screenLeft; 
     693    } 
     694     
     695    WindowData *windowData = _traits.get() ? dynamic_cast<WindowData*>(_traits->inheritedWindowData.get()) : 0; 
     696    _ownsWindow = (windowData) ? (windowData->getNativeWindowRef() == NULL) : true; 
     697     
     698    if (_ownsWindow) { 
     699         
     700        // create the window 
     701        Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width}; 
     702        OSStatus err = 0; 
     703        WindowAttributes attr = computeWindowAttributes(_useWindowDecoration, _traits->supportsResize); 
     704         
     705        err = CreateNewWindow(kDocumentWindowClass, attr, &bounds, &_window); 
     706 
     707        if (err) { 
     708            osg::notify(osg::WARN) << "GraphicsWindowCarbon::realizeImplementation() failed creating a window: " << err << std::endl; 
     709            return false; 
     710        } else { 
     711            osg::notify(osg::INFO) << "GraphicsWindowCarbon::realizeImplementation() - window created with bounds(" << bounds.top << ", " << bounds.left << ", " << bounds.bottom << ", " << bounds.right << ")" << std::endl; 
     712        } 
     713    } 
     714    else { 
     715        _window = windowData->getNativeWindowRef(); 
     716    } 
     717     
     718    Rect titleRect; 
     719    GetWindowBounds(_window, kWindowTitleBarRgn, &titleRect); 
     720    _windowTitleHeight = abs(titleRect.top); 
     721     
     722    if ((_ownsWindow) || (windowData && windowData->installEventHandler())) 
     723        installEventHandler(); 
    626724     
    627725    // set the window title 
     
    721819    } 
    722820     
    723     if (_window) DisposeWindow(_window); 
     821    if (_ownsWindow && _window) DisposeWindow(_window); 
    724822    _window = NULL; 
    725823} 
     
    10741172void GraphicsWindowCarbon::setWindowRectangle(int x, int y, int width, int height) 
    10751173{ 
    1076    // TODO: implement 
    1077      osg::notify(osg::NOTICE)<<"GraphicsWindowCarbon::setWindowRectangle(..) not implemented."<<std::endl; 
     1174    Rect bounds = {y, x, y + height, x + width}; 
     1175    SetWindowBounds(getNativeWindowRef(), kWindowContentRgn, &bounds); 
     1176    aglUpdateContext(_context); 
     1177    MenubarController::instance()->update(); 
     1178 
    10781179} 
    10791180