Use new, supported APIs in OS X 10.10 and iOS 8.0 to get the OS version.

Gestalt is deprecated so we can't use it long term. At the same time,
the new API is cross platform, so we'll no longer have to parse strings
in -[UIDevice systemVersion] either.

Change-Id: Ic81797174c1a3d50b47b9b209205a6a506cc75ef
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
This commit is contained in:
Jake Petroules 2014-06-13 18:59:30 -04:00
parent fac71528cc
commit 4e8720d413
9 changed files with 92 additions and 70 deletions

8
configure vendored
View File

@ -3751,17 +3751,21 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ];
EXEEXT= EXEEXT=
fi fi
if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$BUILD_ON_MAC" = "yes" ]; then
echo "COCOA_LFLAGS =-framework Foundation -framework CoreServices" >>"$mkfile"
echo "CARBON_LFLAGS =-framework ApplicationServices" >>"$mkfile" echo "CARBON_LFLAGS =-framework ApplicationServices" >>"$mkfile"
echo "CARBON_CFLAGS =-fconstant-cfstrings" >>"$mkfile" echo "CARBON_CFLAGS =-fconstant-cfstrings" >>"$mkfile"
EXTRA_LFLAGS="$EXTRA_LFLAGS \$(COCOA_LFLAGS)"
EXTRA_LFLAGS="$EXTRA_LFLAGS \$(CARBON_LFLAGS)" EXTRA_LFLAGS="$EXTRA_LFLAGS \$(CARBON_LFLAGS)"
EXTRA_CFLAGS="$EXTRA_CFLAGS \$(CARBON_CFLAGS)" EXTRA_CFLAGS="$EXTRA_CFLAGS \$(CARBON_CFLAGS)"
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(CARBON_CFLAGS)" EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(CARBON_CFLAGS)"
EXTRA_OBJS="$EXTRA_OBJS \ EXTRA_OBJS="$EXTRA_OBJS \
qsettings_mac.o \ qsettings_mac.o \
qcore_mac.o" qcore_mac.o \
qcore_mac_objc.o"
EXTRA_SRCS="$EXTRA_SRCS \ EXTRA_SRCS="$EXTRA_SRCS \
\"\$(SOURCE_PATH)/src/corelib/io/qsettings_mac.cpp\" \ \"\$(SOURCE_PATH)/src/corelib/io/qsettings_mac.cpp\" \
\"\$(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp\"" \"\$(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp\" \
\"\$(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm\""
fi fi
if [ '!' -z "$D_FLAGS" ]; then if [ '!' -z "$D_FLAGS" ]; then
EXTRA_CFLAGS="$EXTRA_CFLAGS $D_FLAGS" EXTRA_CFLAGS="$EXTRA_CFLAGS $D_FLAGS"

View File

@ -74,6 +74,7 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp \ $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp \
$(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp \ $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp \
$(SOURCE_PATH)/src/corelib/tools/qhash.cpp $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp \ $(SOURCE_PATH)/src/corelib/tools/qhash.cpp $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp \
$(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm \
$(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp \ $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp \
$(SOURCE_PATH)/src/corelib/io/qsettings.cpp $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp \ $(SOURCE_PATH)/src/corelib/io/qsettings.cpp $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp \
$(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp \ $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp \
@ -269,6 +270,9 @@ qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
qcore_mac.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp qcore_mac.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp
qcore_mac_objc.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm
qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp

View File

@ -138,8 +138,8 @@ bootstrap { #Qt code
SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp
mac { mac {
SOURCES += qcore_mac.cpp qsettings_mac.cpp SOURCES += qcore_mac.cpp qsettings_mac.cpp
OBJECTIVE_SOURCES += qlocale_mac.mm OBJECTIVE_SOURCES += qcore_mac_objc.mm qlocale_mac.mm
LIBS += -framework ApplicationServices LIBS += -framework ApplicationServices -framework CoreServices -framework Foundation
} else { } else {
SOURCES += qlocale_unix.cpp SOURCES += qlocale_unix.cpp
} }

View File

@ -1854,16 +1854,14 @@ Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr) {
QSysInfo::MacVersion QSysInfo::macVersion() QSysInfo::MacVersion QSysInfo::macVersion()
{ {
const QAppleOperatingSystemVersion version = qt_apple_os_version(); // qtcore_mac_objc.mm
#if defined(Q_OS_OSX) #if defined(Q_OS_OSX)
SInt32 gestalt_version; return QSysInfo::MacVersion(Q_MV_OSX(version.major, version.minor));
if (Gestalt(gestaltSystemVersionMinor, &gestalt_version) == noErr) {
// add 2 because OS X 10.0 is 0x02 in the enum
return QSysInfo::MacVersion(gestalt_version + 2);
}
#elif defined(Q_OS_IOS) #elif defined(Q_OS_IOS)
return qt_ios_version(); // qtcore_mac_objc.mm return QSysInfo::MacVersion(Q_MV_IOS(version.major, version.minor));
#endif #else
return QSysInfo::MV_Unknown; return QSysInfo::MV_Unknown;
#endif
} }
const QSysInfo::MacVersion QSysInfo::MacintoshVersion = QSysInfo::macVersion(); const QSysInfo::MacVersion QSysInfo::MacintoshVersion = QSysInfo::macVersion();
@ -2502,25 +2500,9 @@ QString QSysInfo::productType()
*/ */
QString QSysInfo::productVersion() QString QSysInfo::productVersion()
{ {
#if defined(Q_OS_IOS) #if defined(Q_OS_MAC)
int major = (int(MacintoshVersion) >> 4) & 0xf; const QAppleOperatingSystemVersion version = qt_apple_os_version();
int minor = int(MacintoshVersion) & 0xf; return QString::number(version.major) + QLatin1Char('.') + QString::number(version.minor);
if (Q_LIKELY(major < 10 && minor < 10)) {
char buf[4] = { char(major + '0'), '.', char(minor + '0'), '\0' };
return QString::fromLatin1(buf, 3);
}
return QString::number(major) + QLatin1Char('.') + QString::number(minor);
#elif defined(Q_OS_OSX)
int minor = int(MacintoshVersion) - 2; // we're not running on Mac OS 9
Q_ASSERT(minor < 100);
char buf[] = "10.0\0";
if (Q_LIKELY(minor < 10)) {
buf[3] += minor;
} else {
buf[3] += minor / 10;
buf[4] = '0' + minor % 10;
}
return QString::fromLatin1(buf);
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
const char *version = winVer_helper(); const char *version = winVer_helper();
if (version) if (version)

View File

@ -120,6 +120,7 @@ public:
#endif #endif
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
# define Q_MV_OSX(major, minor) (major == 10 ? minor + 2 : (major == 9 ? 1 : 0))
# define Q_MV_IOS(major, minor) (QSysInfo::MV_IOS | major << 4 | minor) # define Q_MV_IOS(major, minor) (QSysInfo::MV_IOS | major << 4 | minor)
enum MacVersion { enum MacVersion {
MV_Unknown = 0x0000, MV_Unknown = 0x0000,

View File

@ -99,18 +99,20 @@ winrt {
} }
mac { mac {
SOURCES += \
kernel/qcoreapplication_mac.cpp
}
mac:!nacl {
HEADERS += \ HEADERS += \
kernel/qcore_mac_p.h kernel/qcore_mac_p.h
SOURCES += \ SOURCES += \
kernel/qcoreapplication_mac.cpp \
kernel/qcore_mac.cpp kernel/qcore_mac.cpp
OBJECTIVE_SOURCES += \ OBJECTIVE_SOURCES += \
kernel/qcore_mac_objc.mm kernel/qcore_mac_objc.mm
LIBS_PRIVATE += -framework Foundation
osx: LIBS_PRIVATE += -framework CoreServices
# We need UIKit for UIDevice # We need UIKit for UIDevice
ios: LIBS_PRIVATE += -framework UIKit ios: LIBS_PRIVATE += -framework UIKit
} }

View File

@ -1,6 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Copyright (C) 2014 Petroules Corporation.
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the QtCore module of the Qt Toolkit. ** This file is part of the QtCore module of the Qt Toolkit.
@ -47,6 +48,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
typedef qint16 (*GestaltFunction)(quint32 selector, qint32 *response);
NSString *QCFString::toNSString(const QString &string) NSString *QCFString::toNSString(const QString &string)
{ {
// The const cast below is safe: CfStringRef is immutable and so is NSString. // The const cast below is safe: CfStringRef is immutable and so is NSString.
@ -58,31 +61,49 @@ QString QCFString::toQString(const NSString *nsstr)
return toQString(reinterpret_cast<CFStringRef>(nsstr)); return toQString(reinterpret_cast<CFStringRef>(nsstr));
} }
#ifdef Q_OS_IOS QAppleOperatingSystemVersion qt_apple_os_version()
QSysInfo::MacVersion qt_ios_version()
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; QAppleOperatingSystemVersion v = {0, 0, 0};
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_8_0)
int major = 0, minor = 0; if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) {
NSArray *components = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion;
switch ([components count]) { v.major = osv.majorVersion;
case 3: v.minor = osv.minorVersion;
// We don't care about the patch version v.patch = osv.patchVersion;
case 2: return v;
minor = [[components objectAtIndex:1] intValue];
// fall through
case 1:
major = [[components objectAtIndex:0] intValue];
break;
default:
Q_UNREACHABLE();
} }
[pool release];
return QSysInfo::MacVersion(Q_MV_IOS(major, minor));
}
#endif #endif
// Use temporary variables so we can return 0.0.0 (unknown version)
// in case of an error partway through determining the OS version
qint32 major = 0, minor = 0, patch = 0;
#if defined(Q_OS_IOS)
@autoreleasepool {
NSArray *parts = [UIDevice.currentDevice.systemVersion componentsSeparatedByString:@"."];
major = parts.count > 0 ? [[parts objectAtIndex:0] intValue] : 0;
minor = parts.count > 1 ? [[parts objectAtIndex:1] intValue] : 0;
patch = parts.count > 2 ? [[parts objectAtIndex:2] intValue] : 0;
}
#elif defined(Q_OS_OSX)
static GestaltFunction pGestalt = 0;
if (!pGestalt) {
CFBundleRef b = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CoreServices"));
pGestalt = reinterpret_cast<GestaltFunction>(CFBundleGetFunctionPointerForName(b,
CFSTR("Gestalt")));
}
if (!pGestalt)
return v;
if (pGestalt('sys1', &major) != 0)
return v;
if (pGestalt('sys2', &minor) != 0)
return v;
if (pGestalt('sys3', &patch) != 0)
return v;
#endif
v.major = major;
v.minor = minor;
v.patch = patch;
return v;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -143,9 +143,11 @@ private:
QString string; QString string;
}; };
#ifdef Q_OS_IOS typedef struct {
QSysInfo::MacVersion qt_ios_version(); int major, minor, patch;
#endif } QAppleOperatingSystemVersion;
QAppleOperatingSystemVersion qt_apple_os_version();
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -130,9 +130,15 @@ win32:SOURCES += ../../corelib/io/qfilesystemengine_win.cpp \
../../corelib/plugin/qsystemlibrary.cpp \ ../../corelib/plugin/qsystemlibrary.cpp \
mac { mac {
SOURCES += ../../corelib/kernel/qcoreapplication_mac.cpp \ SOURCES += \
../../corelib/kernel/qcoreapplication_mac.cpp \
../../corelib/kernel/qcore_mac.cpp ../../corelib/kernel/qcore_mac.cpp
LIBS += -framework CoreServices OBJECTIVE_SOURCES += \
../../corelib/kernel/qcore_mac_objc.mm
LIBS += -framework Foundation
osx: LIBS_PRIVATE += -framework CoreServices
ios: LIBS_PRIVATE += -framework UIKit
} }
macx { macx {