summaryrefslogtreecommitdiffstats
path: root/src/corelib/global
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global')
-rw-r--r--src/corelib/global/global.pri6
-rw-r--r--src/corelib/global/qglobal.cpp328
-rw-r--r--src/corelib/global/qglobal.h21
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/global/qnamespace.qdoc9
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp439
-rw-r--r--src/corelib/global/qoperatingsystemversion.h129
-rw-r--r--src/corelib/global/qoperatingsystemversion_darwin.mm101
-rw-r--r--src/corelib/global/qoperatingsystemversion_p.h87
-rw-r--r--src/corelib/global/qoperatingsystemversion_win.cpp171
-rw-r--r--src/corelib/global/qsysinfo.h53
11 files changed, 1146 insertions, 199 deletions
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 36655ca1dd..d23706e631 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -2,6 +2,8 @@
HEADERS += \
global/qglobal.h \
+ global/qoperatingsystemversion.h \
+ global/qoperatingsystemversion_p.h \
global/qsystemdetection.h \
global/qcompilerdetection.h \
global/qprocessordetection.h \
@@ -27,11 +29,15 @@ SOURCES += \
global/qlibraryinfo.cpp \
global/qmalloc.cpp \
global/qnumeric.cpp \
+ global/qoperatingsystemversion.cpp \
global/qlogging.cpp \
global/qhooks.cpp
VERSIONTAGGING_SOURCES = global/qversiontagging.cpp
+darwin: SOURCES += global/qoperatingsystemversion_darwin.mm
+win32: SOURCES += global/qoperatingsystemversion_win.cpp
+
# qlibraryinfo.cpp includes qconfig.cpp
INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 6efdc4c22c..47aca712b7 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -45,6 +45,8 @@
#include "qthreadstorage.h"
#include "qdir.h"
#include "qdatetime.h"
+#include "qoperatingsystemversion.h"
+#include "qoperatingsystemversion_p.h"
#include <private/qlocale_tools_p.h>
#include <qmutex.h>
@@ -1064,10 +1066,6 @@ bool qSharedBuild() Q_DECL_NOTHROW
on which the application is compiled.
\li \l ByteOrder specifies whether the platform is big-endian or
little-endian.
- \li \l WindowsVersion specifies the version of the Windows operating
- system on which the application is run.
- \li \l MacintoshVersion specifies the version of the Macintosh
- operating system on which the application is run.
\endlist
Some constants are defined only on certain platforms. You can use
@@ -1088,12 +1086,14 @@ bool qSharedBuild() Q_DECL_NOTHROW
*/
/*!
+ \deprecated
\variable QSysInfo::WindowsVersion
\brief the version of the Windows operating system on which the
application is run.
*/
/*!
+ \deprecated
\fn QSysInfo::WindowsVersion QSysInfo::windowsVersion()
\since 4.4
@@ -1103,12 +1103,14 @@ bool qSharedBuild() Q_DECL_NOTHROW
*/
/*!
+ \deprecated
\variable QSysInfo::MacintoshVersion
\brief the version of the Macintosh operating system on which
the application is run.
*/
/*!
+ \deprecated
\fn QSysInfo::MacVersion QSysInfo::macVersion()
Returns the version of Darwin (\macos or iOS) on which the
@@ -1126,6 +1128,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
*/
/*!
+ \deprecated
\enum QSysInfo::WinVersion
This enum provides symbolic names for the various versions of the
@@ -1182,6 +1185,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
*/
/*!
+ \deprecated
\enum QSysInfo::MacVersion
This enum provides symbolic names for the various versions of the
@@ -1949,28 +1953,31 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include "qnamespace.h"
QT_END_INCLUDE_NAMESPACE
+#if QT_DEPRECATED_SINCE(5, 9)
QSysInfo::MacVersion QSysInfo::macVersion()
{
- const QAppleOperatingSystemVersion version = qt_apple_os_version(); // qtcore_mac_objc.mm
+ const auto version = QOperatingSystemVersion::current();
#if defined(Q_OS_OSX)
- return QSysInfo::MacVersion(Q_MV_OSX(version.major, version.minor));
+ return QSysInfo::MacVersion(Q_MV_OSX(version.majorVersion(), version.minorVersion()));
#elif defined(Q_OS_IOS)
- return QSysInfo::MacVersion(Q_MV_IOS(version.major, version.minor));
+ return QSysInfo::MacVersion(Q_MV_IOS(version.majorVersion(), version.minorVersion()));
#elif defined(Q_OS_TVOS)
- return QSysInfo::MacVersion(Q_MV_TVOS(version.major, version.minor));
+ return QSysInfo::MacVersion(Q_MV_TVOS(version.majorVersion(), version.minorVersion()));
#elif defined(Q_OS_WATCHOS)
- return QSysInfo::MacVersion(Q_MV_WATCHOS(version.major, version.minor));
+ return QSysInfo::MacVersion(Q_MV_WATCHOS(version.majorVersion(), version.minorVersion()));
#else
return QSysInfo::MV_Unknown;
#endif
}
const QSysInfo::MacVersion QSysInfo::MacintoshVersion = QSysInfo::macVersion();
+#endif
-#ifdef Q_OS_OSX
-static const char *osxVer_helper(QAppleOperatingSystemVersion version = qt_apple_os_version())
+#ifdef Q_OS_DARWIN
+static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current())
{
- if (version.major == 10) {
- switch (version.minor) {
+#ifdef Q_OS_MACOS
+ if (version.majorVersion() == 10) {
+ switch (version.minorVersion()) {
case 9:
return "Mavericks";
case 10:
@@ -1982,6 +1989,9 @@ static const char *osxVer_helper(QAppleOperatingSystemVersion version = qt_apple
}
}
// unknown, future version
+#else
+ Q_UNUSED(version);
+#endif
return 0;
}
#endif
@@ -2022,140 +2032,30 @@ QWindowsSockInit::~QWindowsSockInit()
Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit)
# endif // QT_BOOTSTRAPPED
-#ifdef Q_OS_WINRT
-static inline HMODULE moduleHandleForFunction(LPCVOID address)
-{
- // This is a widely used, decades-old technique for retrieving the handle
- // of a module and is effectively equivalent to GetModuleHandleEx
- // (which is unavailable on WinRT)
- MEMORY_BASIC_INFORMATION mbi = { 0, 0, 0, 0, 0, 0, 0 };
- if (VirtualQuery(address, &mbi, sizeof(mbi)) == 0)
- return 0;
- return reinterpret_cast<HMODULE>(mbi.AllocationBase);
-}
-#endif
-
-static inline OSVERSIONINFOEX determineWinOsVersion()
-{
- OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0};
-
-#define GetProcAddressA GetProcAddress
-
- // GetModuleHandle is not supported in WinRT and linking to it at load time
- // will not pass the Windows App Certification Kit... but it exists and is functional,
- // so use some unusual but widely used techniques to get a pointer to it
-#ifdef Q_OS_WINRT
- // 1. Get HMODULE of kernel32.dll, using the address of some function exported by that DLL
- HMODULE kernelModule = moduleHandleForFunction(reinterpret_cast<LPCVOID>(VirtualQuery));
- if (Q_UNLIKELY(!kernelModule))
- return result;
-
- // 2. Get pointer to GetModuleHandle so we can then load other arbitrary modules (DLLs)
- typedef HMODULE(WINAPI *GetModuleHandleFunction)(LPCWSTR);
- GetModuleHandleFunction pGetModuleHandle = reinterpret_cast<GetModuleHandleFunction>(
- GetProcAddressA(kernelModule, "GetModuleHandleW"));
- if (Q_UNLIKELY(!pGetModuleHandle))
- return result;
-#else
-#define pGetModuleHandle GetModuleHandleW
-#endif
-
-#ifndef Q_OS_WINCE
- HMODULE ntdll = pGetModuleHandle(L"ntdll.dll");
- if (Q_UNLIKELY(!ntdll))
- return result;
-
- // NTSTATUS is not defined on WinRT
- typedef LONG NTSTATUS;
- typedef NTSTATUS (NTAPI *RtlGetVersionFunction)(LPOSVERSIONINFO);
-
- // RtlGetVersion is documented public API but we must load it dynamically
- // because linking to it at load time will not pass the Windows App Certification Kit
- // https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910.aspx
- RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
- GetProcAddressA(ntdll, "RtlGetVersion"));
- if (Q_UNLIKELY(!pRtlGetVersion))
- return result;
-
- // GetVersionEx() has been deprecated in Windows 8.1 and will return
- // only Windows 8 from that version on, so use the kernel API function.
- pRtlGetVersion((LPOSVERSIONINFO) &result); // always returns STATUS_SUCCESS
-#else // !Q_OS_WINCE
- GetVersionEx(&result);
-#endif
- return result;
-}
-
-static OSVERSIONINFOEX winOsVersion()
-{
- OSVERSIONINFOEX realResult = determineWinOsVersion();
-#ifdef QT_DEBUG
- {
- if (Q_UNLIKELY(qEnvironmentVariableIsSet("QT_WINVER_OVERRIDE"))) {
- OSVERSIONINFOEX result = realResult;
- result.dwMajorVersion = 0;
- result.dwMinorVersion = 0;
-
- // Erase any build number and service pack information
- result.dwBuildNumber = 0;
- result.szCSDVersion[0] = L'\0';
- result.wServicePackMajor = 0;
- result.wServicePackMinor = 0;
-
- const QByteArray winVerOverride = qgetenv("QT_WINVER_OVERRIDE");
- if (winVerOverride == "WINDOWS7" || winVerOverride == "2008_R2") {
- result.dwMajorVersion = 6;
- result.dwMinorVersion = 1;
- } else if (winVerOverride == "WINDOWS8" || winVerOverride == "2012") {
- result.dwMajorVersion = 6;
- result.dwMinorVersion = 2;
- } else if (winVerOverride == "WINDOWS8_1" || winVerOverride == "2012_R2") {
- result.dwMajorVersion = 6;
- result.dwMinorVersion = 3;
- } else if (winVerOverride == "WINDOWS10" || winVerOverride == "2016") {
- result.dwMajorVersion = 10;
- } else {
- return realResult;
- }
-
- if (winVerOverride == "2008_R2"
- || winVerOverride == "2012"
- || winVerOverride == "2012_R2"
- || winVerOverride == "2016") {
- // If the current host OS is a domain controller and the override OS
- // is also a server type OS, preserve that information
- if (result.wProductType == VER_NT_WORKSTATION)
- result.wProductType = VER_NT_SERVER;
- } else {
- // Any other OS must be a workstation OS type
- result.wProductType = VER_NT_WORKSTATION;
- }
- }
- }
-#endif
- return realResult;
-}
-
+#if QT_DEPRECATED_SINCE(5, 9)
QSysInfo::WinVersion QSysInfo::windowsVersion()
{
- const OSVERSIONINFOEX osver = winOsVersion();
- if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1)
+ const auto version = QOperatingSystemVersion::current();
+ if (version.majorVersion() == 6 && version.minorVersion() == 1)
return QSysInfo::WV_WINDOWS7;
- if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2)
+ if (version.majorVersion() == 6 && version.minorVersion() == 2)
return QSysInfo::WV_WINDOWS8;
- if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3)
+ if (version.majorVersion() == 6 && version.minorVersion() == 3)
return QSysInfo::WV_WINDOWS8_1;
- if (osver.dwMajorVersion == 10 && osver.dwMinorVersion == 0)
+ if (version.majorVersion() == 10 && version.minorVersion() == 0)
return QSysInfo::WV_WINDOWS10;
return QSysInfo::WV_NT_based;
}
+const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion();
+#endif
static QString winSp_helper()
{
- const qint16 major = winOsVersion().wServicePackMajor;
+ const auto osv = qWindowsVersionInfo();
+ const qint16 major = osv.wServicePackMajor;
if (major) {
QString sp = QStringLiteral(" SP ") + QString::number(major);
- const qint16 minor = winOsVersion().wServicePackMinor;
+ const qint16 minor = osv.wServicePackMinor;
if (minor)
sp += QLatin1Char('.') + QString::number(minor);
@@ -2164,9 +2064,10 @@ static QString winSp_helper()
return QString();
}
-static const char *winVer_helper()
+static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current())
{
- const OSVERSIONINFOEX osver = winOsVersion();
+ Q_UNUSED(version);
+ const OSVERSIONINFOEX osver = qWindowsVersionInfo();
const bool workstation = osver.wProductType == VER_NT_WORKSTATION;
#define Q_WINVER(major, minor) (major << 8 | minor)
@@ -2185,8 +2086,6 @@ static const char *winVer_helper()
return 0;
}
-const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion();
-
#endif
#if defined(Q_OS_UNIX)
# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
@@ -2367,6 +2266,68 @@ static bool findUnixOsVersion(QUnixOSVersion &v)
# endif // USE_ETC_OS_RELEASE
#endif // Q_OS_UNIX
+#ifdef Q_OS_ANDROID
+static const char *osVer_helper(QOperatingSystemVersion)
+{
+/* Data:
+
+
+
+Cupcake
+Donut
+Eclair
+Eclair
+Eclair
+Froyo
+Gingerbread
+Gingerbread
+Honeycomb
+Honeycomb
+Honeycomb
+Ice Cream Sandwich
+Ice Cream Sandwich
+Jelly Bean
+Jelly Bean
+Jelly Bean
+KitKat
+KitKat
+Lollipop
+Lollipop
+Marshmallow
+Nougat
+Nougat
+ */
+ static const char versions_string[] =
+ "\0"
+ "Cupcake\0"
+ "Donut\0"
+ "Eclair\0"
+ "Froyo\0"
+ "Gingerbread\0"
+ "Honeycomb\0"
+ "Ice Cream Sandwich\0"
+ "Jelly Bean\0"
+ "KitKat\0"
+ "Lollipop\0"
+ "Marshmallow\0"
+ "Nougat\0"
+ "\0";
+
+ static const int versions_indices[] = {
+ 0, 0, 0, 1, 9, 15, 15, 15,
+ 22, 28, 28, 40, 40, 40, 50, 50,
+ 69, 69, 69, 80, 80, 87, 87, 96,
+ 108, 108, -1
+ };
+
+ static const int versions_count = (sizeof versions_indices) / (sizeof versions_indices[0]);
+
+ // https://source.android.com/source/build-numbers.html
+ // https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels
+ const int sdk_int = QJNIObjectPrivate::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT");
+ return &versions_string[versions_indices[qBound(0, sdk_int, versions_count - 1)]];
+}
+#endif
/*!
\since 5.4
@@ -2615,9 +2576,9 @@ QString QSysInfo::kernelType()
QString QSysInfo::kernelVersion()
{
#ifdef Q_OS_WIN
- const OSVERSIONINFOEX osver = winOsVersion();
- return QString::number(int(osver.dwMajorVersion)) + QLatin1Char('.') + QString::number(int(osver.dwMinorVersion))
- + QLatin1Char('.') + QString::number(int(osver.dwBuildNumber));
+ const auto osver = QOperatingSystemVersion::current();
+ return QString::number(osver.majorVersion()) + QLatin1Char('.') + QString::number(osver.minorVersion())
+ + QLatin1Char('.') + QString::number(osver.microVersion());
#else
struct utsname u;
if (uname(&u) == 0)
@@ -2685,8 +2646,8 @@ QString QSysInfo::productType()
#elif defined(Q_OS_WATCHOS)
return QStringLiteral("watchos");
#elif defined(Q_OS_MACOS)
- const QAppleOperatingSystemVersion version = qt_apple_os_version();
- if (version.major == 10 && version.minor < 12)
+ const auto version = QOperatingSystemVersion::current();
+ if (version.majorVersion() == 10 && version.minorVersion() < 12)
return QStringLiteral("osx");
return QStringLiteral("macos");
#elif defined(Q_OS_DARWIN)
@@ -2708,8 +2669,23 @@ QString QSysInfo::productType()
version could not be determined, this function returns "unknown".
It will return the Android, iOS, \macos, Windows full-product
- versions on those systems. In particular, on OS X, iOS and Windows, the
- returned string is similar to the macVersion() or windowsVersion() enums.
+ versions on those systems.
+
+ Typical returned values are (note: list not exhaustive):
+ \list
+ \li "2016.09" (Amazon Linux AMI 2016.09)
+ \li "7.1" (Android Nougat)
+ \li "25" (Fedora 25)
+ \li "10.1" (iOS 10.1)
+ \li "10.12" (macOS Sierra)
+ \li "10.0" (tvOS 10)
+ \li "16.10" (Ubuntu 16.10)
+ \li "3.1" (watchOS 3.1)
+ \li "7 SP 1" (Windows 7 Service Pack 1)
+ \li "8.1" (Windows 8.1)
+ \li "10" (Windows 10)
+ \li "Server 2016" (Windows Server 2016)
+ \endlist
On Linux systems, it will try to determine the distribution version and will
return that. This is also done on Debian/kFreeBSD, so this function will
@@ -2726,20 +2702,17 @@ QString QSysInfo::productType()
*/
QString QSysInfo::productVersion()
{
-#if defined(Q_OS_MAC)
- const QAppleOperatingSystemVersion version = qt_apple_os_version();
- return QString::number(version.major) + QLatin1Char('.') + QString::number(version.minor);
+#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN)
+ const auto version = QOperatingSystemVersion::current();
+ return QString::number(version.majorVersion()) + QLatin1Char('.') + QString::number(version.minorVersion());
#elif defined(Q_OS_WIN)
- const char *version = winVer_helper();
+ const char *version = osVer_helper();
if (version) {
const QLatin1Char spaceChar(' ');
return QString::fromLatin1(version).remove(spaceChar).toLower() + winSp_helper().remove(spaceChar).toLower();
}
// fall through
-// Android should not fall through to the Unix code
-#elif defined(Q_OS_ANDROID)
- return QJNIObjectPrivate::getStaticObjectField("android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString();
#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
QUnixOSVersion unixOsVersion;
findUnixOsVersion(unixOsVersion);
@@ -2767,44 +2740,23 @@ QString QSysInfo::productVersion()
*/
QString QSysInfo::prettyProductName()
{
-#if defined(Q_OS_IOS)
- return QLatin1String("iOS ") + productVersion();
-#elif defined(Q_OS_TVOS)
- return QLatin1String("tvOS ") + productVersion();
-#elif defined(Q_OS_WATCHOS)
- return QLatin1String("watchOS ") + productVersion();
-#elif defined(Q_OS_MACOS)
- const QAppleOperatingSystemVersion version = qt_apple_os_version();
- const char *name = osxVer_helper(version);
- if (name) {
- return (version.major == 10 && version.minor < 12
- ? QLatin1String("OS X ")
- : QLatin1String("macOS "))
- + QLatin1String(name)
- + QLatin1String(" (") + QString::number(version.major)
- + QLatin1Char('.') + QString::number(version.minor)
- + QLatin1Char(')');
- } else {
- return QLatin1String("macOS ")
- + QString::number(version.major) + QLatin1Char('.')
- + QString::number(version.minor);
- }
-#elif defined(Q_OS_WINPHONE)
- return QLatin1String("Windows Phone ") + QLatin1String(winVer_helper());
-#elif defined(Q_OS_WIN)
- const char *name = winVer_helper();
- const OSVERSIONINFOEX osver = winOsVersion();
+#if defined(Q_OS_WINPHONE)
+ return QLatin1String("Windows Phone ") + QLatin1String(osVer_helper());
+#elif defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
+ const auto version = QOperatingSystemVersion::current();
+ const char *name = osVer_helper(version);
if (name)
- return QLatin1String("Windows ") + QLatin1String(name) + winSp_helper()
- + QLatin1String(" (") + QString::number(osver.dwMajorVersion)
- + QLatin1Char('.') + QString::number(osver.dwMinorVersion)
+ return version.name() + QLatin1Char(' ') + QLatin1String(name)
+# if defined(Q_OS_WIN)
+ + winSp_helper()
+# endif
+ + QLatin1String(" (") + QString::number(version.majorVersion())
+ + QLatin1Char('.') + QString::number(version.minorVersion())
+ QLatin1Char(')');
- else
- return QLatin1String("Windows ")
- + QString::number(osver.dwMajorVersion) + QLatin1Char('.')
- + QString::number(osver.dwMinorVersion);
-#elif defined(Q_OS_ANDROID)
- return QLatin1String("Android ") + productVersion();
+ else
+ return version.name() + QLatin1Char(' ')
+ + QString::number(version.majorVersion()) + QLatin1Char('.')
+ + QString::number(version.minorVersion());
#elif defined(Q_OS_HAIKU)
return QLatin1String("Haiku ") + productVersion();
#elif defined(Q_OS_UNIX)
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 1737f58c87..4354c85bfe 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -44,6 +44,8 @@
#ifdef __cplusplus
# include <type_traits>
# include <cstddef>
+# include <type_traits>
+# include <utility>
#endif
#include <stddef.h>
@@ -917,17 +919,34 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic
#ifndef QT_NO_FOREACH
+namespace QtPrivate {
+
template <typename T>
class QForeachContainer {
QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE;
public:
QForeachContainer(const T &t) : c(t) {}
QForeachContainer(T &&t) : c(std::move(t)) {}
+ QForeachContainer(const QForeachContainer &other)
+ : c(other.c),
+ i(c.begin()),
+ e(c.end()),
+ control(other.control)
+ {
+ }
+
const T c;
typename T::const_iterator i = c.begin(), e = c.end();
int control = 1;
};
+template<typename T>
+QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t)
+{
+ return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t));
+}
+
+}
// Explanation of the control word:
// - it's initialized to 1
// - that means both the inner and outer loops start
@@ -938,7 +957,7 @@ public:
// - if there was a break inside the inner loop, it will exit with control still
// set to 1; in that case, the outer loop will invert it to 0 and will exit too
#define Q_FOREACH(variable, container) \
-for (QForeachContainer<typename std::remove_reference<decltype(container)>::type> _container_((container)); \
+for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
_container_.control && _container_.i != _container_.e; \
++_container_.i, _container_.control ^= 1) \
for (variable = *_container_.i; _container_.control; _container_.control = 0)
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index a30344995e..873a36f4a6 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -505,6 +505,7 @@ public:
AA_SynthesizeMouseForUnhandledTabletEvents = 24,
AA_CompressHighFrequencyEvents = 25,
AA_DontCheckOpenGLContextThreadAffinity = 26,
+ AA_DisableShaderDiskCache = 27,
// Add new attributes before this line
AA_AttributeCount
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 250195a512..64f0b5e1da 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -257,6 +257,15 @@
\l{QOpenGLContext::makeCurrent}{makeCurrent()}. This value has been
added in Qt 5.8.
+ \value AA_DisableShaderDiskCache Disables caching of shader program binaries
+ on disk. By default Qt Quick, QPainter's OpenGL backend, and any
+ application using QOpenGLShaderProgram with one of its
+ \e addCacheableShaderFromSource overloads will employ a disk-based
+ \l{Caching Program Binaries}{program binary cache} in either the shared
+ or per-process cache storage location, on systems that support
+ \e glProgramBinary(). In the unlikely event of this being problematic,
+ set this attribute to disable all disk-based caching of shaders.
+
The following values are obsolete:
\value AA_ImmediateWidgetCreation This attribute is no longer fully
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
new file mode 100644
index 0000000000..fb1ada905c
--- /dev/null
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -0,0 +1,439 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qoperatingsystemversion.h"
+#if !defined(Q_OS_DARWIN) && !defined(Q_OS_WIN)
+#include "qoperatingsystemversion_p.h"
+#endif
+
+#include <qversionnumber.h>
+
+#if defined(Q_OS_ANDROID)
+#include <private/qjni_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOperatingSystemVersion
+ \inmodule QtCore
+ \since 5.9
+ \brief The QOperatingSystemVersion class provides information about the operating system version.
+
+ Unlike other version functions in QSysInfo, QOperatingSystemVersion provides access to the full
+ version number that \a developers typically use to vary behavior or determine whether to enable
+ APIs or features based on the operating system version (as opposed to the kernel version number
+ or marketing version).
+
+ This class is also a complete replacement for QSysInfo::macVersion and QSysInfo::windowsVersion,
+ additionally providing access to the third (micro) version number component.
+
+ Presently, Android, Apple Platforms (iOS, macOS, tvOS, and watchOS), and Windows are supported.
+
+ The \a majorVersion(), \a minorVersion(), and \a microVersion() functions return the parts of
+ the operating system version number based on:
+
+ \table
+ \header \li Platforms \li Value
+ \row \li Android \li result of parsing
+ \l{https://developer.android.com/reference/android/os/Build.VERSION.html#RELEASE}{android.os.Build.VERSION.RELEASE}
+ using QVersionNumber, with a fallback to
+ \l{https://developer.android.com/reference/android/os/Build.VERSION.html#SDK_INT}{android.os.Build.VERSION.SDK_INT}
+ to determine the major and minor version component if the former fails
+ \row \li Apple Platforms \li majorVersion, minorVersion, and patchVersion from
+ \l{https://developer.apple.com/reference/foundation/nsprocessinfo/1410906-operatingsystemversion?language=objc}{NSProcessInfo.operatingSystemVersion}
+ \row \li Windows \li dwMajorVersion, dwMinorVersion, and dwBuildNumber from
+ \l{https://msdn.microsoft.com/en-us/library/mt723418.aspx}{RtlGetVersion} -
+ note that this function ALWAYS return the version number of the underlying operating system,
+ as opposed to the shim underneath GetVersionEx that hides the real version number
+ if the application is not manifested for that version of the OS
+ \endtable
+*/
+
+/*!
+ \enum QOperatingSystemVersion::OSType
+
+ This enum provides symbolic names for the various operating
+ system families supported by QOperatingSystemVersion.
+
+ \value Android The Google Android operating system.
+ \value IOS The Apple iOS operating system.
+ \value MacOS The Apple macOS operating system.
+ \value TvOS The Apple tvOS operating system.
+ \value WatchOS The Apple watchOS operating system.
+ \value Windows The Microsoft Windows operating system (in both Win32 and WinRT environments).
+
+ \value Unknown An unknown or unsupported operating system.
+*/
+
+/*!
+ \fn QOperatingSystemVersion::QOperatingSystemVersion(int maj, int min, int mic)
+
+ Constructs a QOperatingSystemVersion consisting of the OS type \a os, and
+ major, minor, and micro version numbers \a maj, \a min and \a mic, respectively.
+*/
+
+/*!
+ \fn QOperatingSystemVersion QOperatingSystemVersion::current()
+
+ Returns a QOperatingSystemVersion indicating the current OS and its version number.
+*/
+#if !defined(Q_OS_DARWIN) && !defined(Q_OS_WIN)
+QOperatingSystemVersion QOperatingSystemVersion::current()
+{
+ QOperatingSystemVersion version;
+ version.m_os = currentType();
+#if defined(Q_OS_ANDROID)
+#ifndef QT_BOOTSTRAPPED
+ const QVersionNumber v = QVersionNumber::fromString(QJNIObjectPrivate::getStaticObjectField(
+ "android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString());
+ if (!v.isNull()) {
+ version.m_major = v.majorVersion();
+ version.m_minor = v.minorVersion();
+ version.m_micro = v.microVersion();
+ return version;
+ }
+#endif
+
+ version.m_major = -1;
+ version.m_minor = -1;
+
+ static const int versions[][2] = {
+ { 1, 0 }, // API level 1
+ { 1, 1 }, // API level 2
+ { 1, 5 }, // API level 3
+ { 1, 6 }, // API level 4
+ { 2, 0 }, // API level 5
+ { 2, 0 }, // API level 6
+ { 2, 1 }, // API level 7
+ { 2, 2 }, // API level 8
+ { 2, 3 }, // API level 9
+ { 2, 3 }, // API level 10
+ { 3, 0 }, // API level 11
+ { 3, 1 }, // API level 12
+ { 3, 2 }, // API level 13
+ { 4, 0 }, // API level 14
+ { 4, 0 }, // API level 15
+ { 4, 1 }, // API level 16
+ { 4, 2 }, // API level 17
+ { 4, 3 }, // API level 18
+ { 4, 4 }, // API level 19
+ { 4, 4 }, // API level 20
+ { 5, 0 }, // API level 21
+ { 5, 1 }, // API level 22
+ { 6, 0 }, // API level 23
+ { 7, 0 }, // API level 24
+ { 7, 1 }, // API level 25
+ };
+
+ // This will give us at least the first 2 version components
+ const size_t versionIdx = size_t(QJNIObjectPrivate::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT")) - 1;
+ if (versionIdx < sizeof(versions) / sizeof(versions[0])) {
+ version.m_major = versions[versionIdx][0];
+ version.m_minor = versions[versionIdx][1];
+ }
+
+ // API level 6 was exactly version 2.0.1
+ version.m_micro = versionIdx == 5 ? 1 : -1;
+#else
+ version.m_major = -1;
+ version.m_minor = -1;
+ version.m_micro = -1;
+#endif
+ return version;
+}
+#endif
+
+static inline int compareVersionComponents(int lhs, int rhs)
+{
+ return lhs >= 0 && rhs >= 0 ? lhs - rhs : 0;
+}
+
+/*!
+ \fn int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1,
+ const QOperatingSystemVersion &v2)
+
+ Compares \a v1 with \a v2 and returns an integer less than, equal to, or
+ greater than zero, depending on whether \a v1 is less than, equal to, or
+ greater than \a v2, respectively.
+
+ Comparisons are performed by comparing the version number components of
+ \a v1 and \a v2.
+
+ \note This function cannot take the OS type into account; you should use
+ the overloaded comparison operators to compare QOperatingSystemVersions
+ in a safe manner.
+*/
+int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1, const QOperatingSystemVersion &v2)
+{
+ if (v1.m_major == v2.m_major) {
+ if (v1.m_minor == v2.m_minor) {
+ return compareVersionComponents(v1.m_micro, v2.m_micro);
+ }
+ return compareVersionComponents(v1.m_minor, v2.m_minor);
+ }
+ return compareVersionComponents(v1.m_major, v2.m_major);
+}
+
+#ifndef QT_BOOTSTRAPPED
+/*!
+ \fn QOperatingSystemVersion QOperatingSystemVersion::fromVersionNumber(const QVersionNumber &version,
+ QOperatingSystemVersion::OSType os)
+
+ Returns a QOperatingSystemVersion consisting of the OS type \a os and version number \a version.
+*/
+QOperatingSystemVersion QOperatingSystemVersion::fromVersionNumber(const QVersionNumber &version,
+ QOperatingSystemVersion::OSType os)
+{
+ return QOperatingSystemVersion(os, version.majorVersion(), version.minorVersion(), version.microVersion());
+}
+
+/*!
+ \fn QOperatingSystemVersion QOperatingSystemVersion::toVersionNumber() const
+
+ Returns the QOperatingSystemVersion's version number as a QVersionNumber.
+*/
+QVersionNumber QOperatingSystemVersion::toVersionNumber() const
+{
+ return QVersionNumber(m_major, m_minor, m_micro);
+}
+#endif
+
+/*!
+ \fn int QOperatingSystemVersion::majorVersion() const
+
+ Returns the major version number, that is, the first segment of the operating system's version number.
+
+ See the main class documentation for what the major version number is on a given operating system.
+
+ -1 indicates an unknown or absent version number component.
+
+ \sa minorVersion(), microVersion()
+*/
+
+/*!
+ \fn int QOperatingSystemVersion::minorVersion() const
+
+ Returns the minor version number, that is, the second segment of the operating system's version number.
+
+ See the main class documentation for what the minor version number is on a given operating system.
+
+ -1 indicates an unknown or absent version number component.
+
+ \sa majorVersion(), macro()
+*/
+
+/*!
+ \fn int QOperatingSystemVersion::microVersion() const
+
+ Returns the micro version number, that is, the third segment of the operating system's version number.
+
+ See the main class documentation for what the micro version number is on a given operating system.
+
+ -1 indicates an unknown or absent version number component.
+
+ \sa majorVersion(), minorVersion()
+*/
+
+/*!
+ \fn QOperatingSystemVersion::OSType QOperatingSystemVersion::type() const
+
+ Returns the OS type identified by the QOperatingSystemVersion.
+
+ \sa typeName()
+*/
+
+/*!
+ \fn QString QOperatingSystemVersion::name() const
+
+ Returns a string representation of the OS type identified by the QOperatingSystemVersion.
+
+ \sa type()
+*/
+QString QOperatingSystemVersion::name() const
+{
+ switch (type()) {
+ case QOperatingSystemVersion::Windows:
+ return QStringLiteral("Windows");
+ case QOperatingSystemVersion::MacOS: {
+ if (majorVersion() < 10)
+ return QStringLiteral("Mac OS");
+ if (majorVersion() == 10 && minorVersion() < 8)
+ return QStringLiteral("Mac OS X");
+ if (majorVersion() == 10 && minorVersion() < 12)
+ return QStringLiteral("OS X");
+ return QStringLiteral("macOS");
+ }
+ case QOperatingSystemVersion::IOS: {
+ if (majorVersion() < 4)
+ return QStringLiteral("iPhone OS");
+ return QStringLiteral("iOS");
+ }
+ case QOperatingSystemVersion::TvOS:
+ return QStringLiteral("tvOS");
+ case QOperatingSystemVersion::WatchOS:
+ return QStringLiteral("watchOS");
+ case QOperatingSystemVersion::Android:
+ return QStringLiteral("Android");
+ case QOperatingSystemVersion::Unknown:
+ default:
+ return QString();
+ }
+}
+
+/*!
+ \variable QOperatingSystemVersion::Windows7
+ \brief a version corresponding to Windows 7 (version 6.1).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::Windows7 = QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 1);
+
+/*!
+ \variable QOperatingSystemVersion::Windows8
+ \brief a version corresponding to Windows 8 (version 6.2).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::Windows8 = QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 2);
+
+/*!
+ \variable QOperatingSystemVersion::Windows8_1
+ \brief a version corresponding to Windows 8.1 (version 6.3).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::Windows8_1 = QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 3);
+
+/*!
+ \variable QOperatingSystemVersion::Windows10
+ \brief a version corresponding to Windows 10 (version 10.0).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::Windows10 = QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10);
+
+/*!
+ \variable QOperatingSystemVersion::OSXMavericks
+ \brief a version corresponding to OS X Mavericks (version 10.9).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::OSXMavericks = QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 9);
+
+/*!
+ \variable QOperatingSystemVersion::OSXYosemite
+ \brief a version corresponding to OS X Yosemite (version 10.10).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::OSXYosemite = QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 10);
+
+/*!
+ \variable QOperatingSystemVersion::OSXElCapitan
+ \brief a version corresponding to OS X El Capitan (version 10.11).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::OSXElCapitan = QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 11);
+
+/*!
+ \variable QOperatingSystemVersion::MacOSSierra
+ \brief a version corresponding to macOS Sierra (version 10.12).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::MacOSSierra = QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 12);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidJellyBean
+ \brief a version corresponding to Android Jelly Bean (version 4.1, API level 16).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidJellyBean = QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 1);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidJellyBean_MR1
+ \brief a version corresponding to Android Jelly Bean, maintenance release 1 (version 4.2, API level 17).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidJellyBean_MR1 = QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 2);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidJellyBean_MR2
+ \brief a version corresponding to Android Jelly Bean, maintenance release 2 (version 4.3, API level 18).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidJellyBean_MR2 = QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 3);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidKitKat
+ \brief a version corresponding to Android KitKat (versions 4.4 & 4.4W, API levels 19 & 20).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidKitKat = QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 4);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidLollipop
+ \brief a version corresponding to Android Lollipop (version 5.0, API level 21).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidLollipop = QOperatingSystemVersion(QOperatingSystemVersion::Android, 5, 0);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidLollipop_MR1
+ \brief a version corresponding to Android Lollipop, maintenance release 1 (version 5.1, API level 22).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidLollipop_MR1 = QOperatingSystemVersion(QOperatingSystemVersion::Android, 5, 1);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidMarshmallow
+ \brief a version corresponding to Android Marshmallow (version 6.0, API level 23).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidMarshmallow = QOperatingSystemVersion(QOperatingSystemVersion::Android, 6, 0);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidNougat
+ \brief a version corresponding to Android Nougat (version 7.0, API level 24).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidNougat = QOperatingSystemVersion(QOperatingSystemVersion::Android, 7, 0);
+
+/*!
+ \variable QOperatingSystemVersion::AndroidNougat_MR1
+ \brief a version corresponding to Android Nougat, maintenance release 1 (version 7.0, API level 25).
+ \since 5.9
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::AndroidNougat_MR1 = QOperatingSystemVersion(QOperatingSystemVersion::Android, 7, 1);
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
new file mode 100644
index 0000000000..ef999c6ae4
--- /dev/null
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+
+#ifndef QOPERATINGSYSTEMVERSION_H
+#define QOPERATINGSYSTEMVERSION_H
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QVersionNumber;
+
+class Q_CORE_EXPORT QOperatingSystemVersion
+{
+public:
+ enum OSType {
+ Unknown = 0,
+ Windows,
+ MacOS,
+ IOS,
+ TvOS,
+ WatchOS,
+ Android
+ };
+
+ static const QOperatingSystemVersion Windows7;
+ static const QOperatingSystemVersion Windows8;
+ static const QOperatingSystemVersion Windows8_1;
+ static const QOperatingSystemVersion Windows10;
+
+ static const QOperatingSystemVersion OSXMavericks;
+ static const QOperatingSystemVersion OSXYosemite;
+ static const QOperatingSystemVersion OSXElCapitan;
+ static const QOperatingSystemVersion MacOSSierra;
+
+ static const QOperatingSystemVersion AndroidJellyBean;
+ static const QOperatingSystemVersion AndroidJellyBean_MR1;
+ static const QOperatingSystemVersion AndroidJellyBean_MR2;
+ static const QOperatingSystemVersion AndroidKitKat;
+ static const QOperatingSystemVersion AndroidLollipop;
+ static const QOperatingSystemVersion AndroidLollipop_MR1;
+ static const QOperatingSystemVersion AndroidMarshmallow;
+ static const QOperatingSystemVersion AndroidNougat;
+ static const QOperatingSystemVersion AndroidNougat_MR1;
+
+ QOperatingSystemVersion(const QOperatingSystemVersion &other) = default;
+ Q_DECL_CONSTEXPR QOperatingSystemVersion(OSType osType, int vmajor, int vminor = -1, int vmicro = -1)
+ : m_os(osType), m_major(vmajor), m_minor(vminor), m_micro(vmicro) { }
+
+ static QOperatingSystemVersion current();
+
+ static int compare(const QOperatingSystemVersion &v1, const QOperatingSystemVersion &v2);
+
+ QOperatingSystemVersion fromVersionNumber(const QVersionNumber &version, OSType os);
+ QVersionNumber toVersionNumber() const;
+
+ Q_DECL_CONSTEXPR int majorVersion() const { return m_major; }
+ Q_DECL_CONSTEXPR int minorVersion() const { return m_minor; }
+ Q_DECL_CONSTEXPR int microVersion() const { return m_micro; }
+
+ Q_DECL_CONSTEXPR OSType type() const { return m_os; }
+ QString name() const;
+
+private:
+ QOperatingSystemVersion() = default;
+ OSType m_os;
+ int m_major;
+ int m_minor;
+ int m_micro;
+};
+
+inline bool operator>(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
+{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) > 0; }
+
+inline bool operator>=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
+{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) >= 0; }
+
+inline bool operator<(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
+{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) < 0; }
+
+inline bool operator<=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
+{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) <= 0; }
+
+inline bool operator==(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
+{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) == 0; }
+
+inline bool operator!=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
+{ return !(lhs == rhs); }
+
+QT_END_NAMESPACE
+
+#endif // QOPERATINGSYSTEMVERSION_H
diff --git a/src/corelib/global/qoperatingsystemversion_darwin.mm b/src/corelib/global/qoperatingsystemversion_darwin.mm
new file mode 100644
index 0000000000..3dd007cbb3
--- /dev/null
+++ b/src/corelib/global/qoperatingsystemversion_darwin.mm
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qoperatingsystemversion_p.h"
+#import <Foundation/Foundation.h>
+
+#ifdef Q_OS_IOS
+#import <UIKit/UIKit.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+typedef qint16 (*GestaltFunction)(quint32 selector, qint32 *response);
+
+QOperatingSystemVersion QOperatingSystemVersion::current()
+{
+ QOperatingSystemVersion v;
+ v.m_os = currentType();
+ v.m_major = -1;
+ v.m_minor = -1;
+ v.m_micro = -1;
+#if QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_8_0) || defined(Q_OS_TVOS) || defined(Q_OS_WATCHOS)
+ if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) {
+ NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion;
+ v.m_major = osv.majorVersion;
+ v.m_minor = osv.minorVersion;
+ v.m_micro = osv.patchVersion;
+ return v;
+ }
+#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 QT_MACOS_IOS_DEPLOYMENT_TARGET_BELOW(__MAC_10_10, __IPHONE_8_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_MACOS)
+ 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
+#endif
+ v.m_major = major;
+ v.m_minor = minor;
+ v.m_micro = patch;
+ return v;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qoperatingsystemversion_p.h b/src/corelib/global/qoperatingsystemversion_p.h
new file mode 100644
index 0000000000..78d0daf0c6
--- /dev/null
+++ b/src/corelib/global/qoperatingsystemversion_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPERATINGSYSTEMVERSION_P_H
+#define QOPERATINGSYSTEMVERSION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qoperatingsystemversion.h"
+
+#ifdef Q_OS_WIN
+#include <qt_windows.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN
+OSVERSIONINFOEX qWindowsVersionInfo();
+#endif
+
+static inline QOperatingSystemVersion::OSType currentType()
+{
+#if defined(Q_OS_WIN)
+ return QOperatingSystemVersion::Windows;
+#elif defined(Q_OS_MACOS)
+ return QOperatingSystemVersion::MacOS;
+#elif defined(Q_OS_IOS)
+ return QOperatingSystemVersion::IOS;
+#elif defined(Q_OS_TVOS)
+ return QOperatingSystemVersion::TvOS;
+#elif defined(Q_OS_WATCHOS)
+ return QOperatingSystemVersion::WatchOS;
+#elif defined(Q_OS_ANDROID)
+ return QOperatingSystemVersion::Android;
+#else
+ return QOperatingSystemVersion::Unknown;
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif // QOPERATINGSYSTEMVERSION_P_H
diff --git a/src/corelib/global/qoperatingsystemversion_win.cpp b/src/corelib/global/qoperatingsystemversion_win.cpp
new file mode 100644
index 0000000000..060ca2f7da
--- /dev/null
+++ b/src/corelib/global/qoperatingsystemversion_win.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qoperatingsystemversion_p.h"
+#include <qt_windows.h>
+#include <qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WINRT
+static inline HMODULE moduleHandleForFunction(LPCVOID address)
+{
+ // This is a widely used, decades-old technique for retrieving the handle
+ // of a module and is effectively equivalent to GetModuleHandleEx
+ // (which is unavailable on WinRT)
+ MEMORY_BASIC_INFORMATION mbi = { 0, 0, 0, 0, 0, 0, 0 };
+ if (VirtualQuery(address, &mbi, sizeof(mbi)) == 0)
+ return 0;
+ return reinterpret_cast<HMODULE>(mbi.AllocationBase);
+}
+#endif
+
+static inline OSVERSIONINFOEX determineWinOsVersion()
+{
+ OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0};
+
+#define GetProcAddressA GetProcAddress
+
+ // GetModuleHandle is not supported in WinRT and linking to it at load time
+ // will not pass the Windows App Certification Kit... but it exists and is functional,
+ // so use some unusual but widely used techniques to get a pointer to it
+#ifdef Q_OS_WINRT
+ // 1. Get HMODULE of kernel32.dll, using the address of some function exported by that DLL
+ HMODULE kernelModule = moduleHandleForFunction(reinterpret_cast<LPCVOID>(VirtualQuery));
+ if (Q_UNLIKELY(!kernelModule))
+ return result;
+
+ // 2. Get pointer to GetModuleHandle so we can then load other arbitrary modules (DLLs)
+ typedef HMODULE(WINAPI *GetModuleHandleFunction)(LPCWSTR);
+ GetModuleHandleFunction pGetModuleHandle = reinterpret_cast<GetModuleHandleFunction>(
+ GetProcAddressA(kernelModule, "GetModuleHandleW"));
+ if (Q_UNLIKELY(!pGetModuleHandle))
+ return result;
+#else
+#define pGetModuleHandle GetModuleHandleW
+#endif
+
+#ifndef Q_OS_WINCE
+ HMODULE ntdll = pGetModuleHandle(L"ntdll.dll");
+ if (Q_UNLIKELY(!ntdll))
+ return result;
+
+ // NTSTATUS is not defined on WinRT
+ typedef LONG NTSTATUS;
+ typedef NTSTATUS (NTAPI *RtlGetVersionFunction)(LPOSVERSIONINFO);
+
+ // RtlGetVersion is documented public API but we must load it dynamically
+ // because linking to it at load time will not pass the Windows App Certification Kit
+ // https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910.aspx
+ RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
+ GetProcAddressA(ntdll, "RtlGetVersion"));
+ if (Q_UNLIKELY(!pRtlGetVersion))
+ return result;
+
+ // GetVersionEx() has been deprecated in Windows 8.1 and will return
+ // only Windows 8 from that version on, so use the kernel API function.
+ pRtlGetVersion((LPOSVERSIONINFO) &result); // always returns STATUS_SUCCESS
+#else // !Q_OS_WINCE
+ GetVersionEx(&result);
+#endif
+ return result;
+}
+
+OSVERSIONINFOEX qWindowsVersionInfo()
+{
+ OSVERSIONINFOEX realResult = determineWinOsVersion();
+#ifdef QT_DEBUG
+ {
+ if (Q_UNLIKELY(qEnvironmentVariableIsSet("QT_WINVER_OVERRIDE"))) {
+ OSVERSIONINFOEX result = realResult;
+ result.dwMajorVersion = 0;
+ result.dwMinorVersion = 0;
+
+ // Erase any build number and service pack information
+ result.dwBuildNumber = 0;
+ result.szCSDVersion[0] = L'\0';
+ result.wServicePackMajor = 0;
+ result.wServicePackMinor = 0;
+
+ const QByteArray winVerOverride = qgetenv("QT_WINVER_OVERRIDE");
+ if (winVerOverride == "WINDOWS7" || winVerOverride == "2008_R2") {
+ result.dwMajorVersion = 6;
+ result.dwMinorVersion = 1;
+ } else if (winVerOverride == "WINDOWS8" || winVerOverride == "2012") {
+ result.dwMajorVersion = 6;
+ result.dwMinorVersion = 2;
+ } else if (winVerOverride == "WINDOWS8_1" || winVerOverride == "2012_R2") {
+ result.dwMajorVersion = 6;
+ result.dwMinorVersion = 3;
+ } else if (winVerOverride == "WINDOWS10" || winVerOverride == "2016") {
+ result.dwMajorVersion = 10;
+ } else {
+ return realResult;
+ }
+
+ if (winVerOverride == "2008_R2"
+ || winVerOverride == "2012"
+ || winVerOverride == "2012_R2"
+ || winVerOverride == "2016") {
+ // If the current host OS is a domain controller and the override OS
+ // is also a server type OS, preserve that information
+ if (result.wProductType == VER_NT_WORKSTATION)
+ result.wProductType = VER_NT_SERVER;
+ } else {
+ // Any other OS must be a workstation OS type
+ result.wProductType = VER_NT_WORKSTATION;
+ }
+ }
+ }
+#endif
+ return realResult;
+}
+
+QOperatingSystemVersion QOperatingSystemVersion::current()
+{
+ QOperatingSystemVersion v;
+ v.m_os = currentType();
+ const OSVERSIONINFOEX osv = qWindowsVersionInfo();
+ v.m_major = osv.dwMajorVersion;
+ v.m_minor = osv.dwMinorVersion;
+ v.m_micro = osv.dwBuildNumber;
+ return v;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h
index 23f412aa6a..3cbcfd3fc9 100644
--- a/src/corelib/global/qsysinfo.h
+++ b/src/corelib/global/qsysinfo.h
@@ -49,6 +49,23 @@ QT_BEGIN_NAMESPACE
System information
*/
+/*
+ * GCC (5-7) has a regression that causes it to emit wrong deprecated warnings:
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77849
+ *
+ * Try to work around it by defining our own macro.
+ */
+
+#ifdef QT_SYSINFO_DEPRECATED_X
+#error "QT_SYSINFO_DEPRECATED_X already defined"
+#endif
+
+#ifdef Q_CC_GNU
+#define QT_SYSINFO_DEPRECATED_X(x)
+#else
+#define QT_SYSINFO_DEPRECATED_X(x) QT_DEPRECATED_X(x)
+#endif
+
class QString;
class Q_CORE_EXPORT QSysInfo {
public:
@@ -79,7 +96,8 @@ public:
# endif
};
#endif
- enum WinVersion {
+#if QT_DEPRECATED_SINCE(5, 9)
+ enum QT_DEPRECATED_X("Use QOperatingSystemVersion") WinVersion {
WV_None = 0x0000,
WV_32s = 0x0001,
@@ -117,19 +135,25 @@ public:
WV_CE_6 = 0x0400,
WV_CE_based = 0x0f00
};
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations")
+QT_WARNING_DISABLE_CLANG("-Wdeprecated-declarations")
+QT_WARNING_DISABLE_INTEL(1478)
+QT_WARNING_DISABLE_MSVC(4996)
#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
- static const WinVersion WindowsVersion;
- static WinVersion windowsVersion();
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const WinVersion WindowsVersion;
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static WinVersion windowsVersion();
#else
- static const WinVersion WindowsVersion = WV_None;
- static WinVersion windowsVersion() { return WV_None; }
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const WinVersion WindowsVersion = WV_None;
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static WinVersion windowsVersion() { return WV_None; }
#endif
+QT_WARNING_POP
#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_TVOS(major, minor) (QSysInfo::MV_TVOS | major << 4 | minor)
#define Q_MV_WATCHOS(major, minor) (QSysInfo::MV_WATCHOS | major << 4 | minor)
- enum MacVersion {
+ enum QT_DEPRECATED_X("Use QOperatingSystemVersion") MacVersion {
MV_None = 0xffff,
MV_Unknown = 0x0000,
@@ -198,13 +222,20 @@ public:
MV_WATCHOS_2_2 = Q_MV_WATCHOS(2, 2),
MV_WATCHOS_3_0 = Q_MV_WATCHOS(3, 0)
};
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations")
+QT_WARNING_DISABLE_CLANG("-Wdeprecated-declarations")
+QT_WARNING_DISABLE_INTEL(1478)
+QT_WARNING_DISABLE_MSVC(4996)
#if defined(Q_OS_MAC)
- static const MacVersion MacintoshVersion;
- static MacVersion macVersion();
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const MacVersion MacintoshVersion;
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static MacVersion macVersion();
#else
- static const MacVersion MacintoshVersion = MV_None;
- static MacVersion macVersion() { return MV_None; }
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const MacVersion MacintoshVersion = MV_None;
+ QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static MacVersion macVersion() { return MV_None; }
#endif
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(5, 9)
static QString buildCpuArchitecture();
static QString currentCpuArchitecture();
@@ -219,5 +250,7 @@ public:
static QString machineHostName();
};
+#undef QT_SYSINFO_DEPRECATED_X
+
QT_END_NAMESPACE
#endif // QSYSINFO_H