mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 22:03:23 +00:00
OS Detection
Implements automatic OS and architecture detection. This code has been taken from the Qt repositories for Qt 5.4 (LGPL) and slightly modified into the SubsurfaceSysInfo class. Signed-off-by: Joseph W. Joshua <joejoshw@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
cdd3b3d9cd
commit
1ec5e6ffc4
4 changed files with 903 additions and 3 deletions
|
@ -8,12 +8,14 @@
|
|||
#include "ssrf-version.h"
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
#include "subsurfacesysinfo.h"
|
||||
UserSurvey::UserSurvey(QWidget *parent) : QDialog(parent),
|
||||
ui(new Ui::UserSurvey)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
// fill in the system data
|
||||
ui->system->append(tr("Operating System: %1").arg(SubsurfaceSysInfo::prettyOsName()));
|
||||
ui->system->append(tr("CPU Architecture: %1").arg(SubsurfaceSysInfo::cpuArchitecture()));
|
||||
}
|
||||
|
||||
UserSurvey::~UserSurvey()
|
||||
|
|
|
@ -82,7 +82,8 @@ HEADERS = \
|
|||
qt-ui/profile/ruleritem.h \
|
||||
qt-ui/updatemanager.h \
|
||||
qt-ui/divelogexportdialog.h \
|
||||
qt-ui/usersurvey.h
|
||||
qt-ui/usersurvey.h \
|
||||
subsurfacesysinfo.h
|
||||
|
||||
android: HEADERS -= \
|
||||
qt-ui/usermanual.h \
|
||||
|
@ -160,7 +161,8 @@ SOURCES = \
|
|||
qt-ui/profile/ruleritem.cpp \
|
||||
qt-ui/updatemanager.cpp \
|
||||
qt-ui/divelogexportdialog.cpp \
|
||||
qt-ui/usersurvey.cpp
|
||||
qt-ui/usersurvey.cpp \
|
||||
subsurfacesysinfo.cpp
|
||||
|
||||
android: SOURCES += android.cpp
|
||||
else: linux*: SOURCES += linux.c
|
||||
|
|
603
subsurfacesysinfo.cpp
Normal file
603
subsurfacesysinfo.cpp
Normal file
|
@ -0,0 +1,603 @@
|
|||
#include "subsurfacesysinfo.h"
|
||||
#include <QString>
|
||||
#include "qplatformdefs.h"
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
|
||||
Q_CORE_EXPORT OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref)
|
||||
{
|
||||
return FSPathMakeRef(reinterpret_cast<const UInt8 *>(file.toUtf8().constData()), fsref, 0);
|
||||
}
|
||||
|
||||
Q_CORE_EXPORT void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1)
|
||||
{
|
||||
Q_UNUSED(encoding);
|
||||
Q_UNUSED(len);
|
||||
CFStringGetPascalString(QCFString(s), str, 256, CFStringGetSystemEncoding());
|
||||
}
|
||||
|
||||
Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr) {
|
||||
return QCFString(CFStringCreateWithPascalString(0, pstr, CFStringGetSystemEncoding()));
|
||||
}
|
||||
|
||||
SubsurfaceSysInfo::MacVersion SubsurfaceSysInfo::macVersion()
|
||||
{
|
||||
#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 SubsurfaceSysInfo::MacVersion(gestalt_version + 2);
|
||||
}
|
||||
#elif defined(Q_OS_IOS)
|
||||
return qt_ios_version(); // qtcore_mac_objc.mm
|
||||
#endif
|
||||
return SubsurfaceSysInfo::MV_Unknown;
|
||||
}
|
||||
const SubsurfaceSysInfo::MacVersion SubsurfaceSysInfo::MacintoshVersion = SubsurfaceSysInfo::macVersion();
|
||||
#elif 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
|
||||
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) {
|
||||
// This could be Windows 8.1 or higher. Note that as of Windows 9,
|
||||
// the major version needs to be checked as well.
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_PLATFORMID, VER_EQUAL);
|
||||
OSVERSIONINFOEX checkVersion = { sizeof(OSVERSIONINFOEX), result.dwMajorVersion, result.dwMinorVersion,
|
||||
result.dwBuildNumber, result.dwPlatformId, {'\0'}, 0, 0, 0, 0, 0 };
|
||||
for ( ; VerifyVersionInfo(&checkVersion, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, conditionMask); ++checkVersion.dwMinorVersion)
|
||||
result.dwMinorVersion = checkVersion.dwMinorVersion;
|
||||
}
|
||||
# endif // !Q_OS_WINCE
|
||||
return result;
|
||||
}
|
||||
#endif // !Q_OS_WINRT
|
||||
|
||||
SubsurfaceSysInfo::WinVersion SubsurfaceSysInfo::windowsVersion()
|
||||
{
|
||||
#ifndef VER_PLATFORM_WIN32s
|
||||
#define VER_PLATFORM_WIN32s 0
|
||||
#endif
|
||||
#ifndef VER_PLATFORM_WIN32_WINDOWS
|
||||
#define VER_PLATFORM_WIN32_WINDOWS 1
|
||||
#endif
|
||||
#ifndef VER_PLATFORM_WIN32_NT
|
||||
#define VER_PLATFORM_WIN32_NT 2
|
||||
#endif
|
||||
#ifndef VER_PLATFORM_WIN32_CE
|
||||
#define VER_PLATFORM_WIN32_CE 3
|
||||
#endif
|
||||
|
||||
static SubsurfaceSysInfo::WinVersion winver;
|
||||
if (winver)
|
||||
return winver;
|
||||
#ifdef Q_OS_WINRT
|
||||
winver = SubsurfaceSysInfo::WV_WINDOWS8;
|
||||
#else
|
||||
winver = SubsurfaceSysInfo::WV_NT;
|
||||
const OSVERSIONINFO osver = winOsVersion();
|
||||
#ifdef Q_OS_WINCE
|
||||
DWORD qt_cever = 0;
|
||||
qt_cever = osver.dwMajorVersion * 100;
|
||||
qt_cever += osver.dwMinorVersion * 10;
|
||||
#endif
|
||||
switch (osver.dwPlatformId) {
|
||||
case VER_PLATFORM_WIN32s:
|
||||
winver = SubsurfaceSysInfo::WV_32s;
|
||||
break;
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
// We treat Windows Me (minor 90) the same as Windows 98
|
||||
if (osver.dwMinorVersion == 90)
|
||||
winver = SubsurfaceSysInfo::WV_Me;
|
||||
else if (osver.dwMinorVersion == 10)
|
||||
winver = SubsurfaceSysInfo::WV_98;
|
||||
else
|
||||
winver = SubsurfaceSysInfo::WV_95;
|
||||
break;
|
||||
#ifdef Q_OS_WINCE
|
||||
case VER_PLATFORM_WIN32_CE:
|
||||
if (qt_cever >= 600)
|
||||
winver = SubsurfaceSysInfo::WV_CE_6;
|
||||
if (qt_cever >= 500)
|
||||
winver = SubsurfaceSysInfo::WV_CE_5;
|
||||
else if (qt_cever >= 400)
|
||||
winver = SubsurfaceSysInfo::WV_CENET;
|
||||
else
|
||||
winver = SubsurfaceSysInfo::WV_CE;
|
||||
break;
|
||||
#endif
|
||||
default: // VER_PLATFORM_WIN32_NT
|
||||
if (osver.dwMajorVersion < 5) {
|
||||
winver = SubsurfaceSysInfo::WV_NT;
|
||||
} else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0) {
|
||||
winver = SubsurfaceSysInfo::WV_2000;
|
||||
} else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1) {
|
||||
winver = SubsurfaceSysInfo::WV_XP;
|
||||
} else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2) {
|
||||
winver = SubsurfaceSysInfo::WV_2003;
|
||||
} else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0) {
|
||||
winver = SubsurfaceSysInfo::WV_VISTA;
|
||||
} else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1) {
|
||||
winver = SubsurfaceSysInfo::WV_WINDOWS7;
|
||||
} else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2) {
|
||||
winver = SubsurfaceSysInfo::WV_WINDOWS8;
|
||||
} else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3) {
|
||||
winver = SubsurfaceSysInfo::WV_WINDOWS8_1;
|
||||
} else {
|
||||
qWarning("Qt: Untested Windows version %d.%d detected!",
|
||||
int(osver.dwMajorVersion), int(osver.dwMinorVersion));
|
||||
winver = SubsurfaceSysInfo::WV_NT_based;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
{
|
||||
QByteArray override = qgetenv("QT_WINVER_OVERRIDE");
|
||||
if (override.isEmpty())
|
||||
return winver;
|
||||
|
||||
if (override == "Me")
|
||||
winver = SubsurfaceSysInfo::WV_Me;
|
||||
if (override == "95")
|
||||
winver = SubsurfaceSysInfo::WV_95;
|
||||
else if (override == "98")
|
||||
winver = SubsurfaceSysInfo::WV_98;
|
||||
else if (override == "NT")
|
||||
winver = SubsurfaceSysInfo::WV_NT;
|
||||
else if (override == "2000")
|
||||
winver = SubsurfaceSysInfo::WV_2000;
|
||||
else if (override == "2003")
|
||||
winver = SubsurfaceSysInfo::WV_2003;
|
||||
else if (override == "XP")
|
||||
winver = SubsurfaceSysInfo::WV_XP;
|
||||
else if (override == "VISTA")
|
||||
winver = SubsurfaceSysInfo::WV_VISTA;
|
||||
else if (override == "WINDOWS7")
|
||||
winver = SubsurfaceSysInfo::WV_WINDOWS7;
|
||||
else if (override == "WINDOWS8")
|
||||
winver = SubsurfaceSysInfo::WV_WINDOWS8;
|
||||
else if (override == "WINDOWS8_1")
|
||||
winver = SubsurfaceSysInfo::WV_WINDOWS8_1;
|
||||
}
|
||||
#endif
|
||||
#endif // !Q_OS_WINRT
|
||||
|
||||
return winver;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const SubsurfaceSysInfo::WinVersion SubsurfaceSysInfo::WindowsVersion = SubsurfaceSysInfo::windowsVersion();
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
|
||||
# define USE_ETC_OS_RELEASE
|
||||
# endif
|
||||
struct QUnixOSVersion
|
||||
{
|
||||
// from uname(2)
|
||||
QString sysName;
|
||||
QString sysNameLower;
|
||||
QString sysRelease;
|
||||
|
||||
# if !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_MAC)
|
||||
// from /etc/os-release or guessed
|
||||
QString versionIdentifier; // ${ID}_$VERSION_ID
|
||||
QString versionText; // $PRETTY_NAME
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef USE_ETC_OS_RELEASE
|
||||
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;
|
||||
}
|
||||
|
||||
QString partialIdentifier;
|
||||
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;
|
||||
|
||||
int cmp = strncmp(ptr, idString, strlen(idString));
|
||||
if (cmp < 0)
|
||||
continue;
|
||||
if (cmp == 0) {
|
||||
ptr += strlen(idString);
|
||||
QString id = unquote(ptr, eol);
|
||||
if (partialIdentifier.isNull())
|
||||
partialIdentifier = id;
|
||||
else
|
||||
v.versionIdentifier = id + QLatin1Char('_') + partialIdentifier;
|
||||
continue;
|
||||
}
|
||||
|
||||
cmp = strncmp(ptr, prettyNameString, strlen(prettyNameString));
|
||||
if (cmp < 0)
|
||||
continue;
|
||||
if (cmp == 0) {
|
||||
ptr += strlen(prettyNameString);
|
||||
v.versionText = unquote(ptr, eol);
|
||||
continue;
|
||||
}
|
||||
|
||||
cmp = strncmp(ptr, versionIdString, strlen(versionIdString));
|
||||
if (cmp < 0)
|
||||
continue;
|
||||
if (cmp == 0) {
|
||||
ptr += strlen(versionIdString);
|
||||
QString id = unquote(ptr, eol);
|
||||
if (partialIdentifier.isNull())
|
||||
partialIdentifier = id;
|
||||
else
|
||||
v.versionIdentifier = partialIdentifier + QLatin1Char('_') + id;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // USE_ETC_OS_RELEASE
|
||||
|
||||
static QUnixOSVersion detectUnixVersion()
|
||||
{
|
||||
QUnixOSVersion v;
|
||||
struct utsname u;
|
||||
if (uname(&u) != -1) {
|
||||
v.sysName = QString::fromLatin1(u.sysname);
|
||||
v.sysNameLower = v.sysName.toLower();
|
||||
v.sysRelease = QString::fromLatin1(u.release);
|
||||
} else {
|
||||
v.sysName = QLatin1String("Detection failed");
|
||||
// leave sysNameLower & sysRelease unset
|
||||
}
|
||||
|
||||
# if !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_MAC)
|
||||
# ifdef USE_ETC_OS_RELEASE
|
||||
if (readEtcOsRelease(v))
|
||||
return v;
|
||||
# endif
|
||||
|
||||
if (!v.sysNameLower.isEmpty()) {
|
||||
// will produce "qnx_6.5" or "sunos_5.9"
|
||||
v.versionIdentifier = v.sysNameLower + QLatin1Char('_') + v.sysRelease;
|
||||
}
|
||||
# endif
|
||||
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
QString SubsurfaceSysInfo::unknownText()
|
||||
{
|
||||
return QStringLiteral("unknown");
|
||||
}
|
||||
|
||||
QString SubsurfaceSysInfo::cpuArchitecture()
|
||||
{
|
||||
return QStringLiteral(ARCH_PROCESSOR);
|
||||
}
|
||||
|
||||
QString SubsurfaceSysInfo::fullCpuArchitecture()
|
||||
{
|
||||
return QLatin1String(ARCH_FULL);
|
||||
}
|
||||
|
||||
QString SubsurfaceSysInfo::osType()
|
||||
{
|
||||
#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_LINUX)
|
||||
return QStringLiteral("linux");
|
||||
|
||||
#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(Q_OS_FREEBSD_KERNEL)
|
||||
return QStringLiteral("freebsd");
|
||||
#elif defined(Q_OS_UNIX)
|
||||
QUnixOSVersion unixOsVersion = detectUnixVersion();
|
||||
if (!unixOsVersion.sysNameLower.isEmpty())
|
||||
return unixOsVersion.sysNameLower;
|
||||
#endif
|
||||
return unknownText();
|
||||
}
|
||||
|
||||
QString SubsurfaceSysInfo::osKernelVersion()
|
||||
{
|
||||
#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
|
||||
return detectUnixVersion().sysRelease;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString SubsurfaceSysInfo::osVersion()
|
||||
{
|
||||
#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(Q_OS_UNIX)
|
||||
QUnixOSVersion unixOsVersion = detectUnixVersion();
|
||||
if (!unixOsVersion.versionIdentifier.isEmpty())
|
||||
return unixOsVersion.versionIdentifier;
|
||||
#endif
|
||||
|
||||
// fallback
|
||||
return unknownText();
|
||||
}
|
||||
|
||||
QString SubsurfaceSysInfo::prettyOsName()
|
||||
{
|
||||
#if defined(Q_OS_IOS)
|
||||
return QLatin1String("iOS ") + osVersion();
|
||||
#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;
|
||||
case MV_YOSEMITE:
|
||||
basename = "OS X Yosemite (";
|
||||
break;
|
||||
}
|
||||
if (basename)
|
||||
return QLatin1String(basename) + osVersion() + QLatin1Char(')');
|
||||
|
||||
// a future version of OS X
|
||||
return QLatin1String("OS X ") + osVersion();
|
||||
#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 ") + osVersion();
|
||||
#elif defined(Q_OS_BLACKBERRY)
|
||||
return QLatin1String("BlackBerry ") + osVersion();
|
||||
#elif defined(Q_OS_UNIX)
|
||||
QUnixOSVersion unixOsVersion = detectUnixVersion();
|
||||
if (unixOsVersion.versionText.isEmpty())
|
||||
return unixOsVersion.sysName;
|
||||
else
|
||||
return unixOsVersion.sysName + QLatin1String(" (") + unixOsVersion.versionText + QLatin1Char(')');
|
||||
#else
|
||||
return unknownText();
|
||||
#endif
|
||||
}
|
293
subsurfacesysinfo.h
Normal file
293
subsurfacesysinfo.h
Normal file
|
@ -0,0 +1,293 @@
|
|||
#ifndef SUBSURFACESYSINFO_H
|
||||
#define SUBSURFACESYSINFO_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__arm64__)
|
||||
# define Q_PROCESSOR_ARM
|
||||
# if defined(__arm64__)
|
||||
# define Q_PROCESSOR_ARM_64
|
||||
# else
|
||||
# define Q_PROCESSOR_ARM_32
|
||||
# endif
|
||||
# if defined(__ARM64_ARCH_8__)
|
||||
# define Q_PROCESSOR_ARM_V8
|
||||
# define Q_PROCESSOR_ARM_V7
|
||||
# define Q_PROCESSOR_ARM_V6
|
||||
# define Q_PROCESSOR_ARM_V5
|
||||
# elif defined(__ARM_ARCH_7__) \
|
||||
|| defined(__ARM_ARCH_7A__) \
|
||||
|| defined(__ARM_ARCH_7R__) \
|
||||
|| defined(__ARM_ARCH_7M__) \
|
||||
|| defined(__ARM_ARCH_7S__) \
|
||||
|| defined(_ARM_ARCH_7) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7) \
|
||||
|| (defined(_M_ARM) && _M_ARM-0 >= 7)
|
||||
# define Q_PROCESSOR_ARM_V7
|
||||
# define Q_PROCESSOR_ARM_V6
|
||||
# define Q_PROCESSOR_ARM_V5
|
||||
# elif defined(__ARM_ARCH_6__) \
|
||||
|| defined(__ARM_ARCH_6J__) \
|
||||
|| defined(__ARM_ARCH_6T2__) \
|
||||
|| defined(__ARM_ARCH_6Z__) \
|
||||
|| defined(__ARM_ARCH_6K__) \
|
||||
|| defined(__ARM_ARCH_6ZK__) \
|
||||
|| defined(__ARM_ARCH_6M__) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6) \
|
||||
|| (defined(_M_ARM) && _M_ARM-0 >= 6)
|
||||
# define Q_PROCESSOR_ARM_V6
|
||||
# define Q_PROCESSOR_ARM_V5
|
||||
# elif defined(__ARM_ARCH_5TEJ__) \
|
||||
|| defined(__ARM_ARCH_5TE__) \
|
||||
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5) \
|
||||
|| (defined(_M_ARM) && _M_ARM-0 >= 5)
|
||||
# define Q_PROCESSOR_ARM_V5
|
||||
# endif
|
||||
# if defined(__ARMEL__)
|
||||
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
|
||||
# elif defined(__ARMEB__)
|
||||
# define Q_BYTE_ORDER Q_BIG_ENDIAN
|
||||
# else
|
||||
// Q_BYTE_ORDER not defined, use endianness auto-detection
|
||||
#endif
|
||||
|
||||
|
||||
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
# define Q_PROCESSOR_X86_32
|
||||
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
|
||||
|
||||
# if defined(_M_IX86)
|
||||
# define Q_PROCESSOR_X86 (_M_IX86/100)
|
||||
# elif defined(__i686__) || defined(__athlon__) || defined(__SSE__)
|
||||
# define Q_PROCESSOR_X86 6
|
||||
# elif defined(__i586__) || defined(__k6__)
|
||||
# define Q_PROCESSOR_X86 5
|
||||
# elif defined(__i486__)
|
||||
# define Q_PROCESSOR_X86 4
|
||||
# else
|
||||
# define Q_PROCESSOR_X86 3
|
||||
#endif
|
||||
|
||||
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||
# define Q_PROCESSOR_X86 6
|
||||
# define Q_PROCESSOR_X86_64
|
||||
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
|
||||
# define Q_PROCESSOR_WORDSIZE 8
|
||||
|
||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
# define Q_PROCESSOR_IA64
|
||||
# define Q_PROCESSOR_WORDSIZE 8
|
||||
|
||||
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
|
||||
# define Q_PROCESSOR_MIPS
|
||||
# if defined(_MIPS_ARCH_MIPS1) || (defined(__mips) && __mips - 0 >= 1)
|
||||
# define Q_PROCESSOR_MIPS_I
|
||||
# endif
|
||||
# if defined(_MIPS_ARCH_MIPS2) || (defined(__mips) && __mips - 0 >= 2)
|
||||
# define Q_PROCESSOR_MIPS_II
|
||||
# endif
|
||||
# if defined(_MIPS_ARCH_MIPS32) || defined(__mips32)
|
||||
# define Q_PROCESSOR_MIPS_32
|
||||
# endif
|
||||
# if defined(_MIPS_ARCH_MIPS3) || (defined(__mips) && __mips - 0 >= 3)
|
||||
# define Q_PROCESSOR_MIPS_III
|
||||
# endif
|
||||
# if defined(_MIPS_ARCH_MIPS4) || (defined(__mips) && __mips - 0 >= 4)
|
||||
# define Q_PROCESSOR_MIPS_IV
|
||||
# endif
|
||||
# if defined(_MIPS_ARCH_MIPS5) || (defined(__mips) && __mips - 0 >= 5)
|
||||
# define Q_PROCESSOR_MIPS_V
|
||||
# endif
|
||||
# if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
|
||||
# define Q_PROCESSOR_MIPS_64
|
||||
# endif
|
||||
# if defined(__MIPSEL__)
|
||||
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
|
||||
# elif defined(__MIPSEB__)
|
||||
# define Q_BYTE_ORDER Q_BIG_ENDIAN
|
||||
# else
|
||||
// Q_BYTE_ORDER not defined, use endianness auto-detection
|
||||
#endif
|
||||
|
||||
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
|
||||
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
|
||||
|| defined(_M_MPPC) || defined(_M_PPC)
|
||||
# define Q_PROCESSOR_POWER
|
||||
# if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
|
||||
# define Q_PROCESSOR_POWER_64
|
||||
# else
|
||||
# define Q_PROCESSOR_POWER_32
|
||||
# endif
|
||||
|
||||
#elif defined(__s390__)
|
||||
# define Q_PROCESSOR_S390
|
||||
# if defined(__s390x__)
|
||||
# define Q_PROCESSOR_S390_X
|
||||
# endif
|
||||
# define Q_BYTE_ORDER Q_BIG_ENDIAN
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Some processors support either endian format, try to detect which we are using.
|
||||
#if !defined(Q_BYTE_ORDER)
|
||||
# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN)
|
||||
// Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults
|
||||
# define Q_BYTE_ORDER __BYTE_ORDER__
|
||||
# elif defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN)
|
||||
# define Q_BYTE_ORDER Q_BIG_ENDIAN
|
||||
# elif defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) \
|
||||
|| defined(_WIN32_WCE) || defined(WINAPI_FAMILY) // Windows CE is always little-endian according to MSDN.
|
||||
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
|
||||
# else
|
||||
# error "Unable to determine byte order!"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef Q_PROCESSOR_WORDSIZE
|
||||
# ifdef __SIZEOF_POINTER__
|
||||
/* GCC & friends define this */
|
||||
# define Q_PROCESSOR_WORDSIZE __SIZEOF_POINTER__
|
||||
# elif defined(_LP64) || defined(__LP64__) || defined(WIN64) || defined(_WIN64)
|
||||
# define Q_PROCESSOR_WORDSIZE 8
|
||||
# else
|
||||
# define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
class QString;
|
||||
class SubsurfaceSysInfo {
|
||||
public:
|
||||
enum Sizes {
|
||||
WordSize = (sizeof(void *)<<3)
|
||||
};
|
||||
|
||||
#ifndef QStringLiteral
|
||||
// no lambdas, not GCC, or GCC in C++98 mode with 4-byte wchar_t
|
||||
// fallback, return a temporary QString
|
||||
// source code is assumed to be encoded in UTF-8
|
||||
|
||||
# define QStringLiteral(str) QString::fromUtf8("" str "", sizeof(str) - 1)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(QT_BUILD_QMAKE)
|
||||
enum Endian {
|
||||
BigEndian,
|
||||
LittleEndian
|
||||
};
|
||||
/* needed to bootstrap qmake */
|
||||
static const int ByteOrder;
|
||||
#elif defined(Q_BYTE_ORDER)
|
||||
enum Endian {
|
||||
BigEndian,
|
||||
LittleEndian
|
||||
|
||||
# ifdef Q_QDOC
|
||||
, ByteOrder = <platform-dependent>
|
||||
# elif Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
, ByteOrder = BigEndian
|
||||
# elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
, ByteOrder = LittleEndian
|
||||
# else
|
||||
# error "Undefined byte order"
|
||||
# endif
|
||||
};
|
||||
#endif
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
|
||||
enum WinVersion {
|
||||
WV_32s = 0x0001,
|
||||
WV_95 = 0x0002,
|
||||
WV_98 = 0x0003,
|
||||
WV_Me = 0x0004,
|
||||
WV_DOS_based= 0x000f,
|
||||
|
||||
/* codenames */
|
||||
WV_NT = 0x0010,
|
||||
WV_2000 = 0x0020,
|
||||
WV_XP = 0x0030,
|
||||
WV_2003 = 0x0040,
|
||||
WV_VISTA = 0x0080,
|
||||
WV_WINDOWS7 = 0x0090,
|
||||
WV_WINDOWS8 = 0x00a0,
|
||||
WV_WINDOWS8_1 = 0x00b0,
|
||||
WV_NT_based = 0x00f0,
|
||||
|
||||
/* version numbers */
|
||||
WV_4_0 = WV_NT,
|
||||
WV_5_0 = WV_2000,
|
||||
WV_5_1 = WV_XP,
|
||||
WV_5_2 = WV_2003,
|
||||
WV_6_0 = WV_VISTA,
|
||||
WV_6_1 = WV_WINDOWS7,
|
||||
WV_6_2 = WV_WINDOWS8,
|
||||
WV_6_3 = WV_WINDOWS8_1,
|
||||
|
||||
WV_CE = 0x0100,
|
||||
WV_CENET = 0x0200,
|
||||
WV_CE_5 = 0x0300,
|
||||
WV_CE_6 = 0x0400,
|
||||
WV_CE_based = 0x0f00
|
||||
};
|
||||
static const WinVersion WindowsVersion;
|
||||
static WinVersion windowsVersion();
|
||||
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
# define Q_MV_IOS(major, minor) (QSysInfo::MV_IOS | major << 4 | minor)
|
||||
enum MacVersion {
|
||||
MV_Unknown = 0x0000,
|
||||
|
||||
/* version */
|
||||
MV_9 = 0x0001,
|
||||
MV_10_0 = 0x0002,
|
||||
MV_10_1 = 0x0003,
|
||||
MV_10_2 = 0x0004,
|
||||
MV_10_3 = 0x0005,
|
||||
MV_10_4 = 0x0006,
|
||||
MV_10_5 = 0x0007,
|
||||
MV_10_6 = 0x0008,
|
||||
MV_10_7 = 0x0009,
|
||||
MV_10_8 = 0x000A,
|
||||
MV_10_9 = 0x000B,
|
||||
MV_10_10 = 0x000C,
|
||||
|
||||
/* codenames */
|
||||
MV_CHEETAH = MV_10_0,
|
||||
MV_PUMA = MV_10_1,
|
||||
MV_JAGUAR = MV_10_2,
|
||||
MV_PANTHER = MV_10_3,
|
||||
MV_TIGER = MV_10_4,
|
||||
MV_LEOPARD = MV_10_5,
|
||||
MV_SNOWLEOPARD = MV_10_6,
|
||||
MV_LION = MV_10_7,
|
||||
MV_MOUNTAINLION = MV_10_8,
|
||||
MV_MAVERICKS = MV_10_9,
|
||||
MV_YOSEMITE = MV_10_10,
|
||||
|
||||
/* iOS */
|
||||
MV_IOS = 1 << 8,
|
||||
MV_IOS_4_3 = Q_MV_IOS(4, 3),
|
||||
MV_IOS_5_0 = Q_MV_IOS(5, 0),
|
||||
MV_IOS_5_1 = Q_MV_IOS(5, 1),
|
||||
MV_IOS_6_0 = Q_MV_IOS(6, 0),
|
||||
MV_IOS_6_1 = Q_MV_IOS(6, 1),
|
||||
MV_IOS_7_0 = Q_MV_IOS(7, 0),
|
||||
MV_IOS_7_1 = Q_MV_IOS(7, 1),
|
||||
MV_IOS_8_0 = Q_MV_IOS(8, 0)
|
||||
};
|
||||
static const MacVersion MacintoshVersion;
|
||||
static MacVersion macVersion();
|
||||
#endif
|
||||
static QString unknownText();
|
||||
static QString cpuArchitecture();
|
||||
static QString fullCpuArchitecture();
|
||||
static QString osType();
|
||||
static QString osKernelVersion();
|
||||
static QString osVersion();
|
||||
static QString prettyOsName();
|
||||
};
|
||||
|
||||
|
||||
#endif // SUBSURFACESYSINFO_H
|
Loading…
Add table
Reference in a new issue