A bunch of OS X SDK-related fixes.
Adds runtime support for 10.5 APIs: display modes, bundle paths, system paths, pasteboards. Previously this was compile-time support only, which prevented building on later SDKs while targeting earlier APIs. Adds hardcoded version for pre-10.6 builds, to avoid messing with deprecated Gestalt or having to add a 10.5 non-dispatch singleton (Grand Central Dispatch didn't exist in 10.5) This was SVN commit r14140.
This commit is contained in:
parent
011cbb5725
commit
45a7f577d3
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2010 Wildfire Games
|
||||
/* Copyright (c) 2013 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -30,6 +30,7 @@
|
||||
#include "lib/file/file.h"
|
||||
#include "lib/posix/posix_filesystem.h" // mode_t
|
||||
|
||||
#include <AvailabilityMacros.h> // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
@ -63,8 +64,7 @@ bool CanRunNotifications()
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
||||
#else
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
|
||||
#define kFSEventStreamCreateFlagFileEvents 0x00000010
|
||||
#define kFSEventStreamEventFlagItemIsFile 0x00010000
|
||||
#define kFSEventStreamEventFlagItemRemoved 0x00000200
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2012 Wildfire Games
|
||||
/* Copyright (c) 2013 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -34,6 +34,13 @@
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <mach-o/dyld.h> // _NSGetExecutablePath
|
||||
|
||||
// Ignore deprecation warnings for 10.5 backwards compatibility
|
||||
#if GCC_VERSION >= 402 // (older GCCs don't support this pragma)
|
||||
# if GCC_VERSION >= 406 // store user flags
|
||||
# pragma GCC diagnostic push
|
||||
# endif
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
Status sys_clipboard_set(const wchar_t* text)
|
||||
{
|
||||
@ -75,12 +82,6 @@ namespace gfx {
|
||||
|
||||
Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
|
||||
#else
|
||||
CFDictionaryRef currentMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
|
||||
#endif
|
||||
|
||||
if(xres)
|
||||
*xres = (int)CGDisplayPixelsWide(kCGDirectMainDisplay);
|
||||
|
||||
@ -91,39 +92,56 @@ Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// CGDisplayBitsPerPixel was deprecated in OS X 10.6
|
||||
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(currentMode);
|
||||
if (CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
*bpp = 32;
|
||||
else if (CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
*bpp = 16;
|
||||
else if (CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
*bpp = 8;
|
||||
else // error
|
||||
*bpp = 0;
|
||||
if (CGDisplayCopyDisplayMode != NULL)
|
||||
{
|
||||
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
|
||||
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(currentMode);
|
||||
if (CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
*bpp = 32;
|
||||
else if (CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
*bpp = 16;
|
||||
else if (CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
*bpp = 8;
|
||||
else // error
|
||||
*bpp = 0;
|
||||
|
||||
// We're responsible for this
|
||||
CFRelease(pixelEncoding);
|
||||
#else
|
||||
CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayBitsPerPixel);
|
||||
CFNumberGetValue(num, kCFNumberIntType, bpp);
|
||||
// We're responsible for this
|
||||
CFRelease(pixelEncoding);
|
||||
CGDisplayModeRelease(currentMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif // fallback to 10.5 API
|
||||
CFDictionaryRef currentMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
|
||||
CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayBitsPerPixel);
|
||||
CFNumberGetValue(num, kCFNumberIntType, bpp);
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(freq)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
*freq = (int)CGDisplayModeGetRefreshRate(currentMode);
|
||||
#else
|
||||
CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayRefreshRate);
|
||||
CFNumberGetValue(num, kCFNumberIntType, freq);
|
||||
if (CGDisplayCopyDisplayMode != NULL)
|
||||
{
|
||||
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
|
||||
*freq = (int)CGDisplayModeGetRefreshRate(currentMode);
|
||||
|
||||
// We're responsible for this
|
||||
CGDisplayModeRelease(currentMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif // fallback to 10.5 API
|
||||
CFDictionaryRef currentMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
|
||||
CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayRefreshRate);
|
||||
CFNumberGetValue(num, kCFNumberIntType, freq);
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// We're responsible for this
|
||||
CGDisplayModeRelease(currentMode);
|
||||
#endif
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
@ -161,3 +179,10 @@ OsPath sys_ExecutablePathname()
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
#if GCC_VERSION >= 402
|
||||
# pragma GCC diagnostic warning "-Wdeprecated-declarations"
|
||||
# if GCC_VERSION >= 406
|
||||
# pragma GCC diagnostic pop // restore user flags
|
||||
# endif
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2012 Wildfire Games
|
||||
/* Copyright (c) 2013 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -58,18 +58,19 @@ std::string osx_GetBundlePath()
|
||||
NSBundle *bundle = [NSBundle bundleWithIdentifier: [NSString stringWithUTF8String: BUNDLE_ID_STR]];
|
||||
if (bundle != nil)
|
||||
{
|
||||
NSString *pathStr;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// Retrieve NSURL and convert to POSIX path, then get C-string
|
||||
// encoded as UTF-8, and use it to construct std::string
|
||||
// NSURL:path "If the receiver does not conform to RFC 1808, returns nil."
|
||||
NSString *pathStr = [[bundle bundleURL] path];
|
||||
#else
|
||||
NSString *pathStr = [bundle bundlePath];
|
||||
if ([bundle respondsToSelector: @selector(bundleURL)])
|
||||
pathStr = [[bundle bundleURL] path];
|
||||
else
|
||||
#endif
|
||||
pathStr = [bundle bundlePath];
|
||||
|
||||
if (pathStr != nil)
|
||||
{
|
||||
path = std::string([pathStr UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
@ -84,18 +85,19 @@ std::string osx_GetBundleResourcesPath()
|
||||
NSBundle *bundle = [NSBundle bundleWithIdentifier: [NSString stringWithUTF8String: BUNDLE_ID_STR]];
|
||||
if (bundle != nil)
|
||||
{
|
||||
NSString *pathStr;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// Retrieve NSURL and convert to POSIX path, then get C-string
|
||||
// encoded as UTF-8, and use it to construct std::string
|
||||
// NSURL:path "If the receiver does not conform to RFC 1808, returns nil."
|
||||
NSString *pathStr = [[bundle resourceURL] path];
|
||||
#else
|
||||
NSString *pathStr = [bundle resourcePath];
|
||||
if ([bundle respondsToSelector: @selector(resourceURL)])
|
||||
pathStr = [[bundle resourceURL] path];
|
||||
else
|
||||
#endif
|
||||
pathStr = [bundle resourcePath];
|
||||
|
||||
if (pathStr != nil)
|
||||
{
|
||||
path = std::string([pathStr UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
@ -110,18 +112,19 @@ std::string osx_GetBundleFrameworksPath()
|
||||
NSBundle *bundle = [NSBundle bundleWithIdentifier: [NSString stringWithUTF8String: BUNDLE_ID_STR]];
|
||||
if (bundle != nil)
|
||||
{
|
||||
NSString *pathStr;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// Retrieve NSURL and convert to POSIX path, then get C-string
|
||||
// encoded as UTF-8, and use it to construct std::string
|
||||
// NSURL:path "If the receiver does not conform to RFC 1808, returns nil."
|
||||
NSString *pathStr = [[bundle privateFrameworksURL] path];
|
||||
#else
|
||||
NSString *pathStr = [bundle privateFrameworksPath];
|
||||
if ([bundle respondsToSelector: @selector(privateFrameworksURL)])
|
||||
pathStr = [[bundle privateFrameworksURL] path];
|
||||
else
|
||||
#endif
|
||||
pathStr = [bundle privateFrameworksPath];
|
||||
|
||||
if (pathStr != nil)
|
||||
{
|
||||
path = std::string([pathStr UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2012 Wildfire Games
|
||||
/* Copyright (c) 2013 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -33,22 +33,29 @@ bool osx_GetStringFromPasteboard(std::string& out)
|
||||
NSString* string = nil;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// As of 10.6, pasteboards can hold multiple items
|
||||
NSArray* classes = [NSArray arrayWithObjects:[NSString class], nil];
|
||||
NSDictionary* options = [NSDictionary dictionary];
|
||||
NSArray* copiedItems = [pasteboard readObjectsForClasses:classes options:options];
|
||||
if (copiedItems != nil && [copiedItems count] > 0)
|
||||
if ([pasteboard respondsToSelector: @selector(readObjectsForClasses:)])
|
||||
{
|
||||
NSArray* classes = [NSArray arrayWithObjects:[NSString class], nil];
|
||||
NSDictionary* options = [NSDictionary dictionary];
|
||||
NSArray* copiedItems = [pasteboard readObjectsForClasses:classes options:options];
|
||||
// We only need to support a single item, so grab the first string
|
||||
string = [copiedItems objectAtIndex:0];
|
||||
if (copiedItems != nil && [copiedItems count] > 0)
|
||||
string = [copiedItems objectAtIndex:0];
|
||||
else
|
||||
return false; // No strings found on pasteboard
|
||||
}
|
||||
else
|
||||
return false; // No strings found on pasteboard
|
||||
#else // 10.5
|
||||
// Verify that there is a string available for us
|
||||
NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil];
|
||||
if ([pasteboard availableTypeFromArray:types] != nil)
|
||||
string = [pasteboard stringForType:NSStringPboardType];
|
||||
else
|
||||
return false; // No strings found on pasteboard
|
||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
{
|
||||
#endif // fallback to 10.5 API
|
||||
// Verify that there is a string available for us
|
||||
NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil];
|
||||
if ([pasteboard availableTypeFromArray:types] != nil)
|
||||
string = [pasteboard stringForType:NSStringPboardType];
|
||||
else
|
||||
return false; // No strings found on pasteboard
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
}
|
||||
#endif
|
||||
|
||||
if (string != nil)
|
||||
out = std::string([string UTF8String]);
|
||||
@ -63,15 +70,24 @@ bool osx_SendStringToPasteboard(const std::string& string)
|
||||
// We're only working with strings, so we don't need to lazily write
|
||||
// anything (otherwise we'd need to set up an owner and data provider)
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
NSString* type;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
NSString* type = NSPasteboardTypeString;
|
||||
[pasteboard clearContents];
|
||||
#else // 10.5
|
||||
NSString* type = NSStringPboardType;
|
||||
NSArray* types = [NSArray arrayWithObjects: type, nil];
|
||||
// Roughly equivalent to clearContents followed by addTypes:owner
|
||||
[pasteboard declareTypes:types owner:nil];
|
||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
if ([pasteboard respondsToSelector: @selector(clearContents)])
|
||||
{
|
||||
type = NSPasteboardTypeString;
|
||||
[pasteboard clearContents];
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif // fallback to 10.5 API
|
||||
type = NSStringPboardType;
|
||||
NSArray* types = [NSArray arrayWithObjects: type, nil];
|
||||
// Roughly equivalent to clearContents followed by addTypes:owner
|
||||
[pasteboard declareTypes:types owner:nil];
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// May raise a NSPasteboardCommunicationException
|
||||
BOOL ok = [pasteboard setString:[NSString stringWithUTF8String:string.c_str()] forType:type];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2012 Wildfire Games
|
||||
/* Copyright (c) 2013 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -32,22 +32,28 @@ static std::string getUserDirectoryPath(NSSearchPathDirectory directory)
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
std::string result;
|
||||
|
||||
NSArray* paths;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// Returns array of NSURL objects which are preferred for file paths
|
||||
NSArray* paths = [[NSFileManager defaultManager] URLsForDirectory:directory inDomains:NSUserDomainMask];
|
||||
#else
|
||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, true);
|
||||
#endif
|
||||
if ([NSFileManager instancesRespondToSelector:@selector(URLsForDirectory)])
|
||||
paths = [[NSFileManager defaultManager] URLsForDirectory:directory inDomains:NSUserDomainMask];
|
||||
else
|
||||
#endif // fallback to 10.5 API
|
||||
paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, true);
|
||||
|
||||
if ([paths count] > 0)
|
||||
{
|
||||
NSString* pathStr;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
// Retrieve first NSURL and convert to POSIX path, then get C-string
|
||||
// encoded as UTF-8, and use it to construct std::string
|
||||
// NSURL:path "If the receiver does not conform to RFC 1808, returns nil."
|
||||
NSString* pathStr = [[paths objectAtIndex:0] path];
|
||||
#else
|
||||
NSString* pathStr = [paths objectAtIndex:0];
|
||||
#endif
|
||||
if ([NSFileManager instancesRespondToSelector:@selector(URLsForDirectory)])
|
||||
pathStr = [[paths objectAtIndex:0] path];
|
||||
else
|
||||
#endif // fallback to 10.5 API
|
||||
pathStr = [paths objectAtIndex:0];
|
||||
|
||||
if (pathStr != nil)
|
||||
result = std::string([pathStr UTF8String]);
|
||||
}
|
||||
|
@ -20,48 +20,50 @@
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#import <AvailabilityMacros.h> // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <dispatch/dispatch.h>
|
||||
#import <string>
|
||||
|
||||
#import "osx_bundle.h"
|
||||
#import "osx_sys_version.h"
|
||||
|
||||
#define STRINGIZE2(id) # id
|
||||
#define STRINGIZE(id) STRINGIZE2(id)
|
||||
|
||||
// Pass the bundle identifier string as a build option
|
||||
#ifdef BUNDLE_IDENTIFIER
|
||||
static const char* BUNDLE_ID_STR = STRINGIZE(BUNDLE_IDENTIFIER);
|
||||
#else
|
||||
static const char* BUNDLE_ID_STR = "";
|
||||
#endif
|
||||
|
||||
|
||||
void GetSystemVersion( int &major, int &minor, int &bugfix )
|
||||
void GetSystemVersion(int &major, int &minor, int &bugfix)
|
||||
{
|
||||
// sensible default
|
||||
static int mMajor = 10;
|
||||
static int mMinor = 8;
|
||||
static int mBugfix = 0;
|
||||
// grand central dispatch only available on 10.6+
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
if (dispatch_once != nil)
|
||||
{
|
||||
// sensible default
|
||||
static int mMajor = 10;
|
||||
static int mMinor = 8;
|
||||
static int mBugfix = 0;
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
|
||||
NSArray* versions = [versionString componentsSeparatedByString:@"."];
|
||||
check( versions.count >= 2 );
|
||||
if ( versions.count >= 1 ) {
|
||||
mMajor = [[versions objectAtIndex:0] integerValue];
|
||||
}
|
||||
if ( versions.count >= 2 ) {
|
||||
mMinor = [[versions objectAtIndex:1] integerValue];
|
||||
}
|
||||
if ( versions.count >= 3 ) {
|
||||
mBugfix = [[versions objectAtIndex:2] integerValue];
|
||||
}
|
||||
});
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
|
||||
NSArray* versions = [versionString componentsSeparatedByString:@"."];
|
||||
check(versions.count >= 2);
|
||||
if (versions.count >= 1)
|
||||
mMajor = [[versions objectAtIndex:0] integerValue];
|
||||
if (versions.count >= 2)
|
||||
mMinor = [[versions objectAtIndex:1] integerValue];
|
||||
if (versions.count >= 3)
|
||||
mBugfix = [[versions objectAtIndex:2] integerValue];
|
||||
});
|
||||
|
||||
major = mMajor;
|
||||
minor = mMinor;
|
||||
bugfix = mBugfix;
|
||||
major = mMajor;
|
||||
minor = mMinor;
|
||||
bugfix = mBugfix;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif // fallback to 10.5 API
|
||||
// just return 10.5.0, it's unlikely we support an earlier OS
|
||||
// and unlikely we care about bugfix versions
|
||||
major = 10;
|
||||
minor = 5;
|
||||
bugfix = 0;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user