diff --git a/src/osgViewer/DarwinUtils.h b/src/osgViewer/DarwinUtils.h index bed2ffa4d..cf8ffc2b1 100755 --- a/src/osgViewer/DarwinUtils.h +++ b/src/osgViewer/DarwinUtils.h @@ -90,7 +90,9 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy unsigned int getScreenContaining(int x, int y, int w, int h); protected: - + + virtual void _init(); + /** implementation of setScreenResolution */ bool setScreenResolutionImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) ; @@ -117,6 +119,8 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy private: + + bool _initialized; CGDisplayCount _displayCount; CGDirectDisplayID* _displayIds; diff --git a/src/osgViewer/DarwinUtils.mm b/src/osgViewer/DarwinUtils.mm index fa909d09e..1bcacfd39 100755 --- a/src/osgViewer/DarwinUtils.mm +++ b/src/osgViewer/DarwinUtils.mm @@ -221,21 +221,11 @@ static long getDictLong(CFDictionaryRef refDict, CFStringRef key) // cons /** ctor, get a list of all attached displays */ DarwinWindowingSystemInterface::DarwinWindowingSystemInterface() : + _initialized(false), _displayCount(0), _displayIds(NULL) { - ProcessSerialNumber sn = { 0, kCurrentProcess }; - TransformProcessType(&sn,kProcessTransformToForegroundApplication); - SetFrontProcess(&sn); - - if( CGGetActiveDisplayList( 0, NULL, &_displayCount ) != CGDisplayNoErr ) - osg::notify(osg::WARN) << "DarwinWindowingSystemInterface: could not get # of screens" << std::endl; - - _displayIds = new CGDirectDisplayID[_displayCount]; - if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr ) - osg::notify(osg::WARN) << "DarwinWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl; - - } +} /** dtor */ DarwinWindowingSystemInterface::~DarwinWindowingSystemInterface() @@ -250,12 +240,51 @@ DarwinWindowingSystemInterface::~DarwinWindowingSystemInterface() _displayIds = NULL; } +void DarwinWindowingSystemInterface::_init() +{ + if (_initialized) return; + + ProcessSerialNumber sn = { 0, kCurrentProcess }; + TransformProcessType(&sn,kProcessTransformToForegroundApplication); + SetFrontProcess(&sn); + + if( CGGetActiveDisplayList( 0, NULL, &_displayCount ) != CGDisplayNoErr ) + { + osg::notify(osg::WARN) << "DarwinWindowingSystemInterface: could not get # of screens" << std::endl; + _displayCount = 0; + + _initialized = true; + return; + } + + _displayIds = new CGDirectDisplayID[_displayCount]; + + if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr ) + { + osg::notify(osg::WARN) << "DarwinWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl; + } + + _initialized = true; +} + /** @return a CGDirectDisplayID for a ScreenIdentifier */ -CGDirectDisplayID DarwinWindowingSystemInterface::getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) { +CGDirectDisplayID DarwinWindowingSystemInterface::getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) +{ + _init(); + + if (_displayCount==0) + { + osg::notify(osg::WARN) << "DarwinWindowingSystemInterface::getDisplayID(..) no valid screens available returning 0 instead." << std::endl; + return 0; + } + if (si.screenNum < static_cast(_displayCount)) + { return _displayIds[si.screenNum]; - else { - osg::notify(osg::WARN) << "GraphicsWindowCarbon :: invalid screen # " << si.screenNum << ", returning main-screen instead" << std::endl; + } + else + { + osg::notify(osg::WARN) << "DarwinWindowingSystemInterface::getDisplayID(..) invalid screen # " << si.screenNum << ", returning main-screen instead." << std::endl; return _displayIds[0]; } } @@ -263,11 +292,24 @@ CGDirectDisplayID DarwinWindowingSystemInterface::getDisplayID(const osg::Graphi /** @return count of attached screens */ unsigned int DarwinWindowingSystemInterface::getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si) { + _init(); + return _displayCount; } void DarwinWindowingSystemInterface::getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution) { + _init(); + + if (_displayCount==0) + { + resolution.width = 0; + resolution.height = 0; + resolution.colorDepth = 0; + resolution.refreshRate = 0; + return; + } + CGDirectDisplayID id = getDisplayID(si); resolution.width = CGDisplayPixelsWide(id); resolution.height = CGDisplayPixelsHigh(id); @@ -277,33 +319,51 @@ void DarwinWindowingSystemInterface::getScreenSettings(const osg::GraphicsContex } -void DarwinWindowingSystemInterface::enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList) { - // Warning! This method has not been tested. - resolutionList.clear(); +void DarwinWindowingSystemInterface::enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList) +{ + _init(); - CGDirectDisplayID displayid = getDisplayID(screenIdentifier); - CFArrayRef availableModes = CGDisplayAvailableModes(displayid); - unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes); - for (unsigned int i=0; i(bounds.origin.x); y = static_cast(bounds.origin.y); @@ -316,8 +376,10 @@ bool DarwinWindowingSystemInterface::setScreenSettings(const osg::GraphicsContex { bool result = setScreenResolutionImpl(si, settings.width, settings.height); if (result) + { setScreenRefreshRateImpl(si, settings.refreshRate); - + } + return result; } @@ -326,6 +388,13 @@ bool DarwinWindowingSystemInterface::setScreenSettings(const osg::GraphicsContex /** implementation of setScreenResolution */ bool DarwinWindowingSystemInterface::setScreenResolutionImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) { + _init(); + + if (_displayCount==0) + { + return false; + } + CGDirectDisplayID displayid = getDisplayID(screenIdentifier); // add next line and on following line replace hard coded depth and refresh rate @@ -344,8 +413,15 @@ bool DarwinWindowingSystemInterface::setScreenResolutionImpl(const osg::Graphics } /** implementation of setScreenRefreshRate */ -bool DarwinWindowingSystemInterface::setScreenRefreshRateImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) { - +bool DarwinWindowingSystemInterface::setScreenRefreshRateImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) +{ + _init(); + + if (_displayCount==0) + { + return false; + } + boolean_t success(false); unsigned width, height; getScreenResolution(screenIdentifier, width, height); @@ -371,6 +447,13 @@ bool DarwinWindowingSystemInterface::setScreenRefreshRateImpl(const osg::Graphic unsigned int DarwinWindowingSystemInterface::getScreenContaining(int x, int y, int w, int h) { + _init(); + + if (_displayCount==0) + { + return 0; + } + CGRect rect = CGRectMake(x,y,w,h); for(unsigned int i = 0; i < _displayCount; ++i) { CGRect bounds = CGDisplayBounds( getDisplayID(i) ); @@ -382,9 +465,4 @@ unsigned int DarwinWindowingSystemInterface::getScreenContaining(int x, int y, i return 0; } - - - - - } diff --git a/src/osgViewer/GraphicsWindowCarbon.cpp b/src/osgViewer/GraphicsWindowCarbon.cpp index c7bcfa749..6fe0c1f21 100644 --- a/src/osgViewer/GraphicsWindowCarbon.cpp +++ b/src/osgViewer/GraphicsWindowCarbon.cpp @@ -1053,19 +1053,29 @@ void GraphicsWindowCarbon::transformMouseXY(float& x, float& y) class CarbonWindowingSystemInterface : public DarwinWindowingSystemInterface { public: - CarbonWindowingSystemInterface() - : DarwinWindowingSystemInterface() + CarbonWindowingSystemInterface() : DarwinWindowingSystemInterface() { + } + + virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits) + { + _init(); + + return createGraphicsContextImplementation(traits); + } + + virtual void _init() + { + if (_initialized) return; + + DarwinWindowingSystemInterface::init(); + // register application event handler and AppleEventHandler to get quit-events: static const EventTypeSpec menueventSpec = {kEventClassCommand, kEventCommandProcess}; OSErr status = InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(ApplicationEventHandler), 1, &menueventSpec, 0, NULL); status = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false); } - - virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits) - { - return createGraphicsContextImplementation(traits); - } + }; diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index f5c736db1..2c1666925 100755 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -1382,16 +1382,17 @@ GraphicsWindowCocoa::~GraphicsWindowCocoa() // CocoaWindowingSystemInterface // ---------------------------------------------------------------------------------------------------------- -struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface { - - CocoaWindowingSystemInterface() - : DarwinWindowingSystemInterface() - - { +struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface +{ + + CocoaWindowingSystemInterface() : DarwinWindowingSystemInterface() + { } - + void initAsStandaloneApplication() { + _init(); + static bool s_inited = false; if (s_inited) return; s_inited = true; @@ -1421,6 +1422,8 @@ struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface { virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits) { + _init(); + if (!traits->pbuffer) { GraphicsWindowCocoa::WindowData* windowData = traits->inheritedWindowData ? dynamic_cast(traits->inheritedWindowData.get()) : NULL;