#include "SystemInfomation.h"
#include "../Util.h"
#include <stdio.h>
#include <QtWidgets>
#include <QScreen>
#ifdef __APPLE__
# include "TargetConditionals.h"
#elif defined(_WIN32)
# include <windows.h>
#else
# include <unistd.h>
# include <sys/utsname.h>
# include <sys/sysctl.h>
# include <sys/types.h>
#endif
void getSystemInfo(SystemInfo& a_info)
{
a_info.m_cpuType = "unknown";
a_info.m_osType = "unknown";
a_info.m_osVersion = "unknown";
#ifdef _WIN32
a_info.m_osType = "Windows";
// Get RAM size
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
a_info.m_ramSize = status.ullTotalPhys;
// Get OS version
const OSVERSIONINFO osver = winOsVersion();
a_info.m_osVersion.reserve(512);
snprintf(a_info.m_osVersion.data(), "%i.%i.%i", osver.dwMajorVersion, osver.dwMinorVersion, osver.dwBuildNumber);
// Get OS arch
SYSTEM_INFO info;
GetNativeSystemInfo(&info);
# ifdef _WIN64
//if (info.wProcessorArchitecture == ???)
a_info.m_cpuType = "x86_64";
# else
a_info.m_cpuType = "x86";
# endif
#else
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
a_info.m_ramSize = pages * page_size;
struct utsname u;
long ret = uname(&u);
if (ret != -1)
{
a_info.m_cpuType = u.machine;
a_info.m_osVersion = u.sysname + std::string(" ") + u.release;
}
# ifdef __APPLE__
// Get RAM Size
int mib[2] = { CTL_HW, HW_MEMSIZE };
size_t len = sizeof(uint64_t);
sysctl(mib, sizeof(mib) / sizeof(mib[0]), &u.ramSize, &len, NULL, 0);
# if TARGET_OS_IPHONE
a_info.m_osType = "iOS";
# elif TARGET_OS_MAC
const char *macCodeName = "";
switch (int(MacintoshVersion)) {
case MV_CHEETAH: macCodeName = " Cheetah"; break;
case MV_PUMA: macCodeName = " Puma"; break;
case MV_JAGUAR: macCodeName = " Jaguar"; break;
case MV_PANTHER: macCodeName = " Panther"; break;
case MV_TIGER: macCodeName = " Tiger"; break;
case MV_LEOPARD: macCodeName = " Leopard"; break;
case MV_SNOWLEOPARD: macCodeName = " Snow Leopard"; break;
case MV_LION: macCodeName = " Lion"; break;
case MV_MOUNTAINLION:macCodeName = " Mountain Lion"; break;
case MV_MAVERICKS: macCodeName = " Mavericks"; break;
case MV_YOSEMITE: macCodeName = " Yosemite"; break;
}
a_info.m_osType = "Mac OS X" + std::string(macCodeName);
# endif
# elif __ANDROID__
a_info.m_osType = "Android";
# elif __linux
// system("lsb_release -sd");
FILE* f = fopen("/etc/lsb-release", "rt");
char dist[64] = { 0 };
if (f) {
char buf[128];
while (fgets(buf, 128, f) != 0)
if (sscanf(buf, "DISTRIB_DESCRIPTION=%64c", dist) == 1)
break;
if (dist[0]) {
std::vector<std::string> strBits = split(dist, '"');
a_info.m_osType = strBits[(strBits.size()==3)?1:0];
} else {
a_info.m_osType = "non-specific LSB";
}
fclose(f);
} else {
a_info.m_osType = "non-LSB";
}
# else
a_info.m_osType = "Generic UNIX";
# endif
#endif
// TODO: improve the CPU detection using libcpuid
// Make human readable RAM size string
const char* humanUnitStrings[] = { " bytes", " KB", " MB", " GB", " TB" };
int ramUnit = 0;
uint64_t ramSize = a_info.m_ramSize;
while (ramSize > 1024 && ramUnit < (YQ_ARRAY_SIZE(humanUnitStrings)-1))
ramUnit++, ramSize /= 1000;
a_info.m_ramSizeStr = std::to_string(ramSize) + humanUnitStrings[ramUnit];
// Obtain the screen properties
QScreen *s = QApplication::screens()[0];
int refreshRate = (s) ? s->refreshRate() : 0;
int depth = (s) ? s->depth() : 0;
a_info.m_resolutionWidth = (s) ? s->geometry().width() : 0;
a_info.m_resolutionHeight = (s) ? s->geometry().height() : 0;
a_info.m_resolutionStr = std::to_string(a_info.m_resolutionWidth) + "x"
+ std::to_string(a_info.m_resolutionHeight) + " "
+ std::to_string(depth) + "bit "
+ "@" + std::to_string(refreshRate) + "Hz";
;
}