mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Merge pull request #338 from CarterLi/dev
Improve performance and various fixes
This commit is contained in:
+39
-15
@@ -66,7 +66,8 @@ cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32"
|
||||
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN32" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND AND NOT ANDROID" OFF)
|
||||
cmake_dependent_option(USE_WIN_FAST_PPID_DETECTION "Use internal NTAPI instead of querying WMI to get PPID" ON "WIN32" OFF)
|
||||
cmake_dependent_option(USE_WIN_NTAPI "Allow using internal NTAPI" ON "WIN32" OFF)
|
||||
cmake_dependent_option(USE_WIN_GPU_DXGI "Use DXGI to detect GPUs instead of WMI. Faster, but may ignore GPUs that only support DX9" ON "WIN32" OFF)
|
||||
|
||||
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
||||
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
|
||||
@@ -300,6 +301,7 @@ if(LINUX)
|
||||
src/detection/board/board_linux.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
@@ -335,12 +337,12 @@ elseif(ANDROID)
|
||||
src/detection/bios/bios_nosupport.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/displayserver/displayserver_nosupport.c
|
||||
src/detection/font/font_nosupport.c
|
||||
src/detection/gpu/gpu_nosupport.c
|
||||
src/detection/gtk.c
|
||||
src/detection/host/host_android.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/media/media_nosupport.c
|
||||
@@ -350,7 +352,6 @@ elseif(ANDROID)
|
||||
src/detection/packages/packages_linux.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_linux.c
|
||||
src/detection/qt.c
|
||||
src/detection/swap/swap_linux.c
|
||||
src/detection/temps/temps_linux.c
|
||||
src/detection/terminalfont/terminalfont_android.c
|
||||
@@ -369,19 +370,33 @@ elseif(BSD)
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/cpuUsage/cpuUsage_bsd.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/font/font_linux.c
|
||||
src/detection/gpu/gpu_linux.c
|
||||
src/detection/gtk.c
|
||||
src/detection/host/host_bsd.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_bsd.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_linux.c
|
||||
src/detection/packages/packages_linux.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_bsd.c
|
||||
src/detection/qt.c
|
||||
src/detection/swap/swap_bsd.c
|
||||
src/detection/temps/temps_linux.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/uptime/uptime_bsd.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -393,6 +408,7 @@ elseif(APPLE)
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/cpuUsage/cpuUsage_apple.c
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/disk/disk_apple.m
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
@@ -421,33 +437,35 @@ elseif(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/networking_windows.c
|
||||
src/common/processing_windows.c
|
||||
src/detection/battery/battery_windows.cpp
|
||||
src/detection/bios/bios_windows.cpp
|
||||
src/detection/board/board_windows.cpp
|
||||
src/detection/cpu/cpu_windows.cpp
|
||||
src/detection/cpuUsage/cpuUsage_nowait_windows.cpp
|
||||
src/detection/battery/battery_windows.c
|
||||
src/detection/bios/bios_windows.c
|
||||
src/detection/board/board_windows.c
|
||||
src/detection/cpu/cpu_windows.c
|
||||
src/detection/cpuUsage/cpuUsage_windows.c
|
||||
src/detection/cursor/cursor_windows.c
|
||||
src/detection/disk/disk_windows.c
|
||||
src/detection/displayserver/displayserver_windows.c
|
||||
src/detection/font/font_windows.cpp
|
||||
src/detection/font/font_windows.c
|
||||
src/detection/gpu/gpu_windows.cpp
|
||||
src/detection/host/host_windows.cpp
|
||||
src/detection/host/host_windows.c
|
||||
src/detection/localip/localip_windows.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/memory/memory_windows.cpp
|
||||
src/detection/memory/memory_windows.c
|
||||
src/detection/opengl/opengl_windows.c
|
||||
src/detection/os/os_windows.cpp
|
||||
src/detection/packages/packages_windows.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_windows.cpp
|
||||
src/detection/swap/swap_windows.cpp
|
||||
src/detection/swap/swap_windows.c
|
||||
src/detection/terminalfont/terminalfont_windows.c
|
||||
src/detection/terminalshell/terminalshell_windows.cpp
|
||||
src/detection/uptime/uptime_windows.c
|
||||
src/detection/users/users_windows.cpp
|
||||
src/detection/users/users_windows.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/util/windows/getline.c
|
||||
src/util/windows/pwd.c
|
||||
src/util/windows/register.c
|
||||
src/util/windows/unicode.c
|
||||
src/util/windows/utsname.c
|
||||
src/util/windows/wmi.cpp
|
||||
)
|
||||
@@ -545,9 +563,15 @@ elseif(WIN32)
|
||||
PRIVATE "ws2_32"
|
||||
PRIVATE "ntdll"
|
||||
PRIVATE "version"
|
||||
PRIVATE "setupapi"
|
||||
PRIVATE "dxgi"
|
||||
PRIVATE "wtsapi32"
|
||||
)
|
||||
if(USE_WIN_FAST_PPID_DETECTION)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_FAST_PPID_DETECTION)
|
||||
if(USE_WIN_NTAPI)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI)
|
||||
endif()
|
||||
if(USE_WIN_GPU_DXGI)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_GPU_DXGI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "battery.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <setupapi.h>
|
||||
#include <batclass.h>
|
||||
#include <devguid.h>
|
||||
|
||||
static inline void wrapCloseHandle(HANDLE* handle)
|
||||
{
|
||||
if(*handle)
|
||||
CloseHandle(*handle);
|
||||
}
|
||||
static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
||||
{
|
||||
if(*hdev)
|
||||
SetupDiDestroyDeviceInfoList(*hdev);
|
||||
}
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
|
||||
HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) =
|
||||
SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if(hdev == INVALID_HANDLE_VALUE)
|
||||
return "SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY) failed";
|
||||
|
||||
for(DWORD idev = 0;; idev++)
|
||||
{
|
||||
SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) };
|
||||
if(!SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did))
|
||||
break;
|
||||
|
||||
DWORD cbRequired = 0;
|
||||
SetupDiGetDeviceInterfaceDetailW(hdev, &did, NULL, 0, &cbRequired, NULL); //Fail with not enough buffer
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA_W* FF_AUTO_FREE pdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(cbRequired);
|
||||
if(!pdidd)
|
||||
break; //Out of memory
|
||||
|
||||
pdidd->cbSize = sizeof(*pdidd);
|
||||
if(!SetupDiGetDeviceInterfaceDetailW(hdev, &did, pdidd, cbRequired, &cbRequired, NULL))
|
||||
continue;
|
||||
|
||||
HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hBattery =
|
||||
CreateFileW(pdidd->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if(hBattery == INVALID_HANDLE_VALUE)
|
||||
continue;
|
||||
|
||||
BATTERY_QUERY_INFORMATION bqi = { .InformationLevel = BatteryInformation };
|
||||
|
||||
DWORD dwWait = 0;
|
||||
DWORD dwOut;
|
||||
|
||||
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag, sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag)
|
||||
continue;
|
||||
|
||||
BATTERY_INFORMATION bi = {0};
|
||||
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi, sizeof(bi), &dwOut, NULL))
|
||||
continue;
|
||||
|
||||
if(!(bi.Capabilities & BATTERY_SYSTEM_BATTERY))
|
||||
continue;
|
||||
|
||||
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
|
||||
|
||||
if(memcmp(bi.Chemistry, "PbAc", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Lead Acid");
|
||||
else if(memcmp(bi.Chemistry, "LION", 4) == 0 || memcmp(bi.Chemistry, "Li-I", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Lithium Ion");
|
||||
else if(memcmp(bi.Chemistry, "NiCd", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Nickel Cadmium");
|
||||
else if(memcmp(bi.Chemistry, "NiMH", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Nickel Metal Hydride");
|
||||
else if(memcmp(bi.Chemistry, "NiZn", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Nickel Zinc");
|
||||
else if(memcmp(bi.Chemistry, "RAM\0", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Rechargeable Alkaline-Manganese");
|
||||
else
|
||||
ffStrbufInitS(&battery->technology, "Unknown");
|
||||
|
||||
{
|
||||
ffStrbufInit(&battery->modelName);
|
||||
bqi.InformationLevel = BatteryDeviceName;
|
||||
wchar_t name[64];
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
||||
ffWcharToUtf8(name, &battery->modelName);
|
||||
}
|
||||
|
||||
{
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
bqi.InformationLevel = BatteryManufactureName;
|
||||
wchar_t name[64];
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
||||
ffWcharToUtf8(name, &battery->manufacturer);
|
||||
}
|
||||
|
||||
battery->temperature = 0.0/0.0;
|
||||
if(instance->config.batteryTemp)
|
||||
{
|
||||
bqi.InformationLevel = BatteryTemperature;
|
||||
ULONG temp;
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &temp, sizeof(temp), &dwOut, NULL))
|
||||
battery->temperature = temp;
|
||||
}
|
||||
|
||||
{
|
||||
BATTERY_STATUS bs;
|
||||
BATTERY_WAIT_STATUS bws = { .BatteryTag = bqi.BatteryTag };
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws), &bs, sizeof(bs), &dwOut, NULL) && bs.Capacity != BATTERY_UNKNOWN_CAPACITY)
|
||||
battery->capacity = bs.Capacity * 100.0 / bi.FullChargedCapacity;
|
||||
else
|
||||
battery->capacity = 0;
|
||||
|
||||
ffStrbufInit(&battery->status);
|
||||
if(bs.PowerState & BATTERY_POWER_ON_LINE)
|
||||
ffStrbufAppendS(&battery->status, "AC Connected, ");
|
||||
if(bs.PowerState & BATTERY_DISCHARGING)
|
||||
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||
if(bs.PowerState & BATTERY_CRITICAL)
|
||||
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||
if(bs.PowerState & BATTERY_CHARGING)
|
||||
ffStrbufAppendS(&battery->status, "Charging");
|
||||
ffStrbufTrimRight(&battery->status, ' ');
|
||||
ffStrbufTrimRight(&battery->status, ',');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
extern "C" {
|
||||
#include "battery.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery
|
||||
FFWmiQuery query(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery");
|
||||
|
||||
if(!query)
|
||||
return "Query WMI service failed";
|
||||
|
||||
while(FFWmiRecord record = query.next())
|
||||
{
|
||||
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
|
||||
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
record.getString(L"SystemName", &battery->manufacturer);
|
||||
|
||||
ffStrbufInit(&battery->modelName);
|
||||
record.getString(L"Name", &battery->modelName);
|
||||
|
||||
uint64_t chemistry = 0;
|
||||
record.getUnsigned(L"Chemistry", &chemistry);
|
||||
switch(chemistry)
|
||||
{
|
||||
case 1: ffStrbufInitS(&battery->technology, "Other"); break;
|
||||
case 2: ffStrbufInitS(&battery->technology, "Unknown"); break;
|
||||
case 3: ffStrbufInitS(&battery->technology, "Lead Acid"); break;
|
||||
case 4: ffStrbufInitS(&battery->technology, "Nickel Cadmium"); break;
|
||||
case 5: ffStrbufInitS(&battery->technology, "Nickel Metal Hydride"); break;
|
||||
case 6: ffStrbufInitS(&battery->technology, "Lithium-ion"); break;
|
||||
case 7: ffStrbufInitS(&battery->technology, "Zinc air"); break;
|
||||
case 8: ffStrbufInitS(&battery->technology, "Lithium Polymer"); break;
|
||||
default: ffStrbufInit(&battery->technology); break;
|
||||
}
|
||||
|
||||
record.getReal(L"EstimatedChargeRemaining", &battery->capacity);
|
||||
|
||||
uint64_t batteryStatus;
|
||||
record.getUnsigned(L"BatteryStatus", &batteryStatus);
|
||||
switch(batteryStatus)
|
||||
{
|
||||
case 1: ffStrbufInitS(&battery->status, "Discharging"); break;
|
||||
case 2: ffStrbufInitS(&battery->status, "AC Connected"); break;
|
||||
case 3: ffStrbufInitS(&battery->status, "Fully Charged"); break;
|
||||
case 4: ffStrbufInitS(&battery->status, "Low"); break;
|
||||
case 5: ffStrbufInitS(&battery->status, "Critical"); break;
|
||||
case 6: ffStrbufInitS(&battery->status, "Charging"); break;
|
||||
case 7: ffStrbufInitS(&battery->status, "Charging and High"); break;
|
||||
case 8: ffStrbufInitS(&battery->status, "Charging and Low"); break;
|
||||
case 9: ffStrbufInitS(&battery->status, "Charging and Critical"); break;
|
||||
case 10: ffStrbufInitS(&battery->status, "Undefined"); break;
|
||||
case 11: ffStrbufInitS(&battery->status, "Partially Charged"); break;
|
||||
default: ffStrbufInit(&battery->status); break;
|
||||
}
|
||||
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "bios.h"
|
||||
#include "util/windows/register.h"
|
||||
|
||||
void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInit(&bios->error);
|
||||
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error))
|
||||
return;
|
||||
|
||||
if(!ffRegReadStrbuf(hKey, L"BIOSVersion", &bios->biosRelease, &bios->error))
|
||||
return;
|
||||
ffRegReadStrbuf(hKey, L"BIOSVendor", &bios->biosVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BIOSReleaseDate", &bios->biosDate, NULL);
|
||||
|
||||
uint32_t major, minor;
|
||||
if(
|
||||
ffRegReadUint(hKey, L"BiosMajorRelease", &major, NULL) &&
|
||||
ffRegReadUint(hKey, L"BiosMinorRelease", &minor, NULL)
|
||||
)
|
||||
ffStrbufAppendF(&bios->biosVersion, "%u.%u", (unsigned)major, (unsigned)minor);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
extern "C" {
|
||||
#include "bios.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInit(&bios->error);
|
||||
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
|
||||
FFWmiQuery query(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error);
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
record.getString(L"Name", &bios->biosRelease);
|
||||
record.getString(L"ReleaseDate", &bios->biosDate);
|
||||
record.getString(L"Version", &bios->biosVersion);
|
||||
record.getString(L"Manufacturer", &bios->biosVendor);
|
||||
}
|
||||
else
|
||||
ffStrbufInitS(&bios->error, "No Wmi result returned");
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "board.h"
|
||||
#include "util/windows/register.h"
|
||||
|
||||
void ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
ffStrbufInit(&board->error);
|
||||
|
||||
ffStrbufInit(&board->boardName);
|
||||
ffStrbufInit(&board->boardVendor);
|
||||
ffStrbufInit(&board->boardVersion);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error))
|
||||
return;
|
||||
|
||||
if(!ffRegReadStrbuf(hKey, L"BaseBoardProduct", &board->boardName, &board->error))
|
||||
return;
|
||||
ffRegReadStrbuf(hKey, L"BaseBoardManufacturer", &board->boardVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BaseBoardVersion", &board->boardVersion, NULL);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
extern "C" {
|
||||
#include "board.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" void ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
ffStrbufInit(&board->error);
|
||||
|
||||
ffStrbufInit(&board->boardName);
|
||||
ffStrbufInit(&board->boardVendor);
|
||||
ffStrbufInit(&board->boardVersion);
|
||||
|
||||
FFWmiQuery query(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error);
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
record.getString(L"Product", &board->boardName);
|
||||
record.getString(L"Manufacturer", &board->boardVendor);
|
||||
record.getString(L"Version", &board->boardVersion);
|
||||
}
|
||||
else
|
||||
ffStrbufInitS(&board->error, "No Wmi result returned");
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "cpu.h"
|
||||
#include "util/windows/register.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
cpu->coresPhysical = cpu->coresLogical = cpu->coresOnline = 0;
|
||||
cpu->frequencyMax = cpu->frequencyMin = 0;
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
|
||||
{
|
||||
DWORD length = 0;
|
||||
GetLogicalProcessorInformationEx(RelationProcessorCore, NULL, &length);
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE
|
||||
pLogicalInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length);
|
||||
|
||||
if(pLogicalInfo && GetLogicalProcessorInformationEx(RelationProcessorCore, pLogicalInfo, &length))
|
||||
{
|
||||
for(
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pLogicalInfo;
|
||||
(uint8_t*)ptr < ((uint8_t*)pLogicalInfo) + length;
|
||||
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
|
||||
)
|
||||
{
|
||||
if(ptr->Relationship == RelationProcessorCore)
|
||||
++cpu->coresPhysical;
|
||||
}
|
||||
}
|
||||
}
|
||||
cpu->coresOnline = (uint16_t)GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||
cpu->coresLogical = (uint16_t)GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey;
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL))
|
||||
return;
|
||||
|
||||
{
|
||||
uint32_t mhz;
|
||||
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
|
||||
cpu->frequencyMax = mhz / 1000.0;
|
||||
}
|
||||
|
||||
ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL);
|
||||
ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
extern "C" {
|
||||
#include "cpu.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C"
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
cpu->coresPhysical = cpu->coresLogical = cpu->coresOnline = 0;
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
|
||||
FFWmiQuery query(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, NumberOfEnabledCore, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3");
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
FFWmiRecord record = query.next();
|
||||
if(!record)
|
||||
{
|
||||
//NumberOfEnabledCore is not supported on Windows 10-
|
||||
query = FFWmiQuery(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3");
|
||||
if(!query)
|
||||
return;
|
||||
record = query.next();
|
||||
}
|
||||
|
||||
if(record)
|
||||
{
|
||||
record.getString(L"Name", &cpu->name);
|
||||
record.getString(L"Manufacturer", &cpu->vendor);
|
||||
|
||||
uint64_t value;
|
||||
|
||||
record.getUnsigned(L"NumberOfCores", &value);
|
||||
cpu->coresPhysical = (uint16_t)value;
|
||||
record.getUnsigned(L"NumberOfLogicalProcessors", &value);
|
||||
cpu->coresLogical = (uint16_t)value;
|
||||
cpu->coresOnline = record.getUnsigned(L"NumberOfEnabledCore", &value) ? (uint16_t)value : cpu->coresPhysical;
|
||||
record.getUnsigned(L"CurrentClockSpeed", &value); //There's no MinClockSpeed in Win32_Processor
|
||||
cpu->frequencyMin = (double)value / 1000.0;
|
||||
record.getUnsigned(L"MaxClockSpeed", &value);
|
||||
cpu->frequencyMax = (double)value / 1000.0;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#if FF_DETECTION_CPUUSAGE_NOWAIT
|
||||
|
||||
const char* ffGetCpuUsageResultNoWait(double* result);
|
||||
|
||||
void ffPrepareCPUUsage() {}
|
||||
|
||||
const char* ffGetCpuUsageResult(double* result) {
|
||||
return ffGetCpuUsageResultNoWait(result);
|
||||
}
|
||||
|
||||
#else //FF_DETECTION_CPUUSAGE_NOWAIT
|
||||
|
||||
#include "common/time.h"
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -61,5 +49,3 @@ const char* ffGetCpuUsageResult(double* result)
|
||||
ffTimeSleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FF_DETECTION_CPUUSAGE_NOWAIT
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
#ifndef FF_INCLUDED_detection_cpu_cpuUsage
|
||||
#define FF_INCLUDED_detection_cpu_cpuUsage
|
||||
|
||||
#ifdef _WIN32
|
||||
// Disabled by default because the result does need some time to generate
|
||||
#define FF_DETECTION_CPUUSAGE_NOWAIT 0
|
||||
#endif
|
||||
|
||||
const char* ffGetCpuUsageResult(double* result);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
extern "C" {
|
||||
#include "cpuUsage.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" const char* ffGetCpuUsageResultNoWait(double* result)
|
||||
{
|
||||
FFWmiQuery query(L"SELECT LoadPercentage FROM Win32_Processor");
|
||||
if(!query)
|
||||
return "Query WMI service failed";
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
record.getReal(L"LoadPercentage", result);
|
||||
else
|
||||
return "No WMI result returned";
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_cursor_cursor
|
||||
#define FF_INCLUDED_detection_cursor_cursor
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFCursorResult
|
||||
{
|
||||
FFstrbuf theme;
|
||||
FFstrbuf size;
|
||||
FFstrbuf error;
|
||||
} FFCursorResult;
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "cursor.h"
|
||||
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/settings.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void detectCursorGTK(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
const FFGTKResult* gtk = ffDetectGTK4(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
gtk = ffDetectGTK3(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
gtk = ffDetectGTK2(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->error, "Couldn't detect GTK Cursor");
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufAppend(&result->theme, >k->cursor);
|
||||
ffStrbufAppend(&result->size, >k->cursorSize);
|
||||
}
|
||||
|
||||
static void detectCursorXFCE(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
ffStrbufAppendS(&result->theme, ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue);
|
||||
|
||||
if(result->theme.length == 0)
|
||||
ffStrbufAppendS(&result->error, "Couldn't find xfce cursor in xfconf (xsettings::/Gtk/CursorThemeName)");
|
||||
|
||||
int cursorSizeVal = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue;
|
||||
if(cursorSizeVal > 0)
|
||||
ffStrbufAppendF(&result->size, "%i", cursorSizeVal);
|
||||
}
|
||||
|
||||
static void detectCursorFromConfigFile(const FFinstance* instance, const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault, FFCursorResult* result)
|
||||
{
|
||||
if(ffParsePropFileConfigValues(instance, relativeFilePath, 2, (FFpropquery[]) {
|
||||
{themeStart, &result->theme},
|
||||
{sizeStart, &result->size}
|
||||
})) {
|
||||
|
||||
if(result->theme.length == 0)
|
||||
ffStrbufAppendS(&result->theme, themeDefault);
|
||||
|
||||
if(result->size.length == 0)
|
||||
ffStrbufAppendS(&result->size, sizeDefault);
|
||||
}
|
||||
|
||||
if(result->theme.length == 0)
|
||||
ffStrbufAppendF(&result->error, "Couldn't find cursor in %s", relativeFilePath);
|
||||
}
|
||||
|
||||
static bool detectCursorFromXResources(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
ffParsePropFileHomeValues(instance, ".Xresources", 2, (FFpropquery[]) {
|
||||
{"Xcursor.theme :", &result->theme},
|
||||
{"Xcursor.size :", &result->size}
|
||||
});
|
||||
|
||||
return result->theme.length > 0;
|
||||
}
|
||||
|
||||
static bool detectCursorFromXDG(const FFinstance* instance, bool user, FFCursorResult* result)
|
||||
{
|
||||
if(user)
|
||||
ffParsePropFileHome(instance, ".icons/default/index.theme", "Inherits =", &result->theme);
|
||||
else
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/icons/default/index.theme", "Inherits =", &result->theme);
|
||||
|
||||
return result->theme.length > 0;
|
||||
}
|
||||
|
||||
static bool detectCursorFromEnv(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
const char* xcursor_theme = getenv("XCURSOR_THEME");
|
||||
|
||||
if(!ffStrSet(xcursor_theme))
|
||||
return false;
|
||||
|
||||
ffStrbufAppendS(&result->theme, xcursor_theme);
|
||||
ffStrbufAppendS(&result->size, getenv("XCURSOR_SIZE"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
|
||||
|
||||
if(ffStrbufCompS(&wmde->wmPrettyName, "WSLg") == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->error, "WSLg uses native windows cursor");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, "TTY") == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->error, "Cursor isn't supported in TTY");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "KDE Plasma") == 0)
|
||||
return detectCursorFromConfigFile(instance, "kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result);
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "XFCE"))
|
||||
return detectCursorXFCE(instance, result);
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "LXQt"))
|
||||
return detectCursorFromConfigFile(instance, "lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Gnome") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0)
|
||||
return detectCursorGTK(instance, result);
|
||||
|
||||
if(
|
||||
detectCursorFromEnv(instance, result) ||
|
||||
detectCursorFromXDG(instance, true, result) ||
|
||||
detectCursorFromXResources(instance, result) ||
|
||||
detectCursorFromXDG(instance, false, result)
|
||||
) return;
|
||||
|
||||
detectCursorGTK(instance, result);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "cursor.h"
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
ffStrbufInitS(&result->error, "Not supported on this platform");
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "cursor.h"
|
||||
|
||||
#include "util/windows/register.h"
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey;
|
||||
if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Cursors", &hKey, &result->error))
|
||||
ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error);
|
||||
}
|
||||
@@ -14,7 +14,7 @@ typedef struct FFFontResult
|
||||
/**
|
||||
* Linux / BSD: QT, GTK2, GTK3, GTK4
|
||||
* MacOS: System, User, System Mono, User Mono
|
||||
* Windows: Desktop, Unset, Unset, Unset
|
||||
* Windows: Caption, Menu, Message, Status
|
||||
* Other: Unset, Unset, Unset, Unset
|
||||
*/
|
||||
FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS];
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "font.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <winuser.h>
|
||||
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
NONCLIENTMETRICSW info = { .cbSize = sizeof(info) };
|
||||
if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0))
|
||||
ffStrbufAppendS(&result->error, "SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed");
|
||||
|
||||
LOGFONTW* fonts[4] = { &info.lfCaptionFont, &info.lfMenuFont, &info.lfMessageFont, &info.lfStatusFont };
|
||||
|
||||
for(uint32_t i = 0; i < sizeof(fonts) / sizeof(fonts[0]); ++i)
|
||||
{
|
||||
ffWcharToUtf8(fonts[i]->lfFaceName, &result->fonts[i]);
|
||||
if(fonts[i]->lfHeight < 0)
|
||||
ffStrbufAppendF(&result->fonts[i], " (%dpt)", (int)-fonts[i]->lfHeight);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
extern "C" {
|
||||
#include "font.h"
|
||||
#include "common/font.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
extern "C"
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
wchar_t sql[256] = {};
|
||||
swprintf(sql, 256, L"SELECT IconTitleFaceName, IconTitleSize FROM Win32_Desktop WHERE Name LIKE '%%\\\\%s'", instance->state.passwd->pw_name);
|
||||
|
||||
FFWmiQuery query(sql, &result->error);
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
record.getString(L"IconTitleFaceName", &fontName);
|
||||
|
||||
uint64_t fontSize;
|
||||
record.getUnsigned(L"IconTitleSize", &fontSize);
|
||||
|
||||
ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize);
|
||||
}
|
||||
else
|
||||
ffStrbufInitS(&result->error, "No WMI result returned");
|
||||
}
|
||||
@@ -8,6 +8,10 @@
|
||||
#define FF_GPU_TEMP_UNSET (0/0.0)
|
||||
#define FF_GPU_CORE_COUNT_UNSET -1
|
||||
|
||||
#define FF_GPU_VENDOR_NAME_AMD "AMD"
|
||||
#define FF_GPU_VENDOR_NAME_INTEL "Intel"
|
||||
#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA"
|
||||
|
||||
typedef struct FFGPUResult
|
||||
{
|
||||
FFstrbuf vendor;
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#include "gpu.h"
|
||||
#include "detection/vulkan.h"
|
||||
|
||||
#define FF_GPU_VENDOR_NAME_AMD "AMD"
|
||||
#define FF_GPU_VENDOR_NAME_INTEL "Intel"
|
||||
#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA"
|
||||
|
||||
#ifdef FF_HAVE_LIBPCI
|
||||
#include "common/library.h"
|
||||
#include "common/properties.h"
|
||||
|
||||
@@ -1,13 +1,62 @@
|
||||
extern "C" {
|
||||
#include "gpu.h"
|
||||
#include "util/windows/unicode.h"
|
||||
}
|
||||
|
||||
#ifdef FF_USE_WIN_GPU_DXGI
|
||||
|
||||
#include <dxgi.h>
|
||||
#include <wchar.h>
|
||||
|
||||
static const char* detectWithDxgi(FFlist* gpus)
|
||||
{
|
||||
IDXGIFactory1* pFactory;
|
||||
if(FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory))))
|
||||
return "CreateDXGIFactory1() failed";
|
||||
|
||||
for(unsigned iAdapter = 0;; ++iAdapter)
|
||||
{
|
||||
IDXGIAdapter1* adapter;
|
||||
if(FAILED(pFactory->EnumAdapters1(iAdapter, &adapter)))
|
||||
break;
|
||||
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
if(FAILED(adapter->GetDesc1(&desc)) || (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE))
|
||||
continue;
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
|
||||
if(wmemchr((const wchar_t[]) {0x1002, 0x1022}, (wchar_t)desc.VendorId, 2))
|
||||
ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||
else if(wmemchr((const wchar_t[]) {0x03e7, 0x8086, 0x8087}, (wchar_t)desc.VendorId, 3))
|
||||
ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||
else if(wmemchr((const wchar_t[]) {0x0955, 0x10de, 0x12d2}, (wchar_t)desc.VendorId, 3))
|
||||
ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||
else
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffWcharToUtf8(desc.Description, &gpu->name);
|
||||
|
||||
ffStrbufInit(&gpu->driver);
|
||||
|
||||
adapter->Release();
|
||||
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
}
|
||||
|
||||
pFactory->Release();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
static const char* detectWithWmi(FFlist* gpus)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
FFWmiQuery query(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr);
|
||||
if(!query)
|
||||
return "Query WMI service failed";
|
||||
@@ -36,3 +85,17 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
#ifdef FF_USE_WIN_GPU_DXGI
|
||||
return detectWithDxgi(gpus);
|
||||
#else
|
||||
return detectWithWmi(gpus);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "host.h"
|
||||
#include "util/windows/register.h"
|
||||
|
||||
void ffDetectHostImpl(FFHostResult* host)
|
||||
{
|
||||
ffStrbufInit(&host->error);
|
||||
|
||||
ffStrbufInit(&host->productName);
|
||||
ffStrbufInit(&host->productFamily);
|
||||
ffStrbufInit(&host->productVersion);
|
||||
ffStrbufInit(&host->productSku);
|
||||
ffStrbufInit(&host->sysVendor);
|
||||
ffStrbufInit(&host->chassisType);
|
||||
ffStrbufInit(&host->chassisVendor);
|
||||
ffStrbufInit(&host->chassisVersion);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error))
|
||||
return;
|
||||
|
||||
ffRegReadStrbuf(hKey, L"SystemProductName", &host->productName, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemFamily", &host->productFamily, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemVersion", &host->productVersion, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemSKU", &host->productSku, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemManufacturer", &host->sysVendor, NULL);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
extern "C" {
|
||||
#include "host.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" void ffDetectHostImpl(FFHostResult* host)
|
||||
{
|
||||
ffStrbufInit(&host->error);
|
||||
|
||||
ffStrbufInit(&host->productName);
|
||||
ffStrbufInit(&host->productFamily);
|
||||
ffStrbufInit(&host->productVersion);
|
||||
ffStrbufInit(&host->productSku);
|
||||
ffStrbufInit(&host->sysVendor);
|
||||
ffStrbufInit(&host->chassisType);
|
||||
ffStrbufInit(&host->chassisVendor);
|
||||
ffStrbufInit(&host->chassisVersion);
|
||||
|
||||
FFWmiQuery query(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error);
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
record.getString(L"Name", &host->productName);
|
||||
record.getString(L"Version", &host->productVersion);
|
||||
record.getString(L"SKUNumber", &host->productSku);
|
||||
record.getString(L"Vendor", &host->sysVendor);
|
||||
}
|
||||
else
|
||||
ffStrbufAppendS(&host->error, "No Wmi result returned");
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "memory.h"
|
||||
|
||||
void ffDetectMemoryImpl(FFMemoryStorage* ram)
|
||||
{
|
||||
MEMORYSTATUSEX statex = {
|
||||
.dwLength = sizeof(statex),
|
||||
};
|
||||
GlobalMemoryStatusEx(&statex);
|
||||
ram->bytesTotal = statex.ullTotalPhys;
|
||||
ram->bytesUsed = statex.ullTotalPhys - statex.ullAvailPhys;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
extern "C" {
|
||||
#include "memory.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C"
|
||||
void ffDetectMemoryImpl(FFMemoryStorage* ram)
|
||||
{
|
||||
FFWmiQuery query(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error);
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
//KB
|
||||
record.getUnsigned(L"TotalVisibleMemorySize", &ram->bytesTotal);
|
||||
uint64_t bytesFree;
|
||||
record.getUnsigned(L"FreePhysicalMemory", &bytesFree);
|
||||
ram->bytesUsed = ram->bytesTotal - bytesFree;
|
||||
ram->bytesTotal *= 1024;
|
||||
ram->bytesUsed *= 1024;
|
||||
}
|
||||
else
|
||||
ffStrbufInitS(&ram->error, "No Wmi result returned");
|
||||
}
|
||||
@@ -1,8 +1,49 @@
|
||||
extern "C" {
|
||||
#include "os.h"
|
||||
#include "util/windows/unicode.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
static const char* getOsNameByWmi(FFstrbuf* osName)
|
||||
{
|
||||
FFWmiQuery query(L"SELECT Caption FROM Win32_OperatingSystem");
|
||||
if(!query)
|
||||
return "Query WMI service failed";
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
record.getString(L"Caption", osName);
|
||||
ffStrbufTrimRight(osName, ' ');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return "No WMI result returned";
|
||||
}
|
||||
|
||||
static inline void wrapFreeLibrary(HMODULE* module)
|
||||
{
|
||||
if(*module)
|
||||
FreeLibrary(*module);
|
||||
}
|
||||
|
||||
static const char* getOsNameByWinbrand(FFstrbuf* osName)
|
||||
{
|
||||
//https://dennisbabkin.com/blog/?t=how-to-tell-the-real-version-of-windows-your-app-is-running-on#ver_string
|
||||
if(HMODULE __attribute__((__cleanup__(wrapFreeLibrary))) hWinbrand = LoadLibraryW(L"winbrand.dll"))
|
||||
{
|
||||
PWSTR(WINAPI* BrandingFormatString)(PCWSTR);
|
||||
(FARPROC&)BrandingFormatString = GetProcAddress(hWinbrand, "BrandingFormatString");
|
||||
if(!BrandingFormatString)
|
||||
return "GetProcAddress(BrandingFormatString) failed";
|
||||
|
||||
const wchar_t* rawName = BrandingFormatString(L"%WINDOWS_LONG%");
|
||||
ffWcharToUtf8(rawName, osName);
|
||||
GlobalFree((HGLOBAL)rawName);
|
||||
return NULL;
|
||||
}
|
||||
return "LoadLibraryW(winbrand.dll) failed";
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
|
||||
{
|
||||
@@ -19,56 +60,54 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
|
||||
ffStrbufInit(&os->systemName);
|
||||
ffStrbufInit(&os->architecture);
|
||||
|
||||
FFWmiQuery query(L"SELECT Caption, Version, BuildNumber, OSArchitecture FROM Win32_OperatingSystem");
|
||||
if(!query)
|
||||
if(getOsNameByWinbrand(&os->variant) && getOsNameByWmi(&os->variant))
|
||||
return;
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
ffStrbufTrimRight(&os->variant, ' ');
|
||||
|
||||
//WMI returns the "Microsoft" prefix while BrandingFormatString doesn't. Make them consistant.
|
||||
if(ffStrbufStartsWithS(&os->variant, "Microsoft "))
|
||||
ffStrbufSubstrAfter(&os->variant, strlen("Microsoft ") - 1);
|
||||
|
||||
if(ffStrbufStartsWithS(&os->variant, "Windows "))
|
||||
{
|
||||
record.getString(L"Caption", &os->variant);
|
||||
ffStrbufTrimRight(&os->variant, ' ');
|
||||
if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows "))
|
||||
ffStrbufAppendS(&os->name, "Windows");
|
||||
ffStrbufAppendS(&os->prettyName, "Windows");
|
||||
|
||||
ffStrbufSubstrAfter(&os->variant, strlen("Windows ") - 1);
|
||||
|
||||
if(ffStrbufStartsWithS(&os->variant, "Server "))
|
||||
{
|
||||
ffStrbufAppendS(&os->name, "Microsoft Windows");
|
||||
ffStrbufAppendS(&os->prettyName, "Windows");
|
||||
|
||||
ffStrbufSubstrAfter(&os->variant, strlen("Microsoft Windows ") - 1);
|
||||
|
||||
if(ffStrbufStartsWithS(&os->variant, "Server "))
|
||||
{
|
||||
ffStrbufAppendS(&os->name, " Server");
|
||||
ffStrbufAppendS(&os->prettyName, " Server");
|
||||
ffStrbufSubstrAfter(&os->variant, strlen(" Server") - 1);
|
||||
}
|
||||
|
||||
uint32_t index = ffStrbufFirstIndexC(&os->variant, ' ');
|
||||
ffStrbufAppendNS(&os->version, index, os->variant.chars);
|
||||
ffStrbufSubstrAfter(&os->variant, index);
|
||||
|
||||
// Windows Server 20xx Rx
|
||||
if(ffStrbufEndsWithC(&os->prettyName, 'r'))
|
||||
{
|
||||
if(os->variant.chars[0] == 'R' &&
|
||||
isdigit(os->variant.chars[1]) &&
|
||||
(os->variant.chars[2] == '\0' || os->variant.chars[2] == ' '))
|
||||
{
|
||||
ffStrbufAppendF(&os->version, " R%c", os->variant.chars[1]);
|
||||
ffStrbufSubstrAfter(&os->variant, strlen("Rx ") - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown Windows name, please report this
|
||||
ffStrbufAppend(&os->name, &os->variant);
|
||||
ffStrbufClear(&os->variant);
|
||||
ffStrbufAppendS(&os->name, " Server");
|
||||
ffStrbufAppendS(&os->prettyName, " Server");
|
||||
ffStrbufSubstrAfter(&os->variant, strlen(" Server") - 1);
|
||||
}
|
||||
|
||||
ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars);
|
||||
uint32_t index = ffStrbufFirstIndexC(&os->variant, ' ');
|
||||
ffStrbufAppendNS(&os->version, index, os->variant.chars);
|
||||
ffStrbufSubstrAfter(&os->variant, index);
|
||||
|
||||
record.getString(L"BuildNumber", &os->buildID);
|
||||
record.getString(L"OSArchitecture", &os->architecture);
|
||||
|
||||
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
|
||||
// Windows Server 20xx Rx
|
||||
if(ffStrbufEndsWithC(&os->prettyName, 'r'))
|
||||
{
|
||||
if(os->variant.chars[0] == 'R' &&
|
||||
isdigit(os->variant.chars[1]) &&
|
||||
(os->variant.chars[2] == '\0' || os->variant.chars[2] == ' '))
|
||||
{
|
||||
ffStrbufAppendF(&os->version, " R%c", os->variant.chars[1]);
|
||||
ffStrbufSubstrAfter(&os->variant, strlen("Rx ") - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown Windows name, please report this
|
||||
ffStrbufAppend(&os->name, &os->variant);
|
||||
ffStrbufClear(&os->variant);
|
||||
}
|
||||
|
||||
ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars);
|
||||
|
||||
ffStrbufSetS(&os->architecture, instance->state.utsname.machine);
|
||||
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,50 @@
|
||||
extern "C" {
|
||||
#include "processes.h"
|
||||
#include "util/mallocHelper.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
#ifdef FF_USE_WIN_NTAPI
|
||||
|
||||
#include <winternl.h>
|
||||
|
||||
uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
ULONG size = 0;
|
||||
if(NtQuerySystemInformation(SystemProcessInformation, nullptr, 0, &size) != (NTSTATUS)0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/)
|
||||
{
|
||||
ffStrbufAppendS(error, "NtQuerySystemInformation(SystemProcessInformation, NULL) failed");
|
||||
return 0;
|
||||
}
|
||||
size += sizeof(SystemProcessInformation) * 5; //What if new processes are created during two syscalls?
|
||||
|
||||
SYSTEM_PROCESS_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PROCESS_INFORMATION*)malloc(size);
|
||||
if(!pstart)
|
||||
{
|
||||
ffStrbufAppendF(error, "malloc(%u) failed", (unsigned)size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessInformation, pstart, size, nullptr)))
|
||||
{
|
||||
ffStrbufAppendS(error, "NtQuerySystemInformation(SystemProcessInformation, pstart) failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t result = 1; //Init with 1 because we test for ptr->NextEntryOffset
|
||||
for (auto ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset))
|
||||
++result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error)
|
||||
{
|
||||
FFWmiQuery query(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error);
|
||||
if(!query)
|
||||
return 0;
|
||||
@@ -23,3 +61,5 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "swap.h"
|
||||
|
||||
void ffDetectSwapImpl(FFMemoryStorage* swap)
|
||||
{
|
||||
MEMORYSTATUSEX statex = {
|
||||
.dwLength = sizeof(statex),
|
||||
};
|
||||
GlobalMemoryStatusEx(&statex);
|
||||
swap->bytesTotal = statex.ullTotalPageFile;
|
||||
swap->bytesUsed = statex.ullTotalPageFile - statex.ullAvailPageFile;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
extern "C" {
|
||||
#include "swap.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C"
|
||||
void ffDetectSwapImpl(FFMemoryStorage* swap)
|
||||
{
|
||||
FFWmiQuery query(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error);
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
if(FFWmiRecord record = query.next())
|
||||
{
|
||||
//MB
|
||||
record.getUnsigned(L"AllocatedBaseSize", &swap->bytesTotal);
|
||||
record.getUnsigned(L"CurrentUsage", &swap->bytesUsed);
|
||||
swap->bytesTotal *= 1024 * 1024;
|
||||
swap->bytesUsed *= 1024 * 1024;
|
||||
}
|
||||
else
|
||||
ffStrbufInitS(&swap->error, "No Wmi result returned");
|
||||
}
|
||||
@@ -195,7 +195,7 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu
|
||||
const char* error = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(terminalExe && terminalExe->length > 0)
|
||||
if(terminalExe && terminalExe->length > 0 && !ffStrbufEqualS(terminalExe, "Windows Terminal"))
|
||||
{
|
||||
char jsonPath[MAX_PATH + 1];
|
||||
if(SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, jsonPath)))
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
#include "common/io.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
#include "terminalfont.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
#include "util/windows/register.h"
|
||||
|
||||
static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
@@ -26,47 +24,29 @@ static void detectMintty(const FFinstance* instance, FFTerminalFontResult* termi
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||
}
|
||||
|
||||
static inline void wrapRegCloseKey(HKEY* phKey)
|
||||
{
|
||||
if(*phKey)
|
||||
RegCloseKey(*phKey);
|
||||
}
|
||||
|
||||
static void detectConhost(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
//Current font of conhost doesn't seem to be detectable, we detect default font instead
|
||||
|
||||
HKEY __attribute__((__cleanup__(wrapRegCloseKey))) hKey = NULL;
|
||||
if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed");
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Console", &hKey, &terminalFont->error))
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD bufSize;
|
||||
|
||||
char fontName[128];
|
||||
bufSize = sizeof(fontName);
|
||||
if(RegGetValueA(hKey, NULL, "FaceName", RRF_RT_REG_SZ, NULL, fontName, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "RegGetValueA(FaceName) failed");
|
||||
FF_STRBUF_AUTO_DESTROY fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
if(!ffRegReadStrbuf(hKey, L"FaceName", &fontName, &terminalFont->error))
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t fontSizeNum = 0;
|
||||
bufSize = sizeof(fontSizeNum);
|
||||
if(RegGetValueW(hKey, NULL, L"FontSize", RRF_RT_DWORD, NULL, &fontSizeNum, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "RegGetValueW(FontSize) failed");
|
||||
if(!ffRegReadUint(hKey, L"FontSize", &fontSizeNum, &terminalFont->error))
|
||||
return;
|
||||
}
|
||||
|
||||
char fontSize[16];
|
||||
_ultoa((unsigned long)(fontSizeNum >> 16), fontSize, 10);
|
||||
|
||||
ffFontInitValues(&terminalFont->font, fontName, fontSize);
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize);
|
||||
}
|
||||
|
||||
static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
|
||||
@@ -4,13 +4,11 @@ extern "C" {
|
||||
#include "common/thread.h"
|
||||
}
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <processthreadsapi.h>
|
||||
#include <wchar.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#ifdef FF_USE_WIN_FAST_PPID_DETECTION
|
||||
#ifdef FF_USE_WIN_NTAPI
|
||||
|
||||
#include <winternl.h>
|
||||
|
||||
@@ -59,6 +57,7 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb
|
||||
#else
|
||||
|
||||
#include "util/windows/wmi.hpp"
|
||||
#include <inttypes.h>
|
||||
|
||||
static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName)
|
||||
{
|
||||
@@ -140,12 +139,33 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "powershell_ise"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell ISE");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "cmd"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "Command Prompt");
|
||||
{
|
||||
ffStrbufClear(&result->shellPrettyName);
|
||||
|
||||
HANDLE snapshot;
|
||||
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
|
||||
|
||||
if(snapshot)
|
||||
{
|
||||
MODULEENTRY32W module = { .dwSize = sizeof(module) };
|
||||
for(BOOL success = Module32FirstW(snapshot, &module); success; success = Module32NextW(snapshot, &module))
|
||||
{
|
||||
if(wcsncmp(module.szModule, L"clink_dll_", wcslen(L"clink_dll_")) == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->shellPrettyName, "CMD (with Clink)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
}
|
||||
if(result->shellPrettyName.length == 0)
|
||||
ffStrbufAppendS(&result->shellPrettyName, "Command Prompt");
|
||||
}
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "nu"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "nushell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer"))
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "explorer"))
|
||||
{
|
||||
ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); // Started without shell
|
||||
ffStrbufSetS(&result->shellPrettyName, "Windows Explorer"); // Started without shell
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -199,12 +219,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
{
|
||||
if(
|
||||
result->terminalProcessName.length > 0 &&
|
||||
!ffStrbufStartsWithIgnCaseS(&result->terminalProcessName, "login") &&
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "(login)") != 0 &&
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "systemd") != 0 &&
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "init") != 0 &&
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "(init)") != 0 &&
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "explorer") != 0
|
||||
) return;
|
||||
|
||||
const char* term = nullptr;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "users.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <wtsapi32.h>
|
||||
|
||||
//at the time of writing, <wtsapi32.h> of MinGW doesn't have the definition of WTSEnumerateSessionsExW
|
||||
typedef struct _WTS_SESSION_INFO_1W {
|
||||
DWORD ExecEnvId;
|
||||
WTS_CONNECTSTATE_CLASS State;
|
||||
DWORD SessionId;
|
||||
LPWSTR pSessionName;
|
||||
LPWSTR pHostName;
|
||||
LPWSTR pUserName;
|
||||
LPWSTR pDomainName;
|
||||
LPWSTR pFarmName;
|
||||
} WTS_SESSION_INFO_1W, * PWTS_SESSION_INFO_1W;
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
WTSEnumerateSessionsExW(
|
||||
HANDLE hServer,
|
||||
DWORD* pLevel,
|
||||
DWORD Filter,
|
||||
PWTS_SESSION_INFO_1W* ppSessionInfo,
|
||||
DWORD* pCount);
|
||||
|
||||
void ffDetectUsers(FFlist* users, FFstrbuf* error)
|
||||
{
|
||||
WTS_SESSION_INFO_1W* sessionInfo;
|
||||
DWORD sessionCount;
|
||||
DWORD level = 1;
|
||||
|
||||
if(!WTSEnumerateSessionsExW(WTS_CURRENT_SERVER_HANDLE, &level, 0, &sessionInfo, &sessionCount))
|
||||
{
|
||||
ffStrbufAppendS(error, "WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE) failed");
|
||||
return;
|
||||
}
|
||||
|
||||
for (DWORD i = 0; i < sessionCount; i++)
|
||||
{
|
||||
WTS_SESSION_INFO_1W* session = &sessionInfo[i];
|
||||
if(session->State != WTSActive)
|
||||
continue;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY domainName = ffStrbufFromWchar(session->pDomainName);
|
||||
FF_STRBUF_AUTO_DESTROY userName = ffStrbufFromWchar(session->pUserName);
|
||||
|
||||
ffStrbufInitF((FFstrbuf*)ffListAdd(users), "%s\\%s", domainName.chars, userName.chars);
|
||||
}
|
||||
|
||||
WTSFreeMemory(sessionInfo);
|
||||
|
||||
if(users->length == 0)
|
||||
ffStrbufAppendS(error, "Unable to detect users");
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
extern "C" {
|
||||
#include "users.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
void ffDetectUsers(FFlist* users, FFstrbuf* error)
|
||||
{
|
||||
FFWmiQuery query(L"SELECT Antecedent FROM Win32_LoggedOnUser", error);
|
||||
if(!query)
|
||||
return;
|
||||
|
||||
next:
|
||||
while(FFWmiRecord record = query.next())
|
||||
{
|
||||
FFstrbuf antecedent;
|
||||
ffStrbufInit(&antecedent);
|
||||
record.getString(L"Antecedent", &antecedent); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME"
|
||||
ffStrbufTrimRight(&antecedent, '"'); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME
|
||||
ffStrbufSubstrAfterFirstC(&antecedent, '"'); // DOMAIN",Name="NAME
|
||||
uint32_t index = ffStrbufFirstIndexC(&antecedent, '"');
|
||||
ffStrbufRemoveSubstr(&antecedent, index, ffStrbufLastIndexC(&antecedent, '"')); // DOMAIN"NAME
|
||||
antecedent.chars[index] = '\\';
|
||||
|
||||
for(uint32_t i = 0; i < users->length; ++i)
|
||||
{
|
||||
if(ffStrbufComp((FFstrbuf*)ffListGet(users, i), &antecedent) == 0)
|
||||
goto next;
|
||||
}
|
||||
|
||||
*(FFstrbuf*)ffListAdd(users) = antecedent;
|
||||
}
|
||||
|
||||
if(users->length == 0)
|
||||
ffStrbufAppendS(error, "Unable to detect users");
|
||||
}
|
||||
@@ -182,7 +182,7 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu
|
||||
|
||||
//Add the device to the list of devices shown by the GPU module
|
||||
|
||||
//We don't want softare rasterizers to show up as physical gpu
|
||||
//We don't want software rasterizers to show up as physical gpu
|
||||
if(physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -1,70 +1,117 @@
|
||||
#include "fastfetch.h"
|
||||
#include "wmtheme.h"
|
||||
#include "util/windows/register.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
|
||||
static inline void wrapRegCloseKey(HKEY* phKey)
|
||||
const char* colorHexToString(DWORD hex)
|
||||
{
|
||||
if(*phKey)
|
||||
RegCloseKey(*phKey);
|
||||
switch(hex)
|
||||
{
|
||||
case 0x696cc3: return "Yellow gold";
|
||||
case 0xff8c00: return "Gold";
|
||||
case 0xf7630c: return "Orange bright";
|
||||
case 0xca5010: return "Orange dark";
|
||||
case 0xda3b01: return "Rust";
|
||||
case 0xef6950: return "Pale rust";
|
||||
case 0xd13438: return "Brick red";
|
||||
case 0xff4343: return "Mod red";
|
||||
case 0xe74856: return "Pale red";
|
||||
case 0xe81123: return "Red";
|
||||
case 0xea005e: return "Rose bright";
|
||||
case 0xc30052: return "Rose";
|
||||
case 0xe3008c: return "Plum light";
|
||||
case 0xbf0077: return "Plum";
|
||||
case 0xc239b3: return "Orchid light";
|
||||
case 0x9a0089: return "Orchid";
|
||||
case 0x0078d4: return "Blue";
|
||||
case 0x0063b1: return "Navy blue";
|
||||
case 0x8d8bd7: return "Purple shadow";
|
||||
case 0x6b69d6: return "Purple shadow dark";
|
||||
case 0x8764b8: return "Iris pastel";
|
||||
case 0x744da9: return "Iris Spring";
|
||||
case 0xb146c2: return "Violet red light";
|
||||
case 0x881798: return "Violet red";
|
||||
case 0x0099bc: return "Cool blue bright";
|
||||
case 0x2d7d9a: return "Cool blue";
|
||||
case 0x00b7c3: return "Seafoam";
|
||||
case 0x038387: return "Seafoam teal";
|
||||
case 0x00b294: return "Mint light";
|
||||
case 0x018574: return "Mint dark";
|
||||
case 0x00cc6a: return "Turf green";
|
||||
case 0x10893e: return "Sport green";
|
||||
case 0x7a7574: return "Gray";
|
||||
case 0x5d5a58: return "Gray brown";
|
||||
case 0x68768a: return "Steel blue";
|
||||
case 0x515c6b: return "Metal blue";
|
||||
case 0x567c73: return "Pale moss";
|
||||
case 0x486860: return "Moss";
|
||||
case 0x498205: return "Meadow green";
|
||||
case 0x107c10: return "Green";
|
||||
case 0x767676: return "Overcast";
|
||||
case 0x4c4a48: return "Storm";
|
||||
case 0x69797e: return "Blue gray";
|
||||
case 0x4a5459: return "Gray dark";
|
||||
case 0x647c64: return "Liddy green";
|
||||
case 0x4c574e: return "Sage";
|
||||
case 0x807143: return "Camouflage desert";
|
||||
case 0x766c59: return "Camouflage";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
HKEY __attribute__((__cleanup__(wrapRegCloseKey))) hKey = NULL;
|
||||
if(RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
int SystemUsesLightTheme = 1;
|
||||
DWORD bufSize = sizeof(SystemUsesLightTheme);
|
||||
|
||||
if(RegGetValueW(hKey, NULL, L"SystemUsesLightTheme", RRF_RT_DWORD, NULL, &SystemUsesLightTheme, &bufSize) != ERROR_SUCCESS)
|
||||
uint32_t bgrColor;
|
||||
DWORD bufSize = sizeof(bgrColor);
|
||||
if(RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\DWM", L"AccentColor", RRF_RT_REG_DWORD, NULL, &bgrColor, &bufSize) == ERROR_SUCCESS)
|
||||
{
|
||||
ffStrbufAppendS(themeOrError, "RegGetValueW(SystemUsesLightTheme) failed");
|
||||
return false;
|
||||
ffStrbufAppendS(themeOrError, "Accent Color - ");
|
||||
DWORD rgbColor = ((bgrColor & 0xFF) << 16) | (bgrColor & 0xFF00) | ((bgrColor >> 16) & 0xFF);
|
||||
const char* text = colorHexToString(rgbColor);
|
||||
if(text)
|
||||
ffStrbufAppendS(themeOrError, text);
|
||||
else
|
||||
ffStrbufAppendF(themeOrError, "#%06lX", rgbColor);
|
||||
}
|
||||
|
||||
int AppsUsesLightTheme = 1;
|
||||
bufSize = sizeof(AppsUsesLightTheme);
|
||||
if(RegGetValueW(hKey, NULL, L"AppsUseLightTheme", RRF_RT_DWORD, NULL, &AppsUsesLightTheme, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
ffStrbufAppendS(themeOrError, "RegGetValueW(AppsUseLightTheme) failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
ffStrbufAppendF(themeOrError, "System - %s, Apps - %s", SystemUsesLightTheme ? "Light" : "Dark", AppsUsesLightTheme ? "Light" : "Dark");
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL))
|
||||
{
|
||||
DWORD length = 0;
|
||||
if(RegGetValueA(hKey, NULL, "CurrentTheme", RRF_RT_REG_SZ, NULL, NULL, &length) != ERROR_SUCCESS)
|
||||
uint32_t value = 1;
|
||||
if(ffRegReadUint(hKey, L"SystemUsesLightTheme", &value, NULL))
|
||||
{
|
||||
ffStrbufAppendS(themeOrError, "RegGetValueA(CurrentTheme, NULL) failed");
|
||||
return false;
|
||||
if(themeOrError->length > 0) ffStrbufAppendS(themeOrError, ", ");
|
||||
ffStrbufAppendF(themeOrError, "System - %s", value ? "Light" : "Dark");
|
||||
}
|
||||
|
||||
ffStrbufEnsureFree(themeOrError, length);
|
||||
if(RegGetValueA(hKey, NULL, "CurrentTheme", RRF_RT_REG_SZ, NULL, themeOrError->chars, &length) != ERROR_SUCCESS)
|
||||
if(ffRegReadUint(hKey, L"AppsUseLightTheme", &value, NULL))
|
||||
{
|
||||
ffStrbufAppendS(themeOrError, "RegGetValueA(CurrentTheme) failed");
|
||||
return false;
|
||||
if(themeOrError->length > 0) ffStrbufAppendS(themeOrError, ", ");
|
||||
ffStrbufAppendF(themeOrError, "Apps - %s", value ? "Light" : "Dark");
|
||||
}
|
||||
|
||||
themeOrError->length = length;
|
||||
ffStrbufSubstrBeforeLastC(themeOrError, '.');
|
||||
ffStrbufSubstrAfterLastC(themeOrError, '\\');
|
||||
if (isalpha(themeOrError->chars[0]))
|
||||
themeOrError->chars[0] = (char)toupper(themeOrError->chars[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
else if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL))
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY theme;
|
||||
ffStrbufInit(&theme);
|
||||
if(ffRegReadStrbuf(hKey, L"CurrentTheme", &theme, NULL))
|
||||
{
|
||||
ffStrbufSubstrBeforeLastC(themeOrError, '.');
|
||||
ffStrbufSubstrAfterLastC(themeOrError, '\\');
|
||||
if(isalpha(themeOrError->chars[0]))
|
||||
themeOrError->chars[0] = (char)toupper(themeOrError->chars[0]);
|
||||
if(themeOrError->length > 0) ffStrbufAppendS(themeOrError, ", ");
|
||||
ffStrbufAppendF(themeOrError, "Theme - %s", theme.chars);
|
||||
}
|
||||
}
|
||||
|
||||
if(themeOrError->length == 0)
|
||||
{
|
||||
ffStrbufAppendS(themeOrError, "Failed to find current theme");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+29
-35
@@ -1336,23 +1336,23 @@ static const FFlogo* getLogoWindows11()
|
||||
FF_LOGO_NAMES("Windows 11", "Windows Server 2022")
|
||||
FF_LOGO_LINES(
|
||||
"$1\n"
|
||||
",,**************/ ///////////////()\n"
|
||||
"****************/ ///////////////((\n"
|
||||
"***************// //////////////(((\n"
|
||||
"**************/// ////////////(((((\n"
|
||||
"************///// /////////((((((((\n"
|
||||
"*********//////// /////((((((((((((\n"
|
||||
"*******////////// ///((((((((((((((\n"
|
||||
"****///////////// (((((((((((((((((\n"
|
||||
",,**************/ ///////////////()\n"
|
||||
"****************/ ///////////////((\n"
|
||||
"***************// //////////////(((\n"
|
||||
"**************/// ////////////(((((\n"
|
||||
"************///// /////////((((((((\n"
|
||||
"*********//////// /////((((((((((((\n"
|
||||
"*******////////// ///((((((((((((((\n"
|
||||
"****///////////// (((((((((((((((((\n"
|
||||
"\n"
|
||||
"/////////////(((( (((((((((((((((((\n"
|
||||
"////////////((((( (((((((((((((((((\n"
|
||||
"///////////(((((( (((((((((((((((((\n"
|
||||
"/////////(((((((( (((((((((((((((((\n"
|
||||
"///////(((((((((( (((((((((((((((((\n"
|
||||
"////((((((((((((( (((((((((((((((((\n"
|
||||
"((((((((((((((((( (((((((((((((((((\n"
|
||||
"((((((((((((((((( (((((((((((((((()"
|
||||
"/////////////(((( (((((((((((((((((\n"
|
||||
"////////////((((( (((((((((((((((((\n"
|
||||
"///////////(((((( (((((((((((((((((\n"
|
||||
"/////////(((((((( (((((((((((((((((\n"
|
||||
"///////(((((((((( (((((((((((((((((\n"
|
||||
"////((((((((((((( (((((((((((((((((\n"
|
||||
"((((((((((((((((( (((((((((((((((((\n"
|
||||
"((((((((((((((((( (((((((((((((((()"
|
||||
)
|
||||
FF_LOGO_COLORS(
|
||||
"34" //blue
|
||||
@@ -1362,32 +1362,26 @@ static const FFlogo* getLogoWindows11()
|
||||
FF_LOGO_RETURN
|
||||
}
|
||||
|
||||
static const FFlogo* getLogoWindows11Old()
|
||||
static const FFlogo* getLogoWindows11Small()
|
||||
{
|
||||
FF_LOGO_INIT
|
||||
FF_LOGO_NAMES("Windows 11_old")
|
||||
FF_LOGO_NAMES("Windows 11_small", "Windows 11-small")
|
||||
FF_LOGO_LINES(
|
||||
"$1\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"lllllllll lllllllll\n"
|
||||
"lllllllll lllllllll\n"
|
||||
"lllllllll lllllllll\n"
|
||||
"lllllllll lllllllll\n"
|
||||
"\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################\n"
|
||||
"################ ################"
|
||||
"lllllllll lllllllll\n"
|
||||
"lllllllll lllllllll\n"
|
||||
"lllllllll lllllllll\n"
|
||||
"lllllllll lllllllll\n"
|
||||
)
|
||||
FF_LOGO_COLORS(
|
||||
"34" //blue
|
||||
)
|
||||
FF_LOGO_COLOR_KEYS("34"); //blue
|
||||
FF_LOGO_COLOR_KEYS("33"); //yellow
|
||||
FF_LOGO_COLOR_TITLE("36"); //cyan
|
||||
FF_LOGO_RETURN
|
||||
}
|
||||
@@ -2149,7 +2143,7 @@ static const FFlogo* getLogoUbuntuSmall()
|
||||
|
||||
static const FFlogo* getLogoVanilla()
|
||||
{
|
||||
|
||||
|
||||
FF_LOGO_INIT
|
||||
FF_LOGO_NAMES("vanilla", "vanilla-os","vanilla-linux");
|
||||
FF_LOGO_LINES(
|
||||
@@ -2314,7 +2308,7 @@ GetLogoMethod* ffLogoBuiltinGetAll()
|
||||
getLogoMintOld,
|
||||
getLogoMsys2,
|
||||
getLogoWindows11,
|
||||
getLogoWindows11Old,
|
||||
getLogoWindows11Small,
|
||||
getLogoWindows8,
|
||||
getLogoWindows,
|
||||
getLogoNixOS,
|
||||
|
||||
+26
-226
@@ -1,255 +1,55 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/settings.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "common/printing.h"
|
||||
#include "detection/cursor/cursor.h"
|
||||
|
||||
#define FF_CURSOR_MODULE_NAME "Cursor"
|
||||
#define FF_CURSOR_NUM_FORMAT_ARGS 2
|
||||
|
||||
#if !(defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32))
|
||||
|
||||
static void printCursor(FFinstance* instance, FFstrbuf* cursorTheme, const FFstrbuf* cursorSize)
|
||||
static void printCursor(FFinstance* instance, FFCursorResult* cursor)
|
||||
{
|
||||
ffStrbufRemoveIgnCaseEndS(cursorTheme, "cursors");
|
||||
ffStrbufRemoveIgnCaseEndS(cursorTheme, "cursor");
|
||||
ffStrbufTrimRight(cursorTheme, '_');
|
||||
ffStrbufTrimRight(cursorTheme, '-');
|
||||
if(cursorTheme->length == 0)
|
||||
ffStrbufAppendS(cursorTheme, "default");
|
||||
ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursors");
|
||||
ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursor");
|
||||
ffStrbufTrimRight(&cursor->theme, '_');
|
||||
ffStrbufTrimRight(&cursor->theme, '-');
|
||||
if(cursor->theme.length == 0)
|
||||
ffStrbufAppendS(&cursor->theme, "default");
|
||||
|
||||
if(instance->config.cursor.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor.key);
|
||||
ffStrbufWriteTo(cursorTheme, stdout);
|
||||
ffStrbufWriteTo(&cursor->theme, stdout);
|
||||
|
||||
if(cursorSize != NULL && cursorSize->length > 0)
|
||||
{
|
||||
fputs(" (", stdout);
|
||||
ffStrbufWriteTo(cursorSize, stdout);
|
||||
fputs("px)", stdout);
|
||||
}
|
||||
if(cursor->size.length > 0)
|
||||
printf(" (%spx)", cursor->size.chars);
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
ffPrintFormat(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, FF_CURSOR_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, cursorTheme},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, cursorSize}
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &cursor->theme},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &cursor->size}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void printCursorGTK(FFinstance* instance)
|
||||
{
|
||||
const FFGTKResult* gtk = ffDetectGTK4(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
gtk = ffDetectGTK3(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
gtk = ffDetectGTK2(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Couldn't detect GTK Cursor");
|
||||
return;
|
||||
}
|
||||
|
||||
//gtk->cursor is const, so we don't want to modify it
|
||||
FFstrbuf theme;
|
||||
ffStrbufInitCopy(&theme, >k->cursor);
|
||||
|
||||
printCursor(instance, &theme, >k->cursorSize);
|
||||
|
||||
ffStrbufDestroy(&theme);
|
||||
}
|
||||
|
||||
static void printCursorXFCE(FFinstance* instance)
|
||||
{
|
||||
FFstrbuf cursorTheme;
|
||||
ffStrbufInit(&cursorTheme);
|
||||
|
||||
ffStrbufAppendS(&cursorTheme, ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue);
|
||||
|
||||
if(cursorTheme.length == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Couldn't find xfce cursor in xfconf (xsettings::/Gtk/CursorThemeName)");
|
||||
return;
|
||||
}
|
||||
|
||||
FFstrbuf cursorSize;
|
||||
ffStrbufInit(&cursorSize);
|
||||
int cursorSizeVal = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue;
|
||||
if(cursorSizeVal > 0)
|
||||
ffStrbufAppendF(&cursorSize, "%i", cursorSizeVal);
|
||||
|
||||
printCursor(instance, &cursorTheme, &cursorSize);
|
||||
ffStrbufDestroy(&cursorTheme);
|
||||
ffStrbufDestroy(&cursorSize);
|
||||
}
|
||||
|
||||
static void printCursorFromConfigFile(FFinstance* instance, const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault)
|
||||
{
|
||||
FFstrbuf cursorTheme;
|
||||
ffStrbufInit(&cursorTheme);
|
||||
|
||||
FFstrbuf cursorSize;
|
||||
ffStrbufInit(&cursorSize);
|
||||
|
||||
if(ffParsePropFileConfigValues(instance, relativeFilePath, 2, (FFpropquery[]) {
|
||||
{themeStart, &cursorTheme},
|
||||
{sizeStart, &cursorSize}
|
||||
})) {
|
||||
|
||||
if(cursorTheme.length == 0)
|
||||
ffStrbufAppendS(&cursorTheme, themeDefault);
|
||||
|
||||
if(cursorSize.length == 0)
|
||||
ffStrbufAppendS(&cursorSize, sizeDefault);
|
||||
}
|
||||
|
||||
if(cursorTheme.length == 0)
|
||||
ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Couldn't find cursor in %s", relativeFilePath);
|
||||
else
|
||||
printCursor(instance, &cursorTheme, &cursorSize);
|
||||
|
||||
ffStrbufDestroy(&cursorTheme);
|
||||
ffStrbufDestroy(&cursorSize);
|
||||
}
|
||||
|
||||
static bool printCursorFromXResources(FFinstance* instance)
|
||||
{
|
||||
FFstrbuf theme;
|
||||
ffStrbufInit(&theme);
|
||||
|
||||
FFstrbuf size;
|
||||
ffStrbufInit(&size);
|
||||
|
||||
ffParsePropFileHomeValues(instance, ".Xresources", 2, (FFpropquery[]) {
|
||||
{"Xcursor.theme :", &theme},
|
||||
{"Xcursor.size :", &size}
|
||||
});
|
||||
|
||||
if(theme.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&size);
|
||||
ffStrbufDestroy(&theme);
|
||||
return false;
|
||||
}
|
||||
|
||||
printCursor(instance, &theme, &size);
|
||||
ffStrbufDestroy(&size);
|
||||
ffStrbufDestroy(&theme);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool printCursorFromXDG(FFinstance* instance, bool user)
|
||||
{
|
||||
FFstrbuf theme;
|
||||
ffStrbufInit(&theme);
|
||||
|
||||
if(user)
|
||||
ffParsePropFileHome(instance, ".icons/default/index.theme", "Inherits =", &theme);
|
||||
else
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/icons/default/index.theme", "Inherits =", &theme);
|
||||
|
||||
if(theme.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&theme);
|
||||
return false;
|
||||
}
|
||||
|
||||
printCursor(instance, &theme, NULL);
|
||||
ffStrbufDestroy(&theme);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool printCursorFromEnv(FFinstance* instance)
|
||||
{
|
||||
const char* xcursor_theme = getenv("XCURSOR_THEME");
|
||||
|
||||
if(!ffStrSet(xcursor_theme))
|
||||
return false;
|
||||
|
||||
FFstrbuf theme;
|
||||
ffStrbufInit(&theme);
|
||||
ffStrbufAppendS(&theme, xcursor_theme);
|
||||
|
||||
FFstrbuf size;
|
||||
ffStrbufInit(&size);
|
||||
ffStrbufAppendS(&size, getenv("XCURSOR_SIZE"));
|
||||
|
||||
printCursor(instance, &theme, &size);
|
||||
|
||||
ffStrbufDestroy(&size);
|
||||
ffStrbufDestroy(&theme);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ffPrintCursor(FFinstance* instance)
|
||||
{
|
||||
#if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32)
|
||||
FFCursorResult result;
|
||||
ffStrbufInit(&result.error);
|
||||
ffStrbufInit(&result.theme);
|
||||
ffStrbufInit(&result.size);
|
||||
|
||||
FF_UNUSED(instance);
|
||||
ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Cursor detection is not supported");
|
||||
return;
|
||||
ffDetectCursor(instance, &result);
|
||||
|
||||
#else
|
||||
if(result.error.length)
|
||||
ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "%s", result.error.chars);
|
||||
else
|
||||
printCursor(instance, &result);
|
||||
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
|
||||
|
||||
if(ffStrbufCompS(&wmde->wmPrettyName, "WSLg") == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "WSLg uses native windows cursor");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, "TTY") == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Cursor isn't supported in TTY");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "KDE Plasma") == 0)
|
||||
{
|
||||
printCursorFromConfigFile(instance, "kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "XFCE"))
|
||||
{
|
||||
printCursorXFCE(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "LXQt"))
|
||||
{
|
||||
printCursorFromConfigFile(instance, "lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Gnome") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0)
|
||||
{
|
||||
printCursorGTK(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
if(
|
||||
printCursorFromEnv(instance) ||
|
||||
printCursorFromXDG(instance, true) ||
|
||||
printCursorFromXResources(instance) ||
|
||||
printCursorFromXDG(instance, false)
|
||||
) return;
|
||||
|
||||
printCursorGTK(instance);
|
||||
|
||||
#endif
|
||||
ffStrbufDestroy(&result.error);
|
||||
ffStrbufDestroy(&result.theme);
|
||||
ffStrbufDestroy(&result.size);
|
||||
}
|
||||
|
||||
+7
-2
@@ -45,9 +45,14 @@ static void printFont(const FFFontResult* font)
|
||||
|
||||
static void printFont(const FFFontResult* font)
|
||||
{
|
||||
if(font->fonts[0].length > 0)
|
||||
const char* types[] = { "Caption", "Menu", "Message", "Status" };
|
||||
for(uint32_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i)
|
||||
{
|
||||
printf("%s [Desktop]", font->fonts[0].chars);
|
||||
if(font->fonts[i].length > 0)
|
||||
{
|
||||
printf("%s [%s]", font->fonts[i].chars, types[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -35,8 +35,7 @@ void ffPrintHost(FFinstance* instance)
|
||||
|
||||
if(host->productVersion.length > 0)
|
||||
{
|
||||
ffStrbufAppendC(&output, ' ');
|
||||
ffStrbufAppend(&output, &host->productVersion);
|
||||
ffStrbufAppendF(&output, " (%s)", host->productVersion.chars);
|
||||
}
|
||||
|
||||
ffPrintAndWriteToCache(instance, FF_HOST_MODULE_NAME, &instance->config.host, &output, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void ffWrapFree(void* pPtr)
|
||||
{
|
||||
if(*(void**)pPtr)
|
||||
free(*(void**)pPtr);
|
||||
}
|
||||
|
||||
#define FF_AUTO_FREE __attribute__((__cleanup__(ffWrapFree)))
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "register.h"
|
||||
#include "unicode.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
static const char* hKey2Str(HKEY hKey)
|
||||
{
|
||||
#define HKEY_CASE(compareKey) if(hKey == compareKey) return #compareKey;
|
||||
HKEY_CASE(HKEY_CLASSES_ROOT)
|
||||
HKEY_CASE(HKEY_CURRENT_USER)
|
||||
HKEY_CASE(HKEY_LOCAL_MACHINE)
|
||||
HKEY_CASE(HKEY_USERS)
|
||||
HKEY_CASE(HKEY_PERFORMANCE_DATA)
|
||||
HKEY_CASE(HKEY_PERFORMANCE_TEXT)
|
||||
HKEY_CASE(HKEY_PERFORMANCE_NLSTEXT)
|
||||
HKEY_CASE(HKEY_CURRENT_CONFIG)
|
||||
HKEY_CASE(HKEY_DYN_DATA)
|
||||
HKEY_CASE(HKEY_CURRENT_USER_LOCAL_SETTINGS)
|
||||
#undef HKEY_CASE
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error)
|
||||
{
|
||||
if(RegOpenKeyExW(hKey, subKeyW, 0, KEY_READ, result) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufFromWchar(subKeyW);
|
||||
ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error)
|
||||
{
|
||||
DWORD bufSize; //with tailing '\0'
|
||||
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error)
|
||||
{
|
||||
if(!valueNameW)
|
||||
valueNameW = L"(default)";
|
||||
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW);
|
||||
ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueNameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
wchar_t* FF_AUTO_FREE resultW = (wchar_t*)malloc(bufSize);
|
||||
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, resultW, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error)
|
||||
{
|
||||
if(!valueNameW)
|
||||
valueNameW = L"(default)";
|
||||
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW);
|
||||
ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueNameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ffWcharToUtf8(resultW, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error)
|
||||
{
|
||||
DWORD bufSize = sizeof(*result);
|
||||
if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS)
|
||||
{
|
||||
if(error)
|
||||
{
|
||||
if(!valueNameW)
|
||||
valueNameW = L"(default)";
|
||||
FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW);
|
||||
ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueNameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FASTFETCH_INCLUDED_REGISTER_H
|
||||
#define FASTFETCH_INCLUDED_REGISTER_H
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
static inline void wrapRegCloseKey(HKEY* phKey)
|
||||
{
|
||||
if(*phKey)
|
||||
RegCloseKey(*phKey);
|
||||
}
|
||||
|
||||
#define FF_HKEY_AUTO_DESTROY HKEY __attribute__((__cleanup__(wrapRegCloseKey)))
|
||||
|
||||
bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error);
|
||||
bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error);
|
||||
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "unicode.h"
|
||||
|
||||
void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result)
|
||||
{
|
||||
int len = (int)wcslen(input);
|
||||
if(len <= 0)
|
||||
{
|
||||
ffStrbufClear(result);
|
||||
return;
|
||||
}
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, input, len, NULL, 0, NULL, NULL);
|
||||
ffStrbufEnsureFree(result, (uint32_t)size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, input, len, result->chars, size_needed, NULL, NULL);
|
||||
result->length = (uint32_t)size_needed;
|
||||
result->chars[size_needed] = '\0';
|
||||
}
|
||||
|
||||
FFstrbuf ffStrbufFromWchar(const wchar_t* input)
|
||||
{
|
||||
FFstrbuf result;
|
||||
|
||||
int len = input ? (int)wcslen(input) : 0;
|
||||
if(len <= 0)
|
||||
ffStrbufInit(&result);
|
||||
else
|
||||
{
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, input, len, NULL, 0, NULL, NULL);
|
||||
ffStrbufInitA(&result, (uint32_t)size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, input, len, result.chars, size_needed, NULL, NULL);
|
||||
result.length = (uint32_t)size_needed;
|
||||
result.chars[size_needed] = '\0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FASTFETCH_INCLUDED_UNICODE_H
|
||||
#define FASTFETCH_INCLUDED_UNICODE_H
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result);
|
||||
FFstrbuf ffStrbufFromWchar(const wchar_t* input);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user