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=
fi
if [ "$BUILD_ON_MAC" = "yes" ]; then
echo "COCOA_LFLAGS =-framework Foundation -framework CoreServices" >>"$mkfile"
echo "CARBON_LFLAGS =-framework ApplicationServices" >>"$mkfile"
echo "CARBON_CFLAGS =-fconstant-cfstrings" >>"$mkfile"
EXTRA_LFLAGS="$EXTRA_LFLAGS \$(COCOA_LFLAGS)"
EXTRA_LFLAGS="$EXTRA_LFLAGS \$(CARBON_LFLAGS)"
EXTRA_CFLAGS="$EXTRA_CFLAGS \$(CARBON_CFLAGS)"
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(CARBON_CFLAGS)"
EXTRA_OBJS="$EXTRA_OBJS \
qsettings_mac.o \
qcore_mac.o"
qcore_mac.o \
qcore_mac_objc.o"
EXTRA_SRCS="$EXTRA_SRCS \
\"\$(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
if [ '!' -z "$D_FLAGS" ]; then
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/qlinkedlist.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/qsettings.cpp $(SOURCE_PATH)/src/corelib/kernel/qvariant.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
$(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
$(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
mac {
SOURCES += qcore_mac.cpp qsettings_mac.cpp
OBJECTIVE_SOURCES += qlocale_mac.mm
LIBS += -framework ApplicationServices
OBJECTIVE_SOURCES += qcore_mac_objc.mm qlocale_mac.mm
LIBS += -framework ApplicationServices -framework CoreServices -framework Foundation
} else {
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()
{
const QAppleOperatingSystemVersion version = qt_apple_os_version(); // qtcore_mac_objc.mm
#if defined(Q_OS_OSX)
SInt32 gestalt_version;
if (Gestalt(gestaltSystemVersionMinor, &gestalt_version) == noErr) {
// add 2 because OS X 10.0 is 0x02 in the enum
return QSysInfo::MacVersion(gestalt_version + 2);
}
return QSysInfo::MacVersion(Q_MV_OSX(version.major, version.minor));
#elif defined(Q_OS_IOS)
return qt_ios_version(); // qtcore_mac_objc.mm
#endif
return QSysInfo::MacVersion(Q_MV_IOS(version.major, version.minor));
#else
return QSysInfo::MV_Unknown;
#endif
}
const QSysInfo::MacVersion QSysInfo::MacintoshVersion = QSysInfo::macVersion();
@ -2502,25 +2500,9 @@ QString QSysInfo::productType()
*/
QString QSysInfo::productVersion()
{
#if defined(Q_OS_IOS)
int major = (int(MacintoshVersion) >> 4) & 0xf;
int minor = int(MacintoshVersion) & 0xf;
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);
#if defined(Q_OS_MAC)
const QAppleOperatingSystemVersion version = qt_apple_os_version();
return QString::number(version.major) + QLatin1Char('.') + QString::number(version.minor);
#elif defined(Q_OS_WIN)
const char *version = winVer_helper();
if (version)

View File

@ -120,6 +120,7 @@ public:
#endif
#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)
enum MacVersion {
MV_Unknown = 0x0000,

View File

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

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
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -47,6 +48,8 @@
QT_BEGIN_NAMESPACE
typedef qint16 (*GestaltFunction)(quint32 selector, qint32 *response);
NSString *QCFString::toNSString(const QString &string)
{
// 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));
}
#ifdef Q_OS_IOS
QSysInfo::MacVersion qt_ios_version()
QAppleOperatingSystemVersion qt_apple_os_version()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int major = 0, minor = 0;
NSArray *components = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
switch ([components count]) {
case 3:
// We don't care about the patch version
case 2:
minor = [[components objectAtIndex:1] intValue];
// fall through
case 1:
major = [[components objectAtIndex:0] intValue];
break;
default:
Q_UNREACHABLE();
QAppleOperatingSystemVersion v = {0, 0, 0};
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_8_0)
if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) {
NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion;
v.major = osv.majorVersion;
v.minor = osv.minorVersion;
v.patch = osv.patchVersion;
return v;
}
[pool release];
return QSysInfo::MacVersion(Q_MV_IOS(major, minor));
}
#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

View File

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

View File

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