diff --git a/CMakeLists.txt b/CMakeLists.txt
index 91649c043e..1edbb9bc1c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,8 @@ project(fastfetch
HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch"
)
+set(PROJECT_LICENSE "MIT license")
+
###################
# Target Platform #
###################
@@ -578,6 +580,26 @@ target_link_libraries(flashfetch
PRIVATE libfastfetch
)
+if(WIN32)
+ if(PROJECT_VERSION_TWEAK)
+ string(REGEX MATCH "[0-9]+" PROJECT_VERSION_TWEAK_NUM "${PROJECT_VERSION_TWEAK}")
+ else()
+ set(PROJECT_VERSION_TWEAK_NUM "0")
+ endif()
+
+ set(TARGET_NAME fastfetch)
+ configure_file(src/util/windows/version.rc.in version.fastfetch.rc)
+ target_sources(fastfetch
+ PRIVATE version.fastfetch.rc
+ )
+
+ set(TARGET_NAME flashfetch)
+ configure_file(src/util/windows/version.rc.in version.flashfetch.rc)
+ target_sources(flashfetch
+ PRIVATE version.flashfetch.rc
+ )
+endif()
+
###################
# Testing targets #
###################
diff --git a/README.md b/README.md
index 646e4277ea..6a5f0b7703 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Fastfetch
-Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently Linux, Android, FreeBSD, MacOS and Windows are supported.
+Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
@@ -61,6 +61,8 @@ The following libraries are used if present at runtime:
* [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers.
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module
+Note: On Windows 10-, [ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html) is required to run fastfetch due to [the lack of ASCII escape code native support](https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows). Also make sure to [use `chcp 65001` to enable UTF-8 support](https://conemu.github.io/en/UnicodeSupport.html#utf-8) if you run Windows locale other than English.
+
### Android
* [`freetype`](https://www.freetype.org/): Used for Termux font detection.
@@ -101,7 +103,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt
##### Terminal fonts
```
-Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, TTY, Windows Terminal, Termux, mintty
+Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu
```
## Building
diff --git a/src/common/init.c b/src/common/init.c
index 962bde9fee..e8dc449401 100644
--- a/src/common/init.c
+++ b/src/common/init.c
@@ -334,12 +334,9 @@ static void resetConsole()
#ifdef _WIN32
BOOL WINAPI consoleHandler(DWORD signal)
{
- if(signal == CTRL_C_EVENT)
- {
+ FF_UNUSED(signal);
resetConsole();
- return TRUE;
- }
- return false;
+ exit(0);
}
#else
static void exitSignalHandler(int signal)
@@ -360,6 +357,11 @@ void ffStart(FFinstance* instance)
#ifdef _WIN32
SetConsoleCtrlHandler(consoleHandler, TRUE);
+ HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ DWORD mode = 0;
+ GetConsoleMode(hStdout, &mode);
+ SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
+ // SetConsoleOutputCP(CP_UTF8);
#else
struct sigaction action = { .sa_handler = exitSignalHandler };
sigaction(SIGINT, &action, NULL);
diff --git a/src/common/networking_linux.c b/src/common/networking_linux.c
index 5d656fddd7..7fb6fade55 100644
--- a/src/common/networking_linux.c
+++ b/src/common/networking_linux.c
@@ -67,7 +67,7 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
#ifdef FF_HAVE_THREADS
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
- return state->thread != NULL;
+ return !!state->thread;
#else
connectAndSend(state);
return state->sockfd != -1;
diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c
index dd32fac164..5814acc165 100644
--- a/src/common/networking_windows.c
+++ b/src/common/networking_windows.c
@@ -75,7 +75,7 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
}
}
- FFstrbuf command;
+ FF_STRBUF_AUTO_DESTROY command;
ffStrbufInitA(&command, 64);
ffStrbufAppendS(&command, "GET ");
ffStrbufAppendS(&command, path);
@@ -87,7 +87,6 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen, command.chars, command.length, NULL, &state->overlapped);
freeaddrinfo(addr);
- ffStrbufDestroy(&command);
if(!result && WSAGetLastError() != WSA_IO_PENDING)
{
@@ -95,7 +94,6 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
return false;
}
- ffStrbufDestroy(&command);
return true;
}
diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c
index cd091ac6c3..30e5157343 100644
--- a/src/common/processing_windows.c
+++ b/src/common/processing_windows.c
@@ -27,27 +27,30 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
.hStdOutput = hChildStdoutWrite,
};
- FFstrbuf cmdline;
- ffStrbufInitF(&cmdline, "\"%s\"", argv[0]);
- for(char* const* parg = &argv[1]; *parg; ++parg)
- {
- ffStrbufAppendC(&cmdline, ' ');
- ffStrbufAppendS(&cmdline, *parg);
- }
+ BOOL success;
- BOOL success = CreateProcessA(
- NULL, // application name
- cmdline.chars, // command line
- NULL, // process security attributes
- NULL, // primary thread security attributes
- TRUE, // handles are inherited
- 0, // creation flags
- NULL, // use parent's environment
- NULL, // use parent's current directory
- &siStartInfo, // STARTUPINFO pointer
- &piProcInfo); // receives PROCESS_INFORMATION
+ {
+ FF_STRBUF_AUTO_DESTROY cmdline;
+ ffStrbufInitF(&cmdline, "\"%s\"", argv[0]);
+ for(char* const* parg = &argv[1]; *parg; ++parg)
+ {
+ ffStrbufAppendC(&cmdline, ' ');
+ ffStrbufAppendS(&cmdline, *parg);
+ }
- ffStrbufDestroy(&cmdline);
+ success = CreateProcessA(
+ NULL, // application name
+ cmdline.chars, // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ 0, // creation flags
+ NULL, // use parent's environment
+ NULL, // use parent's current directory
+ &siStartInfo, // STARTUPINFO pointer
+ &piProcInfo // receives PROCESS_INFORMATION
+ );
+ }
CloseHandle(hChildStdoutWrite);
if(!success)
diff --git a/src/common/thread.h b/src/common/thread.h
index 74c536cf2b..c4d2230842 100644
--- a/src/common/thread.h
+++ b/src/common/thread.h
@@ -29,7 +29,7 @@
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
static inline FFThreadType ffThreadCreate(void* (* func)(void*), void* data) {
- FFThreadType newThread = NULL;
+ FFThreadType newThread = 0;
pthread_create(&newThread, NULL, func, data);
return newThread;
}
diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c
index 88499aaa70..7244a89a15 100644
--- a/src/detection/battery/battery_apple.c
+++ b/src/detection/battery/battery_apple.c
@@ -7,7 +7,7 @@
static double detectBatteryTemp()
{
- FFlist temps;
+ FF_LIST_AUTO_DESTROY temps;
ffListInit(&temps, sizeof(FFTempValue));
ffDetectCoreTemps(FF_TEMP_BATTERY, &temps);
@@ -25,7 +25,6 @@ static double detectBatteryTemp()
ffStrbufDestroy(&tempValue->deviceClass);
}
result /= temps.length;
- ffListDestroy(&temps);
return result;
}
diff --git a/src/detection/cpu/cpu.c b/src/detection/cpu/cpu.c
index 3a304606e5..3bfe92e872 100644
--- a/src/detection/cpu/cpu.c
+++ b/src/detection/cpu/cpu.c
@@ -31,7 +31,6 @@ static void detectCPU(const FFinstance* instance, FFCPUResult* cpu)
return;
const char* removeStrings[] = {
- "(R)", "(r)", "(TM)", "(tm)",
" CPU", " FPU", " APU", " Processor",
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c
index dc0c1a3ebe..5f1b354948 100644
--- a/src/detection/cpu/cpu_apple.c
+++ b/src/detection/cpu/cpu_apple.c
@@ -15,7 +15,7 @@ static double getFrequency(const char* propName)
static double detectCpuTemp(const FFstrbuf* cpuName)
{
- FFlist temps;
+ FF_LIST_AUTO_DESTROY temps;
ffListInit(&temps, sizeof(FFTempValue));
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
@@ -38,7 +38,6 @@ static double detectCpuTemp(const FFstrbuf* cpuName)
ffStrbufDestroy(&tempValue->deviceClass);
}
result /= temps.length;
- ffListDestroy(&temps);
return result;
}
diff --git a/src/detection/cpu/cpu_windows.cpp b/src/detection/cpu/cpu_windows.cpp
index 8740fa4b96..e5939cd604 100644
--- a/src/detection/cpu/cpu_windows.cpp
+++ b/src/detection/cpu/cpu_windows.cpp
@@ -17,11 +17,21 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
ffStrbufInit(&cpu->name);
ffStrbufInit(&cpu->vendor);
- FFWmiQuery query(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, ThreadCount, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3");
+ FFWmiQuery query(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, NumberOfEnabledCore, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3");
if(!query)
return;
- if(FFWmiRecord record = query.next())
+ 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);
@@ -32,8 +42,7 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
cpu->coresPhysical = (uint16_t)value;
record.getUnsigned(L"NumberOfLogicalProcessors", &value);
cpu->coresLogical = (uint16_t)value;
- record.getUnsigned(L"ThreadCount", &value);
- cpu->coresOnline = (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);
diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuUsage/cpuUsage.c
index 7470236dc3..82bf1f7d43 100644
--- a/src/detection/cpuUsage/cpuUsage.c
+++ b/src/detection/cpuUsage/cpuUsage.c
@@ -36,23 +36,30 @@ const char* ffGetCpuUsageResult(double* result)
error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
if(error)
return error;
- ffTimeSleep(1000);
+ ffTimeSleep(250);
}
else
{
uint64_t duration = ffTimeGetTick() - startTime;
- if(duration < 1000)
- ffTimeSleep(1000 - (uint32_t) duration);
+ if(duration < 250)
+ ffTimeSleep(250 - (uint32_t) duration);
}
- uint64_t inUseAll2, totalAll2;
- error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2);
- if(error)
- return error;
-
- *result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100;
+ while(true)
+ {
+ uint64_t inUseAll2, totalAll2;
+ error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2);
+ if(error)
+ return error;
- return NULL;
+ if(inUseAll2 != inUseAll1)
+ {
+ *result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100;
+ return NULL;
+ }
+ else
+ ffTimeSleep(250);
+ }
}
#endif //FF_DETECTION_CPUUSAGE_NOWAIT
diff --git a/src/detection/cpuUsage/cpuUsage_windows.c b/src/detection/cpuUsage/cpuUsage_windows.c
index 1aa9ba3f64..bf4cc7644e 100644
--- a/src/detection/cpuUsage/cpuUsage_windows.c
+++ b/src/detection/cpuUsage/cpuUsage_windows.c
@@ -1,8 +1,7 @@
#include "fastfetch.h"
#include "cpuUsage.h"
-#define WIN32_LEAN_AND_MEAN 1
-#include
+#include
static inline uint64_t fileTimeToUint64(const FILETIME* ft) {
return (((uint64_t)ft->dwHighDateTime) << 32) | ((uint64_t)ft->dwLowDateTime);
@@ -11,10 +10,12 @@ static inline uint64_t fileTimeToUint64(const FILETIME* ft) {
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
{
FILETIME idleTime, kernelTime, userTime;
- if(GetSystemTimes(&idleTime, &kernelTime, &userTime) == 0)
+ if(!GetSystemTimes(&idleTime, &kernelTime, &userTime))
return "GetSystemTimes() failed";
- *inUseAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime);
- *totalAll = *inUseAll + fileTimeToUint64(&idleTime);
+ // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getsystemtimes
+ // `kernelTime` also includes the amount of time the system has been idle.
+ *totalAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime);
+ *inUseAll = *totalAll - fileTimeToUint64(&idleTime);
return NULL;
}
diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c
index 93dee0f7d3..8abfbdf20e 100644
--- a/src/detection/disk/disk_linux.c
+++ b/src/detection/disk/disk_linux.c
@@ -73,9 +73,15 @@ void ffDetectDisksImpl(FFDiskResult* disks)
#endif
//Detects stats
- struct statvfs fs;
- if(statvfs(disk->mountpoint.chars, &fs) != 0)
- memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too
+ #ifdef __USE_LARGEFILE64
+ struct statvfs64 fs;
+ if(statvfs64(disk->mountpoint.chars, &fs) != 0)
+ memset(&fs, 0, sizeof(struct statvfs64)); //Set all values to 0, so our values get initialized to 0 too
+ #else
+ struct statvfs fs;
+ if(statvfs(disk->mountpoint.chars, &fs) != 0)
+ memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too
+ #endif
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize);
diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c
index 80211fb38b..96bdf3d2ea 100644
--- a/src/detection/displayserver/displayserver_apple.c
+++ b/src/detection/displayserver/displayserver_apple.c
@@ -4,53 +4,31 @@
#include
#include
#include
-#include
-
-//Resolution code heavily inspired by displayplacer <3
-
-typedef union
-{
- uint8_t rawData[0xDC];
- struct
- {
- uint32_t mode;
- uint32_t flags; // 0x4
- uint32_t width; // 0x8
- uint32_t height; // 0xC
- uint32_t depth; // 0x10
- uint32_t dc2[42];
- uint16_t dc3;
- uint16_t freq; // 0xBC
- uint32_t dc4[4];
- float density; // 0xD0
- } derived;
-} modes_D4;
-
-void CGSGetCurrentDisplayMode(CGDirectDisplayID display, int* modeNum);
-void CGSGetDisplayModeDescriptionOfLength(CGDirectDisplayID display, int idx, modes_D4* mode, int length);
+#include
+#include
static void detectResolution(FFDisplayServerResult* ds)
{
- CGDisplayCount screenCount;
- CGGetOnlineDisplayList(INT_MAX, NULL, &screenCount);
- if(screenCount == 0)
+ CGDirectDisplayID screens[128];
+ uint32_t screenCount;
+ if(CGGetOnlineDisplayList(sizeof(screens) / sizeof(screens[0]), screens, &screenCount) != kCGErrorSuccess)
return;
- CGDirectDisplayID* screens = malloc(screenCount * sizeof(CGDirectDisplayID));
- CGGetOnlineDisplayList(INT_MAX, screens, &screenCount);
-
for(uint32_t i = 0; i < screenCount; i++)
{
- int modeID;
- CGSGetCurrentDisplayMode(screens[i], &modeID);
- modes_D4 mode;
- CGSGetDisplayModeDescriptionOfLength(screens[i], modeID, &mode, 0xD4);
-
- uint32_t refreshRate = ffdsParseRefreshRate(mode.derived.freq);
- ffdsAppendResolution(ds, mode.derived.width, mode.derived.height, refreshRate);
+ CGDirectDisplayID screen = screens[i];
+ CGDisplayModeRef mode = CGDisplayCopyDisplayMode(screen);
+ if(mode)
+ {
+ ffdsAppendResolution(ds,
+ (uint32_t)CGDisplayModeGetWidth(mode),
+ (uint32_t)CGDisplayModeGetHeight(mode),
+ (uint32_t)CGDisplayModeGetRefreshRate(mode)
+ );
+ CGDisplayModeRelease(mode);
+ }
+ CGDisplayRelease(screen);
}
-
- free(screens);
}
static void detectWM(FFDisplayServerResult* ds)
diff --git a/src/detection/font/font.h b/src/detection/font/font.h
index 63d19e2ee6..80bed7a395 100644
--- a/src/detection/font/font.h
+++ b/src/detection/font/font.h
@@ -12,10 +12,10 @@ typedef struct FFFontResult
FFstrbuf error;
/**
- * Linux / BSD: QT, GTK2, GTK3, GTK4
- * MacOS: System, User, Monospace, Application
- * Windows: Desktop, Unset, Unset, Unset
- * Other: Unset, Unset, Unset, Unset
+ * Linux / BSD: QT, GTK2, GTK3, GTK4
+ * MacOS: System, User, System Mono, User Mono
+ * Windows: Desktop, Unset, Unset, Unset
+ * Other: Unset, Unset, Unset, Unset
*/
FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS];
} FFFontResult;
diff --git a/src/detection/font/font_apple.m b/src/detection/font/font_apple.m
index 91689f6e93..773c7705b5 100644
--- a/src/detection/font/font_apple.m
+++ b/src/detection/font/font_apple.m
@@ -1,23 +1,14 @@
#include "common/font.h"
#include "common/io.h"
-#include "util/apple/cf_helpers.h"
#include "font.h"
-#import
-
-static void detectFontForType(CTFontUIFontType uiType, FFstrbuf* font)
-{
- CTFontRef ctFont = CTFontCreateUIFontForLanguage(uiType, 12, NULL);
- ffCfStrGetString(CTFontCopyFamilyName(ctFont), font);
-}
+#import
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
{
FF_UNUSED(instance);
- ffSuppressIO(true);
- detectFontForType(kCTFontUIFontSystem, &result->fonts[0]);
- detectFontForType(kCTFontUIFontUser, &result->fonts[1]);
- detectFontForType(kCTFontUIFontUserFixedPitch, &result->fonts[2]);
- detectFontForType(kCTFontUIFontApplication, &result->fonts[3]);
- ffSuppressIO(false);
+ ffStrbufAppendS(&result->fonts[0], [NSFont systemFontOfSize:12].familyName.UTF8String);
+ ffStrbufAppendS(&result->fonts[1], [NSFont userFontOfSize:12].familyName.UTF8String);
+ ffStrbufAppendS(&result->fonts[2], [NSFont monospacedSystemFontOfSize:12 weight:400].familyName.UTF8String);
+ ffStrbufAppendS(&result->fonts[3], [NSFont userFixedPitchFontOfSize:12].familyName.UTF8String);
}
diff --git a/src/detection/font/font_windows.cpp b/src/detection/font/font_windows.cpp
index 3d883bd586..fd400fb715 100644
--- a/src/detection/font/font_windows.cpp
+++ b/src/detection/font/font_windows.cpp
@@ -18,7 +18,7 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
if(FFWmiRecord record = query.next())
{
- FFstrbuf fontName;
+ FF_STRBUF_AUTO_DESTROY fontName;
ffStrbufInit(&fontName);
record.getString(L"IconTitleFaceName", &fontName);
@@ -26,8 +26,6 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
record.getUnsigned(L"IconTitleSize", &fontSize);
ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize);
-
- ffStrbufDestroy(&fontName);
}
else
ffStrbufInitS(&result->error, "No WMI result returned");
diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c
index bad6747d3a..52292d83e8 100644
--- a/src/detection/gpu/gpu_apple.c
+++ b/src/detection/gpu/gpu_apple.c
@@ -8,7 +8,7 @@
static double detectGpuTemp(const FFstrbuf* gpuName)
{
- FFlist temps;
+ FF_LIST_AUTO_DESTROY temps;
ffListInit(&temps, sizeof(FFTempValue));
if(ffStrbufStartsWithS(gpuName, "Apple M1"))
@@ -35,7 +35,6 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
ffStrbufDestroy(&tempValue->deviceClass);
}
result /= temps.length;
- ffListDestroy(&temps);
return result;
}
diff --git a/src/detection/host/host.h b/src/detection/host/host.h
index e66af41fb6..e49e8faadc 100644
--- a/src/detection/host/host.h
+++ b/src/detection/host/host.h
@@ -5,9 +5,6 @@
#include "fastfetch.h"
-#define FF_HOST_PRODUCT_NAME_WSL "Windows Subsystem for Linux"
-#define FF_HOST_PRODUCT_NAME_MSYS "Windows on MSYS"
-
typedef struct FFHostResult
{
FFstrbuf productFamily;
diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c
index ef9cfbf5e3..4833131036 100644
--- a/src/detection/host/host_linux.c
+++ b/src/detection/host/host_linux.c
@@ -1,5 +1,6 @@
#include "host.h"
#include "common/io.h"
+#include "common/processing.h"
#include
@@ -94,6 +95,27 @@ void ffDetectHostImpl(FFHostResult* host)
{
//On WSL, the real host can't be detected. Instead use WSL as host.
if(getenv("WSL_DISTRO") != NULL || getenv("WSL_INTEROP") != NULL)
- ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_WSL);
+ {
+ ffStrbufAppendS(&host->productName, "Windows Subsystem for Linux");
+
+ FFstrbuf wslVer; //Wide charactors
+ ffStrbufInit(&wslVer);
+ if(!ffProcessAppendStdOut(&wslVer, (char* const[]){
+ "wsl.exe",
+ "--version",
+ NULL
+ }) && wslVer.length > 0)
+ {
+ ffStrbufSubstrBeforeFirstC(&wslVer, '\r'); //CRLF
+ ffStrbufSubstrAfterLastC(&wslVer, ' ');
+ ffStrbufAppendS(&host->productName, " (");
+ for(uint32_t i = 0; i < wslVer.length; ++i) {
+ if(wslVer.chars[i]) //don't append \0
+ ffStrbufAppendC(&host->productName, wslVer.chars[i]);
+ }
+ ffStrbufAppendC(&host->productName, ')');
+ }
+ ffStrbufDestroy(&wslVer);
+ }
}
}
diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp
index 5d0333db85..cbdd440ad1 100644
--- a/src/detection/host/host_windows.cpp
+++ b/src/detection/host/host_windows.cpp
@@ -28,5 +28,5 @@ extern "C" void ffDetectHostImpl(FFHostResult* host)
record.getString(L"Vendor", &host->sysVendor);
}
else
- ffStrbufInitS(&host->error, "No Wmi result returned");
+ ffStrbufAppendS(&host->error, "No Wmi result returned");
}
diff --git a/src/detection/os/os_android.c b/src/detection/os/os_android.c
index bb3b6c9daf..eb4bf97d55 100644
--- a/src/detection/os/os_android.c
+++ b/src/detection/os/os_android.c
@@ -5,14 +5,11 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
{
FF_UNUSED(instance);
- ffStrbufInit(&os->name);
- ffStrbufSetS(&os->name, "Android");
+ ffStrbufInitS(&os->name, "Android");
- ffStrbufInit(&os->prettyName);
- ffStrbufSetS(&os->prettyName, "Android");
+ ffStrbufInitS(&os->prettyName, "Android");
- ffStrbufInit(&os->id);
- ffStrbufSetS(&os->id, "android");
+ ffStrbufInitS(&os->id, "android");
ffStrbufInit(&os->version);
ffSettingsGetAndroidProperty("ro.build.version.release", &os->version);
@@ -26,13 +23,11 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
ffStrbufInit(&os->buildID);
ffSettingsGetAndroidProperty("ro.build.id", &os->buildID);
- ffStrbufInit(&os->systemName);
- ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
+ ffStrbufInitS(&os->systemName, instance->state.utsname.sysname);
- ffStrbufInit(&os->architecture);
- ffStrbufSetS(&os->architecture, instance->state.utsname.machine);
+ ffStrbufInitS(&os->architecture, instance->state.utsname.machine);
- ffStrbufInitA(&os->idLike, 0);
- ffStrbufInitA(&os->variant, 0);
- ffStrbufInitA(&os->variantID, 0);
+ ffStrbufInit(&os->idLike);
+ ffStrbufInit(&os->variant);
+ ffStrbufInit(&os->variantID);
}
diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp
index e28607c9c1..5bd9d11c53 100644
--- a/src/detection/os/os_windows.cpp
+++ b/src/detection/os/os_windows.cpp
@@ -26,6 +26,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
if(FFWmiRecord record = query.next())
{
record.getString(L"Caption", &os->variant);
+ ffStrbufTrimRight(&os->variant, ' ');
if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows "))
{
ffStrbufAppendS(&os->name, "Microsoft Windows");
diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c
index 3966240fdc..e1323e1e55 100644
--- a/src/detection/packages/packages_apple.c
+++ b/src/detection/packages/packages_apple.c
@@ -27,7 +27,7 @@ static uint32_t getNumElements(const char* dirname, unsigned char type)
static uint32_t countBrewPackages(const char* dirname)
{
- FFstrbuf baseDir;
+ FF_STRBUF_AUTO_DESTROY baseDir;
ffStrbufInitS(&baseDir, dirname);
uint32_t result = 0;
@@ -41,7 +41,6 @@ static uint32_t countBrewPackages(const char* dirname)
result += getNumElements(baseDir.chars, DT_DIR);
ffStrbufSubstrBefore(&baseDir, baseDirLength);
- ffStrbufDestroy(&baseDir);
return result;
}
@@ -59,14 +58,11 @@ static uint32_t getBrewPackages()
static uint32_t countMacPortsPackages(const char* dirname)
{
- FFstrbuf baseDir;
+ FF_STRBUF_AUTO_DESTROY baseDir;
ffStrbufInitS(&baseDir, dirname);
ffStrbufAppendS(&baseDir, "/var/macports/software");
- uint32_t result = getNumElements(baseDir.chars, DT_DIR);
-
- ffStrbufDestroy(&baseDir);
- return result;
+ return getNumElements(baseDir.chars, DT_DIR);
}
static uint32_t getMacPortsPackages()
diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c
index 015546ecf0..9daee1c917 100644
--- a/src/detection/temps/temps_apple.c
+++ b/src/detection/temps/temps_apple.c
@@ -104,12 +104,11 @@ static uint32_t smcStrtoul(const char *str, int size, int base)
static void smcUltostr(char *str, uint32_t val)
{
- str[0] = '\0';
- sprintf(str, "%c%c%c%c",
- (unsigned int)val >> 24,
- (unsigned int)val >> 16,
- (unsigned int)val >> 8,
- (unsigned int)val);
+ str[0] = (char)(val >> 24);
+ str[1] = (char)(val >> 16);
+ str[2] = (char)(val >> 8);
+ str[3] = (char)val;
+ str[4] = '\0';
}
static const char *smcCall(io_connect_t conn, uint32_t selector, SmcKeyData_t *inputStructure, SmcKeyData_t *outputStructure)
diff --git a/src/detection/terminalfont/terminalfont_android.c b/src/detection/terminalfont/terminalfont_android.c
index 8dd1ff2fe3..eaa4fa52d8 100644
--- a/src/detection/terminalfont/terminalfont_android.c
+++ b/src/detection/terminalfont/terminalfont_android.c
@@ -31,7 +31,7 @@ const char* detectTermux(const FFinstance* instance, FFTerminalFontResult* termi
goto exit;
}
- if(ffFT_New_Face(library, FF_TERMUX_FONT_PATH, 0, &face ))
+ if(ffFT_New_Face(library, FF_TERMUX_FONT_PATH, 0, &face))
{
error = "FT_NEW_Face(" FF_TERMUX_FONT_PATH ") failed";
goto exit;
@@ -49,7 +49,7 @@ const char* detectTermux(const FFinstance* instance, FFTerminalFontResult* termi
#else
FF_UNUSED(terminalFont);
- ffStrbufSetS(&terminalFont->error, "fastfetch is built without freetype2 support");
+ return "fastfetch is built without freetype2 support";
#endif
}
diff --git a/src/detection/terminalfont/terminalfont_apple.m b/src/detection/terminalfont/terminalfont_apple.m
index fb8c2769b3..1ee387aa27 100644
--- a/src/detection/terminalfont/terminalfont_apple.m
+++ b/src/detection/terminalfont/terminalfont_apple.m
@@ -22,7 +22,7 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi
error:&error];
if(error)
{
- ffStrbufAppendS(&terminalFont->error, [error localizedDescription].UTF8String);
+ ffStrbufAppendS(&terminalFont->error, error.localizedDescription.UTF8String);
return;
}
@@ -46,25 +46,42 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi
static void detectAppleTerminal(FFTerminalFontResult* terminalFont)
{
- FFstrbuf fontName;
- ffStrbufInit(&fontName);
- ffOsascript("tell application \"Terminal\" to font name of window frontmost", &fontName);
+ FF_STRBUF_AUTO_DESTROY font;
+ ffStrbufInit(&font);
+ ffOsascript("tell application \"Terminal\" to font name of window frontmost & \" \" & font size of window frontmost", &font);
- if(fontName.length == 0)
+ if(font.length == 0)
{
ffStrbufAppendS(&terminalFont->error, "executing osascript failed");
- ffStrbufDestroy(&fontName);
return;
}
- FFstrbuf fontSize;
- ffStrbufInit(&fontSize);
- ffOsascript("tell application \"Terminal\" to font size of window frontmost", &fontSize);
+ ffFontInitWithSpace(&terminalFont->font, font.chars);
+}
+
+static void detectWarpTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
+{
+ NSError* error;
+ NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/dev.warp.Warp-Stable.plist", instance->state.passwd->pw_dir];
+ NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
+ error:&error];
+ if(error)
+ {
+ ffStrbufAppendS(&terminalFont->error, error.localizedDescription.UTF8String);
+ return;
+ }
+
+ NSString* fontName = [dict valueForKey:@"FontName"];
+ if(!fontName)
+ fontName = @"Hack";
+ else
+ fontName = [fontName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]];
- ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
+ NSString* fontSize = [dict valueForKey:@"FontSize"];
+ if(!fontSize)
+ fontSize = @"13";
- ffStrbufDestroy(&fontName);
- ffStrbufDestroy(&fontSize);
+ ffFontInitValues(&terminalFont->font, fontName.UTF8String, fontSize.UTF8String);
}
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
@@ -73,4 +90,6 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh
detectIterm2(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Apple_Terminal") == 0)
detectAppleTerminal(terminalFont);
+ else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WarpTerminal") == 0)
+ detectWarpTerminal(instance, terminalFont);
}
diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c
index 6a68bb6a5f..e6ea456be2 100644
--- a/src/detection/terminalfont/terminalfont_windows.c
+++ b/src/detection/terminalfont/terminalfont_windows.c
@@ -1,4 +1,5 @@
#include "common/properties.h"
+#include "common/io.h"
#include "detection/terminalshell/terminalshell.h"
#include "terminalfont.h"
@@ -7,10 +8,10 @@
static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
- FFstrbuf fontName;
+ FF_STRBUF_AUTO_DESTROY fontName;
ffStrbufInit(&fontName);
- FFstrbuf fontSize;
+ FF_STRBUF_AUTO_DESTROY fontSize;
ffStrbufInit(&fontSize);
ffParsePropFileHomeValues(instance, ".minttyrc", 2, (FFpropquery[]) {
@@ -23,9 +24,12 @@ static void detectMintty(const FFinstance* instance, FFTerminalFontResult* termi
ffStrbufAppendC(&fontSize, '9');
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
+}
- ffStrbufDestroy(&fontName);
- ffStrbufDestroy(&fontSize);
+static inline void wrapRegCloseKey(HKEY* phKey)
+{
+ if(*phKey)
+ RegCloseKey(*phKey);
}
static void detectConhost(const FFinstance* instance, FFTerminalFontResult* terminalFont)
@@ -34,7 +38,7 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term
//Current font of conhost doesn't seem to be detectable, we detect default font instead
- HKEY hKey;
+ HKEY __attribute__((__cleanup__(wrapRegCloseKey))) hKey = NULL;
if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed");
@@ -43,34 +47,78 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term
DWORD bufSize;
- wchar_t fontNameW[64];
- bufSize = sizeof(fontNameW);
- if(RegQueryValueExW(hKey, L"FaceName", NULL, NULL, (LPBYTE)fontNameW, &bufSize) != ERROR_SUCCESS)
+ char fontName[128];
+ bufSize = sizeof(fontName);
+ if(RegGetValueA(hKey, NULL, "FaceName", RRF_RT_REG_SZ, NULL, fontName, &bufSize) != ERROR_SUCCESS)
{
- ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(FaceName) failed");
- goto exit;
+ ffStrbufAppendS(&terminalFont->error, "RegGetValueA(FaceName) failed");
+ return;
}
- fontNameW[bufSize] = '\0';
-
- char fontNameA[128];
- int fontNameALen = WideCharToMultiByte(CP_UTF8, 0, fontNameW, (int)(bufSize / 2), fontNameA, sizeof(fontNameA), NULL, NULL);
- fontNameA[fontNameALen] = '\0';
uint32_t fontSizeNum = 0;
bufSize = sizeof(fontSizeNum);
- if(RegQueryValueExW(hKey, L"fontSize", NULL, NULL, (LPBYTE)&fontSizeNum, &bufSize) != ERROR_SUCCESS)
+ if(RegGetValueW(hKey, NULL, L"FontSize", RRF_RT_DWORD, NULL, &fontSizeNum, &bufSize) != ERROR_SUCCESS)
{
- ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(fontSize) failed");
- goto exit;
+ ffStrbufAppendS(&terminalFont->error, "RegGetValueW(FontSize) failed");
+ return;
}
char fontSize[16];
- snprintf(fontSize, sizeof(fontSize), "%u", (fontSizeNum >> 16));
+ _ultoa((unsigned long)(fontSizeNum >> 16), fontSize, 10);
+
+ ffFontInitValues(&terminalFont->font, fontName, fontSize);
+}
+
+static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* terminalFont)
+{
+ FF_UNUSED(instance)
+
+ //https://conemu.github.io/en/ConEmuXml.html#search-sequence
+ FFstrbuf path;
+ ffStrbufInit(&path);
+
+ FFstrbuf fontName;
+ ffStrbufInit(&fontName);
+
+ FFstrbuf fontSize;
+ ffStrbufInit(&fontSize);
+
+ const char* paths[] = { "ConEmuDir", "ConEmuBaseDir", "APPDATA" };
+ for (uint32_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i)
+ {
+ ffStrbufSetS(&path, getenv(paths[i]));
+ if(path.length > 0)
+ {
+ ffStrbufAppendS(&path, "/ConEmu.xml");
+ if(ffParsePropFileValues(path.chars, 2, (FFpropquery[]){
+ {"error, "Failed to parse ConEmu.xml");
+ return;
+ }
+
+ if(fontName.length > 0)
+ ffStrbufSubstrBeforeLastC(&fontName, '"');
+ else
+ ffStrbufAppendS(&fontName, "Consola");
- ffFontInitValues(&terminalFont->font, fontNameA, fontSize);
+ if(fontSize.length > 0)
+ ffStrbufSubstrBeforeLastC(&fontSize, '"');
+ else
+ ffStrbufAppendS(&fontSize, "14");
-exit:
- RegCloseKey(hKey);
+ ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
+
+ ffStrbufDestroy(&fontName);
+ ffStrbufDestroy(&fontSize);
}
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
@@ -79,4 +127,6 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh
detectMintty(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0)
detectConhost(instance, terminalFont);
+ else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "ConEmuC"))
+ detectConEmu(instance, terminalFont);
}
diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c
index 57867fdb60..2c3e7319de 100644
--- a/src/detection/terminalshell/terminalshell_linux.c
+++ b/src/detection/terminalshell/terminalshell_linux.c
@@ -1,5 +1,4 @@
#include "fastfetch.h"
-#include "detection/host/host.h"
#include "common/io.h"
#include "common/parsing.h"
#include "common/processing.h"
@@ -180,10 +179,17 @@ 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 &&
+ !ffStrbufIgnCaseEqualS(&result->terminalProcessName, "(login)") &&
+
+ #ifdef __APPLE__
+ !ffStrbufIgnCaseEqualS(&result->terminalProcessName, "launchd") &&
+ !ffStrbufIgnCaseEqualS(&result->terminalProcessName, "stable") && //for WarpTerminal
+ #else
+ !ffStrbufIgnCaseEqualS(&result->terminalProcessName, "systemd") &&
+ !ffStrbufIgnCaseEqualS(&result->terminalProcessName, "init") &&
+ !ffStrbufIgnCaseEqualS(&result->terminalProcessName, "(init)") &&
+ #endif
+
ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0
) return;
@@ -193,11 +199,13 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
if(getenv("SSH_CONNECTION") != NULL)
term = getenv("SSH_TTY");
+ #ifdef __linux__
//Windows Terminal
if(!ffStrSet(term) && (
getenv("WT_SESSION") != NULL ||
getenv("WT_PROFILE_ID") != NULL
)) term = "Windows Terminal";
+ #endif
//Alacritty
if(!ffStrSet(term) && (
@@ -230,10 +238,8 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
if(!ffStrSet(term))
{
//We are in WSL but not in Windows Terminal
- const FFHostResult* host = ffDetectHost();
- if(ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_WSL) == 0 ||
- ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS) == 0) //TODO better WSL or MSYS detection
- term = "conhost";
+ if(getenv("WSL_DISTRO") != NULL || getenv("WSL_INTEROP") != NULL)
+ term = "conhost";
}
#endif
@@ -365,6 +371,8 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
ffStrbufInitS(&result.terminalPrettyName, "iTerm");
else if(ffStrbufEqualS(&result.terminalProcessName, "Apple_Terminal"))
ffStrbufInitS(&result.terminalPrettyName, "Apple Terminal");
+ else if(ffStrbufEqualS(&result.terminalProcessName, "WarpTerminal"))
+ ffStrbufInitS(&result.terminalPrettyName, "Warp");
else if(strncmp(result.terminalExeName, result.terminalProcessName.chars, result.terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName
ffStrbufInitS(&result.terminalPrettyName, result.terminalExeName);
else
diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp
index 770e043eb5..6f0139a2ee 100644
--- a/src/detection/terminalshell/terminalshell_windows.cpp
+++ b/src/detection/terminalshell/terminalshell_windows.cpp
@@ -189,6 +189,8 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid)
ffStrbufSetS(&result->terminalPrettyName, "Visual Studio Code");
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer"))
ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer");
+ else if(ffStrbufStartsWithIgnCaseS(&result->terminalPrettyName, "ConEmuC"))
+ ffStrbufSetS(&result->terminalPrettyName, "ConEmu");
return ppid;
}
diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c
index 7611f05dae..00303300d4 100644
--- a/src/detection/wmtheme/wmtheme_windows.c
+++ b/src/detection/wmtheme/wmtheme_windows.c
@@ -4,38 +4,67 @@
#define WIN32_LEAN_AND_MEAN 1
#include
+static inline void wrapRegCloseKey(HKEY* phKey)
+{
+ if(*phKey)
+ RegCloseKey(*phKey);
+}
+
bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError)
{
FF_UNUSED(instance);
- HKEY hKey;
- if(RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+ HKEY __attribute__((__cleanup__(wrapRegCloseKey))) hKey = NULL;
+ if(RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
- ffStrbufAppendS(themeOrError, "RegOpenKeyExW() failed");
- return false;
- }
+ int SystemUsesLightTheme = 1;
+ DWORD bufSize = sizeof(SystemUsesLightTheme);
- bool result = true;
- int SystemUsesLightTheme = 1;
- DWORD bufSize = sizeof(SystemUsesLightTheme);
+ if(RegGetValueW(hKey, NULL, L"SystemUsesLightTheme", RRF_RT_DWORD, NULL, &SystemUsesLightTheme, &bufSize) != ERROR_SUCCESS)
+ {
+ ffStrbufAppendS(themeOrError, "RegGetValueW(SystemUsesLightTheme) failed");
+ return false;
+ }
- if(RegQueryValueExW(hKey, L"SystemUsesLightTheme", NULL, NULL, (LPBYTE)&SystemUsesLightTheme, &bufSize) != ERROR_SUCCESS)
- {
- ffStrbufAppendS(themeOrError, "RegOpenKeyExW(SystemUsesLightTheme) failed");
- goto exit;
- }
+ 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;
+ }
- int AppsUsesLightTheme = 1;
- bufSize = sizeof(AppsUsesLightTheme);
- if(RegQueryValueExW(hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&AppsUsesLightTheme, &bufSize) != ERROR_SUCCESS)
- {
- ffStrbufAppendS(themeOrError, "RegOpenKeyExW(AppsUseLightTheme) failed");
- goto exit;
+ 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)
+ {
+ DWORD length = 0;
+ if(RegGetValueA(hKey, NULL, "CurrentTheme", RRF_RT_REG_SZ, NULL, NULL, &length) != ERROR_SUCCESS)
+ {
+ ffStrbufAppendS(themeOrError, "RegGetValueA(CurrentTheme, NULL) failed");
+ return false;
+ }
- ffStrbufAppendF(themeOrError, "System - %s, Apps - %s", SystemUsesLightTheme ? "Light" : "Dark", AppsUsesLightTheme ? "Light" : "Dark");
+ ffStrbufEnsureFree(themeOrError, length);
+ if(RegGetValueA(hKey, NULL, "CurrentTheme", RRF_RT_REG_SZ, NULL, themeOrError->chars, &length) != ERROR_SUCCESS)
+ {
+ ffStrbufAppendS(themeOrError, "RegGetValueA(CurrentTheme) failed");
+ return false;
+ }
-exit:
- RegCloseKey(hKey);
- return result;
+ themeOrError->length = length;
+ ffStrbufSubstrBeforeLastC(themeOrError, '.');
+ ffStrbufSubstrAfterLastC(themeOrError, '\\');
+ if (isalpha(themeOrError->chars[0]))
+ themeOrError->chars[0] = (char)toupper(themeOrError->chars[0]);
+
+ return true;
+ }
+ else
+ {
+ ffStrbufAppendS(themeOrError, "Failed to find current theme");
+ return false;
+ }
}
diff --git a/src/modules/gpu.c b/src/modules/gpu.c
index 11507191a4..905fd9774a 100644
--- a/src/modules/gpu.c
+++ b/src/modules/gpu.c
@@ -44,12 +44,6 @@ void ffPrintGPU(FFinstance* instance)
if(ffPrintFromCache(instance, FF_GPU_MODULE_NAME, &instance->config.gpu, FF_GPU_NUM_FORMAT_ARGS))
return;
- if(ffStrbufCompS(&ffDetectHost()->productName, FF_HOST_PRODUCT_NAME_WSL) == 0)
- {
- ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu, "WSL doesn't expose senseful GPU names");
- return;
- }
-
const FFlist* gpus = ffDetectGPU(instance);
if(gpus->length == 0)
diff --git a/src/util/FFlist.h b/src/util/FFlist.h
index d9d5167922..fd7a0f5ca6 100644
--- a/src/util/FFlist.h
+++ b/src/util/FFlist.h
@@ -45,4 +45,8 @@ static inline void ffListSort(FFlist* list, int(*compar)(const void*, const void
qsort(list->data, list->length, list->elementSize, compar);
}
+#if defined(_WIN32) || defined(__APPLE__)
+ #define FF_LIST_AUTO_DESTROY FFlist __attribute__((__cleanup__(ffListDestroy)))
+#endif
+
#endif
diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h
index 736e1d26da..80503e55d3 100644
--- a/src/util/FFstrbuf.h
+++ b/src/util/FFstrbuf.h
@@ -301,4 +301,9 @@ static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf
{
return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars);
}
+
+#if defined(_WIN32) || defined(__APPLE__)
+ #define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy)))
+#endif
+
#endif
diff --git a/src/util/apple/osascript.m b/src/util/apple/osascript.m
index 363a50d12d..8b01ba0697 100644
--- a/src/util/apple/osascript.m
+++ b/src/util/apple/osascript.m
@@ -4,14 +4,14 @@
#import
#import
-bool ffOsascript(const char* input, FFstrbuf* result) {
- NSString* appleScript = [NSString stringWithUTF8String: input];
- NSAppleScript* script = [[NSAppleScript alloc] initWithSource:appleScript];
+bool ffOsascript(const char* input, FFstrbuf* result)
+{
+ NSAppleScript* script = [NSAppleScript.alloc initWithSource:@(input)];
NSDictionary* errInfo = nil;
NSAppleEventDescriptor* descriptor = [script executeAndReturnError:&errInfo];
if (errInfo)
return false;
- ffStrbufSetS(result, [[descriptor stringValue] cStringUsingEncoding:NSUTF8StringEncoding]);
+ ffStrbufSetS(result, descriptor.stringValue.UTF8String);
return true;
}
diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c
index 07f6e52e81..a1f68021df 100644
--- a/src/util/windows/utsname.c
+++ b/src/util/windows/utsname.c
@@ -27,20 +27,22 @@ static int detectVersion(struct utsname *name)
DWORD bufSize;
- DWORD currentMajorVersionNumber;
- bufSize = sizeof(currentMajorVersionNumber);
- if(RegGetValueA(hKey, NULL, "CurrentMajorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMajorVersionNumber, &bufSize) != ERROR_SUCCESS)
- {
- RegCloseKey(hKey);
- return 1;
- }
+ char currentVersion[32];
- DWORD currentMinorVersionNumber;
- bufSize = sizeof(currentMinorVersionNumber);
- if(RegGetValueA(hKey, NULL, "CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMinorVersionNumber, &bufSize) != ERROR_SUCCESS)
{
- RegCloseKey(hKey);
- return 1;
+ DWORD currentMajorVersionNumber;
+ DWORD currentMinorVersionNumber;
+ bufSize = sizeof(currentMajorVersionNumber);
+ if(RegGetValueW(hKey, NULL, L"CurrentMajorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMajorVersionNumber, &bufSize) == ERROR_SUCCESS &&
+ RegGetValueW(hKey, NULL, L"CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMinorVersionNumber, &bufSize) == ERROR_SUCCESS
+ )
+ snprintf(currentVersion, sizeof(currentVersion), "%u.%u", (unsigned)currentMajorVersionNumber, (unsigned)currentMinorVersionNumber);
+ else
+ {
+ bufSize = sizeof(currentVersion);
+ if(RegGetValueA(hKey, NULL, "CurrentVersion", RRF_RT_REG_SZ, NULL, currentVersion, &bufSize) != ERROR_SUCCESS)
+ strcpy(currentVersion, "0.0");
+ }
}
char currentBuildNumber[32];
@@ -53,7 +55,7 @@ static int detectVersion(struct utsname *name)
if(RegGetValueA(hKey, NULL, "UBR", RRF_RT_REG_DWORD, NULL, &ubr, &bufSize) != ERROR_SUCCESS || bufSize != sizeof(ubr))
ubr = 0;
- snprintf(name->release, sizeof(name->release), "%u.%u.%s.%u", (unsigned)currentMajorVersionNumber, (unsigned)currentMinorVersionNumber, currentBuildNumber, (unsigned)ubr);
+ snprintf(name->release, sizeof(name->release), "%s.%s.%u", currentVersion, currentBuildNumber, (unsigned)ubr);
bufSize = sizeof(name->version);
RegGetValueA(hKey, NULL, "DisplayVersion", RRF_RT_REG_SZ, NULL, name->version, &bufSize);
diff --git a/src/util/windows/version.rc.in b/src/util/windows/version.rc.in
new file mode 100644
index 0000000000..3e1833eec4
--- /dev/null
+++ b/src/util/windows/version.rc.in
@@ -0,0 +1,47 @@
+//
+// Include the necessary resources
+//
+#include
+#include
+
+#ifdef RC_INVOKED
+
+//
+// Set up debug information
+//
+#if DEBUG
+#define VER_DEBUG VS_FF_DEBUG
+#else
+#define VER_DEBUG 0
+#endif
+
+// ------- version info -------------------------------------------------------
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,@PROJECT_VERSION_TWEAK_NUM@
+PRODUCTVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,@PROJECT_VERSION_TWEAK_NUM@
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEFLAGS (VER_DEBUG|VS_FF_PRERELEASE)
+FILEOS VOS_NT
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "@PROJECT_HOMEPAGE_URL@"
+ VALUE "FileDescription", "@PROJECT_DESCRIPTION@"
+ VALUE "FileVersion", "@PROJECT_VERSION@@PROJECT_VERSION_TWEAK@"
+ VALUE "InternalName", "@TARGET_NAME@.exe"
+ VALUE "LegalCopyright", "@PROJECT_LICENSE@"
+ VALUE "OriginalFilename", "@TARGET_NAME@.exe"
+ VALUE "ProductName", "@PROJECT_NAME@"
+ VALUE "ProductVersion", "@PROJECT_VERSION@@PROJECT_VERSION_TWEAK@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409,1252
+ END
+END
+#endif
diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp
index 6a273f86a4..cba0c07c55 100644
--- a/src/util/windows/wmi.cpp
+++ b/src/util/windows/wmi.cpp
@@ -128,7 +128,7 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error)
if (InitOnceExecuteOnce(&s_InitOnce, &InitHandleFunction, nullptr, (void**)&context) == FALSE)
{
if(error)
- ffStrbufInitS(error, context);
+ ffStrbufAppendS(error, context);
return;
}
diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp
index 7b27c75904..6f7d214cb9 100644
--- a/src/util/windows/wmi.hpp
+++ b/src/util/windows/wmi.hpp
@@ -23,12 +23,15 @@ struct FFWmiRecord
if(!ok) obj = nullptr;
}
FFWmiRecord(const FFWmiRecord&) = delete;
- FFWmiRecord(FFWmiRecord&& other) {
+ FFWmiRecord(FFWmiRecord&& other) { *this = (FFWmiRecord&&)other; }
+ ~FFWmiRecord() { if(obj) obj->Release(); }
+ explicit operator bool() { return !!obj; }
+ FFWmiRecord& operator =(FFWmiRecord&& other) {
+ if(obj) obj->Release();
obj = other.obj;
other.obj = nullptr;
+ return *this;
}
- ~FFWmiRecord() { if(obj) obj->Release(); }
- explicit operator bool() { return !!obj; }
bool getString(const wchar_t* key, FFstrbuf* strbuf);
bool getSigned(const wchar_t* key, int64_t* integer);
@@ -43,13 +46,16 @@ struct FFWmiQuery
FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error = nullptr);
explicit FFWmiQuery(IEnumWbemClassObject* pEnumerator): pEnumerator(pEnumerator) {}
FFWmiQuery(const FFWmiQuery& other) = delete;
- FFWmiQuery(FFWmiQuery&& other) {
- pEnumerator = other.pEnumerator;
- other.pEnumerator = nullptr;
- }
+ FFWmiQuery(FFWmiQuery&& other) { *this = (FFWmiQuery&&)other; }
~FFWmiQuery() { if(pEnumerator) pEnumerator->Release(); }
explicit operator bool() { return !!pEnumerator; }
+ FFWmiQuery& operator =(FFWmiQuery&& other) {
+ if(pEnumerator) pEnumerator->Release();
+ pEnumerator = other.pEnumerator;
+ other.pEnumerator = nullptr;
+ return *this;
+ }
FFWmiRecord next() {
FFWmiRecord result(pEnumerator);