From 02120e188e537eb078ebff8e88c0e1531f99d5db Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Dec 2013 13:44:42 +0000 Subject: [PATCH] From Stephan Hunber, "I found some time and ported osgDB::FileUtils and DarwinUtils across new apis to fix the warnings about deprecated api-usage. * osgDB::FileUtils uses now the Cocoa-API to determine the paths of the application-support-folder * DarwinUtils uses now modern functions of the quartz-api to get and set screen-resolutions. Removed some of the osg-deprecated stuff. " --- src/osgDB/CMakeLists.txt | 2 - src/osgDB/FileUtils.cpp | 108 ++++++----------- src/osgViewer/DarwinUtils.h | 7 -- src/osgViewer/DarwinUtils.mm | 226 ++++++++++++++++++++++------------- 4 files changed, 175 insertions(+), 168 deletions(-) diff --git a/src/osgDB/CMakeLists.txt b/src/osgDB/CMakeLists.txt index 18f2a16c7..dd03046a0 100644 --- a/src/osgDB/CMakeLists.txt +++ b/src/osgDB/CMakeLists.txt @@ -33,12 +33,10 @@ ELSE () ENDIF() IF(APPLE AND NOT ANDROID) - IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR) # compile FileUtils.cpp as objective-c++ SET_SOURCE_FILES_PROPERTIES(FileUtils.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++" ) - ENDIF() ENDIF() diff --git a/src/osgDB/FileUtils.cpp b/src/osgDB/FileUtils.cpp index 3ecd24e3c..7af1fbbde 100644 --- a/src/osgDB/FileUtils.cpp +++ b/src/osgDB/FileUtils.cpp @@ -51,6 +51,7 @@ typedef char TCHAR; //>OSG_IOS //IOS includes #include "TargetConditionals.h" + #include #if (TARGET_OS_IPHONE) #include @@ -85,6 +86,10 @@ typedef char TCHAR; #include #include #include + + #if defined(_DARWIN_FEATURE_64_BIT_INODE) + #define stat64 stat + #endif #endif // set up _S_ISDIR() @@ -868,7 +873,7 @@ bool osgDB::containsCurrentWorkingDirectoryReference(const FilePathList& paths) } #elif defined(__APPLE__) -#if (TARGET_OS_IPHONE) +#if (TARGET_OS_IPHONE) || (MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) #define COMPILE_COCOA_VERSION #else #define COMPILE_CARBON_VERSION @@ -1006,7 +1011,7 @@ bool osgDB::containsCurrentWorkingDirectoryReference(const FilePathList& paths) } appendInstallationLibraryFilePaths(filepath); - + // Since this is currently the only Objective-C code in the // library, we need an autoreleasepool for obj-c memory management. // If more Obj-C is added, we might move this pool to another @@ -1016,29 +1021,28 @@ bool osgDB::containsCurrentWorkingDirectoryReference(const FilePathList& paths) NSAutoreleasePool* mypool = [[NSAutoreleasePool alloc] init]; NSString* myBundlePlugInPath; - NSString* userSupportDir; // This will grab the "official" bundle plug in path. // It will be YourProgram.app/Contents/PlugIns (for App bundles) // or YourProgram/PlugIns (for Unix executables) myBundlePlugInPath = [[NSBundle mainBundle] builtInPlugInsPath]; - // Now setup the other search paths - // Cocoa has a nice method for tilde expansion. - // There's probably a better way of getting this directory, but I - // can't find the call. - userSupportDir = [@"~/Library/Application Support/OpenSceneGraph/PlugIns" stringByExpandingTildeInPath]; - - // Can setup the remaining directories directly in C++ - // Since Obj-C and C++ objects don't understand each other, // the Obj-C strings must be converted down to C strings so // C++ can make them into C++ strings. filepath.push_back( [myBundlePlugInPath UTF8String] ); - filepath.push_back( [userSupportDir UTF8String] ); + + // add all application-support-folders + NSArray *systemSearchPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSAllDomainsMask, YES); - filepath.push_back( "/Library/Application Support/OpenSceneGraph/PlugIns" ); - filepath.push_back( "/Network/Library/Application Support/OpenSceneGraph/PlugIns" ); + NSFileManager *fileManager = [NSFileManager defaultManager]; + + for (NSString *systemPath in systemSearchPaths) { + NSString *systemPluginsPath = [systemPath stringByAppendingPathComponent:@"OpenSceneGraph/PlugIns"]; + if ([fileManager fileExistsAtPath:systemPluginsPath]) { + filepath.push_back( [systemPluginsPath UTF8String] ); + } + } // Clean up the autorelease pool [mypool release]; @@ -1107,71 +1111,29 @@ bool osgDB::containsCurrentWorkingDirectoryReference(const FilePathList& paths) } // Next, check the User's Application Support folder - errCode = FSFindFolder( kUserDomain, kApplicationSupportFolderType, kDontCreateFolder, &f ); - if(noErr == errCode) + int domains[3] = { kUserDomain, kLocalDomain, kNetworkDomain }; + + for(unsigned int domain_ndx = 0; domain_ndx < 3; ++domain_ndx) { - // Get the URL - url = CFURLCreateFromFSRef( 0, &f ); - if(url) + errCode = FSFindFolder( domains[domain_ndx], kApplicationSupportFolderType, kDontCreateFolder, &f ); + if(noErr == errCode) { - filepath.push_back(GetPathFromCFURLRef(url) + OSG_PLUGIN_PATH); - CFRelease( url ); + // Get the URL + url = CFURLCreateFromFSRef( 0, &f ); + if(url) + { + filepath.push_back(GetPathFromCFURLRef(url) + OSG_PLUGIN_PATH); + CFRelease( url ); + } + else + OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't create CFURLRef for application support Path at ndx " << domain_ndx << std::endl; + + url = NULL; } else - OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't create CFURLRef for User's application support Path" << std::endl; - - url = NULL; - } - else - { - OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't find the User's Application Support Path" << std::endl; - } - - // Next, check the Local System's Application Support Folder - errCode = FSFindFolder( kLocalDomain, kApplicationSupportFolderType, kDontCreateFolder, &f ); - if(noErr == errCode) - { - // Get the URL - url = CFURLCreateFromFSRef( 0, &f ); - - if(url) { - filepath.push_back(GetPathFromCFURLRef(url) + OSG_PLUGIN_PATH); - CFRelease( url ); + OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't find the User's Application Support Path at ndx " << domain_ndx << std::endl; } - else - OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't create CFURLRef for local System's ApplicationSupport Path" << std::endl; - - url = NULL; - } - else - { - OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't find the Local System's Application Support Path" << std::endl; - } - - // Finally, check the Network Application Support Folder - // This one has a likely chance of not existing so an error - // may be returned. Don't panic. - errCode = FSFindFolder( kNetworkDomain, kApplicationSupportFolderType, kDontCreateFolder, &f ); - if(noErr == errCode) - { - // Get the URL - url = CFURLCreateFromFSRef( 0, &f ); - - if(url) - { - filepath.push_back(GetPathFromCFURLRef(url) + OSG_PLUGIN_PATH); - CFRelease( url ); - } - else - OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't create CFURLRef for network Application Support Path" << std::endl; - - url = NULL; - } - else - { - // had to comment out as it segfauls the OSX app otherwise - // OSG_NOTIFY( osg::DEBUG_INFO ) << "Couldn't find the Network Application Support Path" << std::endl; } } #else diff --git a/src/osgViewer/DarwinUtils.h b/src/osgViewer/DarwinUtils.h index 10b56fe71..f68798fc5 100644 --- a/src/osgViewer/DarwinUtils.h +++ b/src/osgViewer/DarwinUtils.h @@ -109,13 +109,6 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy protected: virtual void _init(); - - /** implementation of setScreenResolution */ - bool setScreenResolutionImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) ; - - /** implementation of setScreenRefreshRate */ - bool setScreenRefreshRateImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate); - template osg::GraphicsContext* createGraphicsContextImplementation(osg::GraphicsContext::Traits* traits) diff --git a/src/osgViewer/DarwinUtils.mm b/src/osgViewer/DarwinUtils.mm index 08b84986d..d6bcce6b8 100644 --- a/src/osgViewer/DarwinUtils.mm +++ b/src/osgViewer/DarwinUtils.mm @@ -11,6 +11,7 @@ #include #include "DarwinUtils.h" #include +#include @interface MenubarToggler : NSObject { @@ -104,21 +105,9 @@ namespace osgDarwin { -// -// Lion replacement for CGDisplayBitsPerPixel(CGDirectDisplayID displayId) -// -size_t displayBitsPerPixel( CGDirectDisplayID displayId ) +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 +size_t displayBitsPerPixelForMode(CGDisplayModeRef mode) { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - return CGDisplayBitsPerPixel(displayId); -#else - CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId); - if (!mode) - { - OSG_WARN << "CGDisplayCopyDisplayMode returned NULL" << std::endl; - return 0; - } - CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); if (!pixEnc) { @@ -144,14 +133,88 @@ size_t displayBitsPerPixel( CGDirectDisplayID displayId ) { OSG_WARN << "Unable to match pixel encoding '" << CFStringGetCStringPtr(pixEnc, kCFStringEncodingUTF8) << "'" << std::endl; } - - CGDisplayModeRelease(mode); CFRelease(pixEnc); + + return depth; +} + +#endif + +size_t displayBitsPerPixel( CGDirectDisplayID displayId ) +{ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + return CGDisplayBitsPerPixel(displayId); +#else + CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId); + if (!mode) + { + OSG_WARN << "CGDisplayCopyDisplayMode returned NULL" << std::endl; + return 0; + } + + unsigned int depth = displayBitsPerPixelForMode(mode); + CGDisplayModeRelease(mode); return depth; #endif } + +static bool findBestDisplayModeFor(const CGDirectDisplayID& displayid, int desired_width, int desired_height, unsigned int desired_color_depth, double desired_refresh_rate) { + + CFArrayRef availableModes = CGDisplayCopyAllDisplayModes(displayid, NULL); + unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes); + + CGDisplayModeRef best_match(NULL); + + int best_dx = std::numeric_limits::max(); + int best_dy = std::numeric_limits::max(); + + + for (unsigned int i=0; i 0) && (dx <= best_dx) && (dy > 0) && (dy <= best_dy) && (color_depth >= desired_color_depth) && (rate >= desired_refresh_rate)) { + best_match = mode; + best_dx = dx; + best_dy = dy; + } + } + bool result = false; + if(best_match) + { + result = CGDisplaySetDisplayMode(displayid, best_match, NULL) != kCGErrorSuccess; + } + else if (desired_refresh_rate > 0) + { + // try again with a lower refresh-rate + result = findBestDisplayModeFor(displayid, desired_width, desired_height, desired_color_depth, 0); + } + else if (desired_color_depth > 0) + { + // try again with a lower color_depth + result = findBestDisplayModeFor(displayid, desired_width, desired_height, 0, 0); + } + + CFRelease(availableModes); + + return result; +} + + + + static inline CGRect toCGRect(NSRect nsRect) { CGRect cgRect; @@ -418,12 +481,25 @@ void DarwinWindowingSystemInterface::getScreenSettings(const osg::GraphicsContex resolution.refreshRate = 0; return; } - + CGDirectDisplayID id = getDisplayID(si); - resolution.width = CGDisplayPixelsWide(id); - resolution.height = CGDisplayPixelsHigh(id); - resolution.colorDepth = displayBitsPerPixel(id); - resolution.refreshRate = getDictDouble (CGDisplayCurrentMode(id), kCGDisplayRefreshRate); // Not tested + #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 + + CGDisplayModeRef display_mode_ref = CGDisplayCopyDisplayMode(id); + resolution.width = CGDisplayModeGetWidth(display_mode_ref); + resolution.height = CGDisplayModeGetHeight(display_mode_ref); + resolution.colorDepth = displayBitsPerPixelForMode(display_mode_ref); + resolution.refreshRate = CGDisplayModeGetRefreshRate(display_mode_ref); + + CGDisplayModeRelease(display_mode_ref); + + #else + resolution.width = CGDisplayPixelsWide(id); + resolution.height = CGDisplayPixelsHigh(id); + resolution.colorDepth = displayBitsPerPixel(id); + + resolution.refreshRate = getDictDouble (CGDisplayCurrentMode(id), kCGDisplayRefreshRate); // Not tested + #endif if (resolution.refreshRate<0) resolution.refreshRate = 0; } @@ -441,6 +517,27 @@ void DarwinWindowingSystemInterface::enumerateScreenSettings(const osg::Graphics } CGDirectDisplayID displayid = getDisplayID(screenIdentifier); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 + + CFArrayRef availableModes = CGDisplayCopyAllDisplayModes(displayid, NULL); + unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes); + for (unsigned int i=0; i= 1060) + + return findBestDisplayModeFor(displayid, settings.width, settings.height, settings.colorDepth, settings.refreshRate); + + #else + // add next line and on following line replace hard coded depth and refresh rate + CGRefreshRate refresh = getDictDouble (CGDisplayCurrentMode(displayid), kCGDisplayRefreshRate); + CFDictionaryRef display_mode_values = + CGDisplayBestModeForParametersAndRefreshRate( + displayid, + settings.colorDepth, + settings.width, settings.height, + settings.refreshRate, + NULL); + + + return CGDisplaySwitchToMode(displayid, display_mode_values) != kCGErrorSuccess; + #endif + + return false; } -/** 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 - CGRefreshRate refresh = getDictDouble (CGDisplayCurrentMode(displayid), kCGDisplayRefreshRate); - CFDictionaryRef display_mode_values = - CGDisplayBestModeForParametersAndRefreshRate( - displayid, - displayBitsPerPixel(displayid), - width, height, - refresh, - NULL); - - - CGDisplaySwitchToMode(displayid, display_mode_values); - return true; -} - -/** implementation of setScreenRefreshRate */ -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); - - CGDirectDisplayID displayid = getDisplayID(screenIdentifier); - - // add next line and on following line replace hard coded depth and refresh rate - CFDictionaryRef display_mode_values = - CGDisplayBestModeForParametersAndRefreshRate( - displayid, - displayBitsPerPixel(displayid), - width, height, - refreshRate, - &success); - - - if (success) - CGDisplaySwitchToMode(displayid, display_mode_values); - - return (success != 0); -} - unsigned int DarwinWindowingSystemInterface::getScreenContaining(int x, int y, int w, int h) {