mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 21:20:19 +00:00
5a4485b63b
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
621 lines
18 KiB
C++
621 lines
18 KiB
C++
// SPDX-License-Identifier: LGPL-2.1+
|
|
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
|
** Copyright (C) 2014 Intel Corporation
|
|
** Contact: http://www.qt-project.org/legal
|
|
**
|
|
** 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 Digia. For licensing terms and
|
|
** conditions see http://qt.digia.com/licensing. For further information
|
|
** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
** packaging of this file. Please review the following information to
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
**
|
|
** In addition, as a special exception, Digia gives you certain additional
|
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3.0 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
|
** packaging of this file. Please review the following information to
|
|
** ensure the GNU General Public License version 3.0 requirements will be
|
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include "subsurfacesysinfo.h"
|
|
#include <QString>
|
|
|
|
#ifdef Q_OS_UNIX
|
|
#include <sys/utsname.h>
|
|
#endif
|
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
|
|
|
|
#ifndef QStringLiteral
|
|
# define QStringLiteral QString::fromUtf8
|
|
#endif
|
|
|
|
#ifdef Q_OS_UNIX
|
|
#include <qplatformdefs.h>
|
|
#endif
|
|
|
|
#ifdef __APPLE__
|
|
#include <CoreServices/CoreServices.h>
|
|
#endif
|
|
|
|
// --- this is a copy of Qt 5.4's src/corelib/global/archdetect.cpp ---
|
|
|
|
// main part: processor type
|
|
#if defined(Q_PROCESSOR_ALPHA)
|
|
# define ARCH_PROCESSOR "alpha"
|
|
#elif defined(Q_PROCESSOR_ARM)
|
|
# define ARCH_PROCESSOR "arm"
|
|
#elif defined(Q_PROCESSOR_AVR32)
|
|
# define ARCH_PROCESSOR "avr32"
|
|
#elif defined(Q_PROCESSOR_BLACKFIN)
|
|
# define ARCH_PROCESSOR "bfin"
|
|
#elif defined(Q_PROCESSOR_X86_32)
|
|
# define ARCH_PROCESSOR "i386"
|
|
#elif defined(Q_PROCESSOR_X86_64)
|
|
# define ARCH_PROCESSOR "x86_64"
|
|
#elif defined(Q_PROCESSOR_IA64)
|
|
# define ARCH_PROCESSOR "ia64"
|
|
#elif defined(Q_PROCESSOR_MIPS)
|
|
# define ARCH_PROCESSOR "mips"
|
|
#elif defined(Q_PROCESSOR_POWER)
|
|
# define ARCH_PROCESSOR "power"
|
|
#elif defined(Q_PROCESSOR_S390)
|
|
# define ARCH_PROCESSOR "s390"
|
|
#elif defined(Q_PROCESSOR_SH)
|
|
# define ARCH_PROCESSOR "sh"
|
|
#elif defined(Q_PROCESSOR_SPARC)
|
|
# define ARCH_PROCESSOR "sparc"
|
|
#else
|
|
# define ARCH_PROCESSOR "unknown"
|
|
#endif
|
|
|
|
// endinanness
|
|
#if defined(Q_LITTLE_ENDIAN)
|
|
# define ARCH_ENDIANNESS "little_endian"
|
|
#elif defined(Q_BIG_ENDIAN)
|
|
# define ARCH_ENDIANNESS "big_endian"
|
|
#endif
|
|
|
|
// pointer type
|
|
#if defined(Q_OS_WIN64) || (defined(Q_OS_WINRT) && defined(_M_X64))
|
|
# define ARCH_POINTER "llp64"
|
|
#elif defined(__LP64__) || QT_POINTER_SIZE - 0 == 8
|
|
# define ARCH_POINTER "lp64"
|
|
#else
|
|
# define ARCH_POINTER "ilp32"
|
|
#endif
|
|
|
|
// secondary: ABI string (includes the dash)
|
|
#if defined(__ARM_EABI__) || defined(__mips_eabi)
|
|
# define ARCH_ABI1 "-eabi"
|
|
#elif defined(_MIPS_SIM)
|
|
# if _MIPS_SIM == _ABIO32
|
|
# define ARCH_ABI1 "-o32"
|
|
# elif _MIPS_SIM == _ABIN32
|
|
# define ARCH_ABI1 "-n32"
|
|
# elif _MIPS_SIM == _ABI64
|
|
# define ARCH_ABI1 "-n64"
|
|
# elif _MIPS_SIM == _ABIO64
|
|
# define ARCH_ABI1 "-o64"
|
|
# endif
|
|
#else
|
|
# define ARCH_ABI1 ""
|
|
#endif
|
|
#if defined(__ARM_PCS_VFP) || defined(__mips_hard_float)
|
|
# define ARCH_ABI2 "-hardfloat"
|
|
#else
|
|
# define ARCH_ABI2 ""
|
|
#endif
|
|
|
|
#define ARCH_ABI ARCH_ABI1 ARCH_ABI2
|
|
|
|
#define ARCH_FULL ARCH_PROCESSOR "-" ARCH_ENDIANNESS "-" ARCH_POINTER ARCH_ABI
|
|
|
|
// --- end of archdetect.cpp ---
|
|
// copied from Qt 5.4.1's src/corelib/global/qglobal.cpp
|
|
|
|
#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
|
|
|
|
QT_BEGIN_INCLUDE_NAMESPACE
|
|
#include "qt_windows.h"
|
|
QT_END_INCLUDE_NAMESPACE
|
|
|
|
#ifndef Q_OS_WINRT
|
|
# ifndef Q_OS_WINCE
|
|
// Fallback for determining Windows versions >= 8 by looping using the
|
|
// version check macros. Note that it will return build number=0 to avoid
|
|
// inefficient looping.
|
|
static inline void determineWinOsVersionFallbackPost8(OSVERSIONINFO *result)
|
|
{
|
|
result->dwBuildNumber = 0;
|
|
DWORDLONG conditionMask = 0;
|
|
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
|
VER_SET_CONDITION(conditionMask, VER_PLATFORMID, VER_EQUAL);
|
|
OSVERSIONINFOEX checkVersion = { sizeof(OSVERSIONINFOEX), result->dwMajorVersion, 0,
|
|
result->dwBuildNumber, result->dwPlatformId, {'\0'}, 0, 0, 0, 0, 0 };
|
|
for ( ; VerifyVersionInfo(&checkVersion, VER_MAJORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMajorVersion)
|
|
result->dwMajorVersion = checkVersion.dwMajorVersion;
|
|
conditionMask = 0;
|
|
checkVersion.dwMajorVersion = result->dwMajorVersion;
|
|
checkVersion.dwMinorVersion = 0;
|
|
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_EQUAL);
|
|
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
|
VER_SET_CONDITION(conditionMask, VER_PLATFORMID, VER_EQUAL);
|
|
for ( ; VerifyVersionInfo(&checkVersion, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMinorVersion)
|
|
result->dwMinorVersion = checkVersion.dwMinorVersion;
|
|
}
|
|
|
|
# endif // !Q_OS_WINCE
|
|
|
|
static inline OSVERSIONINFO winOsVersion()
|
|
{
|
|
OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0, {'\0'}};
|
|
// GetVersionEx() has been deprecated in Windows 8.1 and will return
|
|
// only Windows 8 from that version on.
|
|
# if defined(_MSC_VER) && _MSC_VER >= 1800
|
|
# pragma warning( push )
|
|
# pragma warning( disable : 4996 )
|
|
# endif
|
|
GetVersionEx(&result);
|
|
# if defined(_MSC_VER) && _MSC_VER >= 1800
|
|
# pragma warning( pop )
|
|
# endif
|
|
# ifndef Q_OS_WINCE
|
|
if (result.dwMajorVersion == 6 && result.dwMinorVersion == 2) {
|
|
determineWinOsVersionFallbackPost8(&result);
|
|
}
|
|
# endif // !Q_OS_WINCE
|
|
return result;
|
|
}
|
|
#endif // !Q_OS_WINRT
|
|
|
|
static const char *winVer_helper()
|
|
{
|
|
switch (int(SubsurfaceSysInfo::WindowsVersion)) {
|
|
case SubsurfaceSysInfo::WV_NT:
|
|
return "NT";
|
|
case SubsurfaceSysInfo::WV_2000:
|
|
return "2000";
|
|
case SubsurfaceSysInfo::WV_XP:
|
|
return "XP";
|
|
case SubsurfaceSysInfo::WV_2003:
|
|
return "2003";
|
|
case SubsurfaceSysInfo::WV_VISTA:
|
|
return "Vista";
|
|
case SubsurfaceSysInfo::WV_WINDOWS7:
|
|
return "7";
|
|
case SubsurfaceSysInfo::WV_WINDOWS8:
|
|
return "8";
|
|
case SubsurfaceSysInfo::WV_WINDOWS8_1:
|
|
return "8.1";
|
|
|
|
case SubsurfaceSysInfo::WV_CE:
|
|
return "CE";
|
|
case SubsurfaceSysInfo::WV_CENET:
|
|
return "CENET";
|
|
case SubsurfaceSysInfo::WV_CE_5:
|
|
return "CE5";
|
|
case SubsurfaceSysInfo::WV_CE_6:
|
|
return "CE6";
|
|
}
|
|
// unknown, future version
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if defined(Q_OS_UNIX)
|
|
# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
|
|
# define USE_ETC_OS_RELEASE
|
|
struct QUnixOSVersion
|
|
{
|
|
// from /etc/os-release
|
|
QString productType; // $ID
|
|
QString productVersion; // $VERSION_ID
|
|
QString prettyName; // $PRETTY_NAME
|
|
};
|
|
|
|
static QString unquote(const char *begin, const char *end)
|
|
{
|
|
if (*begin == '"') {
|
|
Q_ASSERT(end[-1] == '"');
|
|
return QString::fromLatin1(begin + 1, end - begin - 2);
|
|
}
|
|
return QString::fromLatin1(begin, end - begin);
|
|
}
|
|
|
|
static bool readEtcOsRelease(QUnixOSVersion &v)
|
|
{
|
|
// we're avoiding QFile here
|
|
int fd = QT_OPEN("/etc/os-release", O_RDONLY);
|
|
if (fd == -1)
|
|
return false;
|
|
|
|
QT_STATBUF sbuf;
|
|
if (QT_FSTAT(fd, &sbuf) == -1) {
|
|
QT_CLOSE(fd);
|
|
return false;
|
|
}
|
|
|
|
QByteArray buffer(sbuf.st_size, Qt::Uninitialized);
|
|
buffer.resize(QT_READ(fd, buffer.data(), sbuf.st_size));
|
|
QT_CLOSE(fd);
|
|
|
|
const char *ptr = buffer.constData();
|
|
const char *end = buffer.constEnd();
|
|
const char *eol;
|
|
for ( ; ptr != end; ptr = eol + 1) {
|
|
static const char idString[] = "ID=";
|
|
static const char prettyNameString[] = "PRETTY_NAME=";
|
|
static const char versionIdString[] = "VERSION_ID=";
|
|
|
|
// find the end of the line after ptr
|
|
eol = static_cast<const char *>(memchr(ptr, '\n', end - ptr));
|
|
if (!eol)
|
|
eol = end - 1;
|
|
|
|
// note: we're doing a binary search here, so comparison
|
|
// must always be sorted
|
|
int cmp = strncmp(ptr, idString, strlen(idString));
|
|
if (cmp < 0)
|
|
continue;
|
|
if (cmp == 0) {
|
|
ptr += strlen(idString);
|
|
v.productType = unquote(ptr, eol);
|
|
continue;
|
|
}
|
|
|
|
cmp = strncmp(ptr, prettyNameString, strlen(prettyNameString));
|
|
if (cmp < 0)
|
|
continue;
|
|
if (cmp == 0) {
|
|
ptr += strlen(prettyNameString);
|
|
v.prettyName = unquote(ptr, eol);
|
|
continue;
|
|
}
|
|
|
|
cmp = strncmp(ptr, versionIdString, strlen(versionIdString));
|
|
if (cmp < 0)
|
|
continue;
|
|
if (cmp == 0) {
|
|
ptr += strlen(versionIdString);
|
|
v.productVersion = unquote(ptr, eol);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
# endif // USE_ETC_OS_RELEASE
|
|
#endif // Q_OS_UNIX
|
|
|
|
static QString unknownText()
|
|
{
|
|
return QStringLiteral("unknown");
|
|
}
|
|
|
|
QString SubsurfaceSysInfo::buildCpuArchitecture()
|
|
{
|
|
return QStringLiteral(ARCH_PROCESSOR);
|
|
}
|
|
|
|
QString SubsurfaceSysInfo::currentCpuArchitecture()
|
|
{
|
|
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
|
// We don't need to catch all the CPU architectures in this function;
|
|
// only those where the host CPU might be different than the build target
|
|
// (usually, 64-bit platforms).
|
|
SYSTEM_INFO info;
|
|
GetNativeSystemInfo(&info);
|
|
switch (info.wProcessorArchitecture) {
|
|
# ifdef PROCESSOR_ARCHITECTURE_AMD64
|
|
case PROCESSOR_ARCHITECTURE_AMD64:
|
|
return QStringLiteral("x86_64");
|
|
# endif
|
|
# ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
|
|
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
|
# endif
|
|
case PROCESSOR_ARCHITECTURE_IA64:
|
|
return QStringLiteral("ia64");
|
|
}
|
|
#elif defined(Q_OS_UNIX)
|
|
long ret = -1;
|
|
struct utsname u;
|
|
|
|
# if defined(Q_OS_SOLARIS)
|
|
// We need a special call for Solaris because uname(2) on x86 returns "i86pc" for
|
|
// both 32- and 64-bit CPUs. Reference:
|
|
// http://docs.oracle.com/cd/E18752_01/html/816-5167/sysinfo-2.html#REFMAN2sysinfo-2
|
|
// http://fxr.watson.org/fxr/source/common/syscall/systeminfo.c?v=OPENSOLARIS
|
|
// http://fxr.watson.org/fxr/source/common/conf/param.c?v=OPENSOLARIS;im=10#L530
|
|
if (ret == -1)
|
|
ret = sysinfo(SI_ARCHITECTURE_64, u.machine, sizeof u.machine);
|
|
# endif
|
|
|
|
if (ret == -1)
|
|
ret = uname(&u);
|
|
|
|
// we could use detectUnixVersion() above, but we only need a field no other function does
|
|
if (ret != -1) {
|
|
// the use of QT_BUILD_INTERNAL here is simply to ensure all branches build
|
|
// as we don't often build on some of the less common platforms
|
|
# if defined(Q_PROCESSOR_ARM) || defined(QT_BUILD_INTERNAL)
|
|
if (strcmp(u.machine, "aarch64") == 0)
|
|
return QStringLiteral("arm64");
|
|
if (strncmp(u.machine, "armv", 4) == 0)
|
|
return QStringLiteral("arm");
|
|
# endif
|
|
# if defined(Q_PROCESSOR_POWER) || defined(QT_BUILD_INTERNAL)
|
|
// harmonize "powerpc" and "ppc" to "power"
|
|
if (strncmp(u.machine, "ppc", 3) == 0)
|
|
return QLatin1String("power") + QLatin1String(u.machine + 3);
|
|
if (strncmp(u.machine, "powerpc", 7) == 0)
|
|
return QLatin1String("power") + QLatin1String(u.machine + 7);
|
|
if (strcmp(u.machine, "Power Macintosh") == 0)
|
|
return QLatin1String("power");
|
|
# endif
|
|
# if defined(Q_PROCESSOR_SPARC) || defined(QT_BUILD_INTERNAL)
|
|
// Solaris sysinfo(2) (above) uses "sparcv9", but uname -m says "sun4u";
|
|
// Linux says "sparc64"
|
|
if (strcmp(u.machine, "sun4u") == 0 || strcmp(u.machine, "sparc64") == 0)
|
|
return QStringLiteral("sparcv9");
|
|
if (strcmp(u.machine, "sparc32") == 0)
|
|
return QStringLiteral("sparc");
|
|
# endif
|
|
# if defined(Q_PROCESSOR_X86) || defined(QT_BUILD_INTERNAL)
|
|
// harmonize all "i?86" to "i386"
|
|
if (strlen(u.machine) == 4 && u.machine[0] == 'i'
|
|
&& u.machine[2] == '8' && u.machine[3] == '6')
|
|
return QStringLiteral("i386");
|
|
if (strcmp(u.machine, "amd64") == 0) // Solaris
|
|
return QStringLiteral("x86_64");
|
|
# endif
|
|
return QString::fromLatin1(u.machine);
|
|
}
|
|
#endif
|
|
return buildCpuArchitecture();
|
|
}
|
|
|
|
|
|
QString SubsurfaceSysInfo::buildAbi()
|
|
{
|
|
return QLatin1String(ARCH_FULL);
|
|
}
|
|
|
|
QString SubsurfaceSysInfo::kernelType()
|
|
{
|
|
#if defined(Q_OS_WINCE)
|
|
return QStringLiteral("wince");
|
|
#elif defined(Q_OS_WIN)
|
|
return QStringLiteral("winnt");
|
|
#elif defined(Q_OS_UNIX)
|
|
struct utsname u;
|
|
if (uname(&u) == 0)
|
|
return QString::fromLatin1(u.sysname).toLower();
|
|
#endif
|
|
return unknownText();
|
|
}
|
|
|
|
QString SubsurfaceSysInfo::kernelVersion()
|
|
{
|
|
#ifdef Q_OS_WINRT
|
|
// TBD
|
|
return QString();
|
|
#elif defined(Q_OS_WIN)
|
|
const OSVERSIONINFO osver = winOsVersion();
|
|
return QString::number(int(osver.dwMajorVersion)) + QLatin1Char('.') + QString::number(int(osver.dwMinorVersion))
|
|
+ QLatin1Char('.') + QString::number(int(osver.dwBuildNumber));
|
|
#else
|
|
struct utsname u;
|
|
if (uname(&u) == 0)
|
|
return QString::fromLatin1(u.release);
|
|
return QString();
|
|
#endif
|
|
}
|
|
|
|
QString SubsurfaceSysInfo::productType()
|
|
{
|
|
// similar, but not identical to QFileSelectorPrivate::platformSelectors
|
|
#if defined(Q_OS_WINPHONE)
|
|
return QStringLiteral("winphone");
|
|
#elif defined(Q_OS_WINRT)
|
|
return QStringLiteral("winrt");
|
|
#elif defined(Q_OS_WINCE)
|
|
return QStringLiteral("wince");
|
|
#elif defined(Q_OS_WIN)
|
|
return QStringLiteral("windows");
|
|
|
|
#elif defined(Q_OS_BLACKBERRY)
|
|
return QStringLiteral("blackberry");
|
|
#elif defined(Q_OS_QNX)
|
|
return QStringLiteral("qnx");
|
|
|
|
#elif defined(Q_OS_ANDROID)
|
|
return QStringLiteral("android");
|
|
|
|
#elif defined(Q_OS_IOS)
|
|
return QStringLiteral("ios");
|
|
#elif defined(Q_OS_OSX)
|
|
return QStringLiteral("osx");
|
|
#elif defined(Q_OS_DARWIN)
|
|
return QStringLiteral("darwin");
|
|
|
|
#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
|
|
QUnixOSVersion unixOsVersion;
|
|
readEtcOsRelease(unixOsVersion);
|
|
if (!unixOsVersion.productType.isEmpty())
|
|
return unixOsVersion.productType;
|
|
#endif
|
|
return unknownText();
|
|
}
|
|
|
|
QString SubsurfaceSysInfo::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);
|
|
#elif defined(Q_OS_WIN)
|
|
const char *version = winVer_helper();
|
|
if (version)
|
|
return QString::fromLatin1(version).toLower();
|
|
// fall through
|
|
|
|
// Android and Blackberry should not fall through to the Unix code
|
|
#elif defined(Q_OS_ANDROID)
|
|
// TBD
|
|
#elif defined(Q_OS_BLACKBERRY)
|
|
deviceinfo_details_t *deviceInfo;
|
|
if (deviceinfo_get_details(&deviceInfo) == BPS_SUCCESS) {
|
|
QString bbVersion = QString::fromLatin1(deviceinfo_details_get_device_os_version(deviceInfo));
|
|
deviceinfo_free_details(&deviceInfo);
|
|
return bbVersion;
|
|
}
|
|
#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
|
|
QUnixOSVersion unixOsVersion;
|
|
readEtcOsRelease(unixOsVersion);
|
|
if (!unixOsVersion.productVersion.isEmpty())
|
|
return unixOsVersion.productVersion;
|
|
#endif
|
|
|
|
// fallback
|
|
return unknownText();
|
|
}
|
|
|
|
QString SubsurfaceSysInfo::prettyProductName()
|
|
{
|
|
#if defined(Q_OS_IOS)
|
|
return QLatin1String("iOS ") + productVersion();
|
|
#elif defined(Q_OS_OSX)
|
|
// get the known codenames
|
|
const char *basename = 0;
|
|
switch (int(MacintoshVersion)) {
|
|
case MV_CHEETAH:
|
|
case MV_PUMA:
|
|
case MV_JAGUAR:
|
|
case MV_PANTHER:
|
|
case MV_TIGER:
|
|
// This version of Qt does not run on those versions of OS X
|
|
// so this case label will never be reached
|
|
Q_UNREACHABLE();
|
|
break;
|
|
case MV_LEOPARD:
|
|
basename = "Mac OS X Leopard (";
|
|
break;
|
|
case MV_SNOWLEOPARD:
|
|
basename = "Mac OS X Snow Leopard (";
|
|
break;
|
|
case MV_LION:
|
|
basename = "Mac OS X Lion (";
|
|
break;
|
|
case MV_MOUNTAINLION:
|
|
basename = "OS X Mountain Lion (";
|
|
break;
|
|
case MV_MAVERICKS:
|
|
basename = "OS X Mavericks (";
|
|
break;
|
|
#ifdef MV_YOSEMITE
|
|
case MV_YOSEMITE:
|
|
#else
|
|
case 0x000C: // MV_YOSEMITE
|
|
#endif
|
|
basename = "OS X Yosemite (";
|
|
break;
|
|
#ifdef MV_ELCAPITAN
|
|
case MV_ELCAPITAN :
|
|
#else
|
|
case 0x000D: // MV_ELCAPITAN
|
|
#endif
|
|
basename = "OS X El Capitan (";
|
|
break;
|
|
}
|
|
if (basename)
|
|
return QLatin1String(basename) + productVersion() + QLatin1Char(')');
|
|
|
|
// a future version of OS X
|
|
return QLatin1String("OS X ") + productVersion();
|
|
#elif defined(Q_OS_WINPHONE)
|
|
return QLatin1String("Windows Phone ") + QLatin1String(winVer_helper());
|
|
#elif defined(Q_OS_WIN)
|
|
return QLatin1String("Windows ") + QLatin1String(winVer_helper());
|
|
#elif defined(Q_OS_ANDROID)
|
|
return QLatin1String("Android ") + productVersion();
|
|
#elif defined(Q_OS_BLACKBERRY)
|
|
return QLatin1String("BlackBerry ") + productVersion();
|
|
#elif defined(Q_OS_UNIX)
|
|
# ifdef USE_ETC_OS_RELEASE
|
|
QUnixOSVersion unixOsVersion;
|
|
readEtcOsRelease(unixOsVersion);
|
|
if (!unixOsVersion.prettyName.isEmpty())
|
|
return unixOsVersion.prettyName;
|
|
# endif
|
|
struct utsname u;
|
|
if (uname(&u) == 0)
|
|
return QString::fromLatin1(u.sysname) + QLatin1Char(' ') + QString::fromLatin1(u.release);
|
|
#endif
|
|
return unknownText();
|
|
}
|
|
|
|
#endif // Qt >= 5.4
|
|
|
|
QString SubsurfaceSysInfo::prettyOsName()
|
|
{
|
|
// Matches the pre-release version of Qt 5.4
|
|
QString pretty = prettyProductName();
|
|
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID)
|
|
// QSysInfo::kernelType() returns lowercase ("linux" instead of "Linux")
|
|
struct utsname u;
|
|
if (uname(&u) == 0)
|
|
return QString::fromLatin1(u.sysname) + QLatin1String(" (") + pretty + QLatin1Char(')');
|
|
#endif
|
|
return pretty;
|
|
}
|
|
|
|
extern "C" {
|
|
bool isWin7Or8()
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
return (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) >= QSysInfo::WV_WINDOWS7;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
}
|