Merge pull request #338 from CarterLi/dev

Improve performance and various fixes
This commit is contained in:
Linus Dierheimer
2022-11-24 14:14:03 +01:00
committed by GitHub
46 changed files with 1115 additions and 775 deletions
+39 -15
View File
@@ -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()
+133
View File
@@ -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;
}
-65
View File
@@ -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;
}
+28
View File
@@ -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);
}
-28
View File
@@ -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");
}
+21
View File
@@ -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);
}
-26
View File
@@ -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");
}
+53
View File
@@ -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);
}
-51
View File
@@ -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;
}
}
-14
View File
@@ -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
-5
View File
@@ -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;
}
+17
View File
@@ -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
+131
View File
@@ -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, &gtk->cursor);
ffStrbufAppend(&result->size, &gtk->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);
}
+6
View File
@@ -0,0 +1,6 @@
#include "cursor.h"
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
{
ffStrbufInitS(&result->error, "Not supported on this platform");
}
+12
View File
@@ -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);
}
+1 -1
View File
@@ -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];
+22
View File
@@ -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);
}
}
-32
View File
@@ -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");
}
+4
View File
@@ -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;
-4
View File
@@ -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"
+67 -4
View File
@@ -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
}
+27
View File
@@ -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);
}
-32
View File
@@ -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");
}
+11
View File
@@ -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;
}
-25
View File
@@ -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");
}
+83 -44
View File
@@ -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);
}
+41 -1
View File
@@ -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
+11
View File
@@ -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;
}
-23
View File
@@ -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");
}
+1 -1
View File
@@ -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;
+55
View File
@@ -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");
}
-35
View File
@@ -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");
}
+1 -1
View File
@@ -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;
+91 -44
View File
@@ -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
View File
@@ -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
View File
@@ -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, &gtk->cursor);
printCursor(instance, &theme, &gtk->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
View File
@@ -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
View File
@@ -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[]) {
+9
View File
@@ -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)))
+82
View File
@@ -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;
}
+23
View File
@@ -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
+36
View File
@@ -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;
}
+11
View File
@@ -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