From eaa4230bf59bb0678efdceca3b0b8a362788a758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 2 Oct 2022 17:52:09 +0800 Subject: [PATCH 001/311] Windows: add basic support for msys2 --- CMakeLists.txt | 9 ++++--- README.md | 4 +-- src/common/init.c | 2 +- src/detection/cpuUsage/cpuUsage_linux.c | 2 +- src/detection/host/host.h | 1 + src/detection/host/host_linux.c | 14 ++++++----- src/detection/terminalShell.c | 14 ++++++----- .../terminalfont/terminalfont_linux.c | 25 +++++++++++++++++++ 8 files changed, 52 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ad108cd95..140ff0620 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,12 +11,12 @@ project(fastfetch # Target Platform # ################### -if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") +if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*|MSYS") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) elseif(NOT APPLE AND NOT ANDROID) - message(FATAL_ERROR "Unsupported platform") + message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() ##################### @@ -82,7 +82,10 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,$ENV{HOMEBREW_PREFIX}/lib") endif() -set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined") +set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer") +if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "MSYS") + set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined") +endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG} -rdynamic") diff --git a/README.md b/README.md index 8eb20f122..8f834a886 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, BSD and MacOS 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, BSD, MacOS and Windows on [MSYS2](https://www.msys2.org/) are supported. @@ -82,7 +82,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 +Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, TTY, Windows Terminal, Termux, mintty ``` ## Building diff --git a/src/common/init.c b/src/common/init.c index ec5dab5d3..5971b916d 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -257,7 +257,7 @@ void ffInitInstance(FFinstance* instance) defaultConfig(instance); } -#if !defined(__ANDROID__) +#if !defined(__ANDROID__) && !defined(__CYGWIN__) static void* connectDisplayServerThreadMain(void* instance) { diff --git a/src/detection/cpuUsage/cpuUsage_linux.c b/src/detection/cpuUsage/cpuUsage_linux.c index 3696a8d77..c3e9b37aa 100644 --- a/src/detection/cpuUsage/cpuUsage_linux.c +++ b/src/detection/cpuUsage/cpuUsage_linux.c @@ -5,7 +5,7 @@ const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll) { - long user, nice, system, idle, iowait, irq, softirq; + long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; FILE* procStat = fopen("/proc/stat", "r"); if(procStat == NULL) diff --git a/src/detection/host/host.h b/src/detection/host/host.h index cdf2fbf53..02a1b9e6a 100644 --- a/src/detection/host/host.h +++ b/src/detection/host/host.h @@ -6,6 +6,7 @@ #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 { diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c index 80e048ae7..400d7f856 100644 --- a/src/detection/host/host_linux.c +++ b/src/detection/host/host_linux.c @@ -109,10 +109,12 @@ void ffDetectHostImpl(FFHostResult* host) if(ffStrbufStartsWithS(&host->productName, "Standard PC")) ffStrbufPrependS(&host->productName, "KVM/QEMU "); - //On WSL, the real host can't be detected. Instead use WSL as host. - if(host->productFamily.length == 0 && host->productName.length == 0 && ( - getenv("WSLENV") != NULL || - getenv("WSL_DISTRO") != NULL || - getenv("WSL_INTEROP") != NULL - )) ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_WSL); + if(host->productFamily.length == 0 && host->productName.length == 0) + { + //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); + else if(getenv("MSYSTEM") != NULL && strcmp(getenv("MSYSTEM"), "MSYS") == 0) + ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS); + } } diff --git a/src/detection/terminalShell.c b/src/detection/terminalShell.c index cd3785a0f..26c37e159 100644 --- a/src/detection/terminalShell.c +++ b/src/detection/terminalShell.c @@ -1,4 +1,5 @@ #include "fastfetch.h" +#include "detection/host/host.h" #include "detection/terminalshell.h" #include "common/io.h" #include "common/parsing.h" @@ -149,17 +150,18 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) getenv("KONSOLE_VERSION") != NULL )) term = "konsole"; - //MacOS + //MacOS, mintty if(!ffStrSet(term)) term = getenv("TERM_PROGRAM"); //We are in WSL but not in Windows Terminal - if(!ffStrSet(term) && ( - getenv("WSLENV") != NULL || - getenv("WSL_DISTRO") != NULL || - getenv("WSL_INTEROP") != NULL - )) + if(!ffStrSet(term)) + { + const FFHostResult* host = ffDetectHost(); + if(ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_WSL) == 0 || + ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS) == 0) term = "conhost"; + } //Normal Terminal if(!ffStrSet(term)) diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index f68d45744..ac3bb3a6a 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -312,6 +312,29 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFon #endif +static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + FFstrbuf fontName; + ffStrbufInit(&fontName); + + FFstrbuf fontSize; + ffStrbufInit(&fontSize); + + ffParsePropFileHomeValues(instance, ".minttyrc", 2, (FFpropquery[]) { + {"Font=", &fontName}, + {"FontHeight=", &fontSize} + }); + if(fontName.length == 0) + ffStrbufAppendS(&fontName, "Lucida Console"); + if(fontSize.length == 0) + ffStrbufAppendC(&fontSize, '9'); + + ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&fontSize); +} + void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0) @@ -326,4 +349,6 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0) detectFromWindowsTeriminal(instance, terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0) + detectMintty(instance, terminalFont); } From db88d413c3ff9dc2e51cdfdaa2dc9ee9f75387ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 3 Oct 2022 00:28:59 +0800 Subject: [PATCH 002/311] TerminalFont: print error on failing --- src/detection/terminalfont/terminalfont_linux.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index ac3bb3a6a..24a62e9d5 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -292,12 +292,17 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFon FFstrbuf name; ffStrbufInit(&name); int size = -1; - detectFromWTImpl(instance, &json, &name, &size); + error = detectFromWTImpl(instance, &json, &name, &size); ffStrbufDestroy(&json); - char sizeStr[16]; - snprintf(sizeStr, sizeof(sizeStr), "%d", size); - ffFontInitValues(&terminalFont->font, name.chars, sizeStr); + if(error) + ffStrbufAppendS(&terminalFont->error, error); + else + { + char sizeStr[16]; + snprintf(sizeStr, sizeof(sizeStr), "%d", size); + ffFontInitValues(&terminalFont->font, name.chars, sizeStr); + } ffStrbufDestroy(&name); } From c7e6e45078448a36d72c9ac47ae44efb3d20fad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Oct 2022 00:41:43 +0800 Subject: [PATCH 003/311] Host: split Bios module; init support for Windows --- CMakeLists.txt | 47 ++++- src/common/init.c | 1 + src/detection/bios/bios.h | 19 ++ src/detection/bios/bios_android.c | 11 + src/detection/bios/bios_apple.c | 11 + src/detection/bios/bios_linux.c | 58 +++++ src/detection/bios/bios_windows.cpp | 38 ++++ .../displayserver/displayserver_windows.c | 14 ++ src/detection/host/host.h | 5 +- src/detection/host/host_android.c | 6 +- src/detection/host/host_apple.c | 10 +- src/detection/host/host_linux.c | 14 +- src/detection/host/host_windows.cpp | 45 ++++ src/detection/terminalShell.c | 2 +- src/fastfetch.c | 23 +- src/fastfetch.h | 2 + src/flashfetch.c | 1 + src/modules/bios.c | 42 ++++ src/modules/host.c | 12 +- src/util/windows/wmi.cpp | 199 ++++++++++++++++++ src/util/windows/wmi.hpp | 43 ++++ 21 files changed, 559 insertions(+), 44 deletions(-) create mode 100644 src/detection/bios/bios.h create mode 100644 src/detection/bios/bios_android.c create mode 100644 src/detection/bios/bios_apple.c create mode 100644 src/detection/bios/bios_linux.c create mode 100644 src/detection/bios/bios_windows.cpp create mode 100644 src/detection/displayserver/displayserver_windows.c create mode 100644 src/detection/host/host_windows.cpp create mode 100644 src/modules/bios.c create mode 100644 src/util/windows/wmi.cpp create mode 100644 src/util/windows/wmi.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 140ff0620..7dc7ee21c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs project(fastfetch VERSION 1.7.2 - LANGUAGES C + LANGUAGES C CXX # Windows part requires C++ compiler DESCRIPTION "Fast system information tool" HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch" ) @@ -11,8 +11,10 @@ project(fastfetch # Target Platform # ################### -if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*|MSYS") +if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel +elseif("${CMAKE_SYSTEM_NAME}" MATCHES "MSYS") + set(WIN_MSYS TRUE CACHE BOOL "..." FORCE) # Windows on msys2 elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) elseif(NOT APPLE AND NOT ANDROID) @@ -26,7 +28,7 @@ endif() include(CMakeDependentOption) cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD" OFF) +cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN_MSYS" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF) @@ -46,7 +48,7 @@ cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX" OFF) +cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN_MSYS" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) option(BUILD_TESTS "Build tests" OFF) # Also create test executables @@ -76,6 +78,11 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") +if(WIN_MSYS) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion") +endif() + # Used for dlopen finding dylibs installed by homebrew # `/opt/homebrew/lib` is not on in dlopen search path by default if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) @@ -83,7 +90,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) endif() set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer") -if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "MSYS") +if(NOT WIN_MSYS) set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") @@ -216,6 +223,7 @@ set(LIBFASTFETCH_SRC src/modules/separator.c src/modules/os.c src/modules/host.c + src/modules/bios.c src/modules/kernel.c src/modules/uptime.c src/modules/processes.c @@ -260,14 +268,14 @@ if(BSD OR APPLE) ) endif() -if(LINUX OR ANDROID) +if(LINUX OR ANDROID OR WIN_MSYS) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c ) endif() -if(LINUX OR ANDROID OR BSD) +if(LINUX OR ANDROID OR BSD OR WIN_MSYS) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c @@ -279,6 +287,7 @@ endif() if(LINUX OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/host/host_linux.c + src/detection/bios/bios_linux.c src/detection/os/os_linux.c src/detection/gpu/gpu_linux.c src/detection/battery/battery_linux.c @@ -294,12 +303,29 @@ if(LINUX OR BSD) ) endif() +if(WIN_MSYS) + list(APPEND LIBFASTFETCH_SRC + src/detection/host/host_windows.cpp + src/detection/bios/bios_windows.cpp + src/detection/os/os_linux.c + src/detection/gpu/gpu_linux.c + src/detection/battery/battery_linux.c + src/detection/displayserver/displayserver_windows.c + src/detection/terminalfont/terminalfont_linux.c + src/detection/media/media_linux.c + src/detection/wmtheme/wmtheme_linux.c + src/detection/font/font_linux.c + src/util/windows/wmi.cpp + ) +endif() + if(APPLE) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_apple.c src/util/apple/cf_helpers.c src/util/apple/osascript.m src/detection/host/host_apple.c + src/detection/bios/bios_apple.c src/detection/os/os_apple.m src/detection/cpu/cpu_apple.c src/detection/gpu/gpu_apple.c @@ -326,6 +352,7 @@ endif() if(ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/host/host_android.c + src/detection/bios/bios_android.c src/detection/os/os_android.c src/detection/gpu/gpu_android.c src/detection/battery/battery_android.c @@ -411,6 +438,12 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" ) +elseif(WIN_MSYS) + target_link_libraries(libfastfetch + PRIVATE "-lwbemuuid" + PRIVATE "-lole32" + PRIVATE "-loleaut32" + ) endif() target_include_directories(libfastfetch diff --git a/src/common/init.c b/src/common/init.c index 5971b916d..a1498c50f 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -162,6 +162,7 @@ static void defaultConfig(FFinstance* instance) initModuleArg(&instance->config.os); initModuleArg(&instance->config.host); + initModuleArg(&instance->config.bios); initModuleArg(&instance->config.kernel); initModuleArg(&instance->config.uptime); initModuleArg(&instance->config.processes); diff --git a/src/detection/bios/bios.h b/src/detection/bios/bios.h new file mode 100644 index 000000000..6f664b4b2 --- /dev/null +++ b/src/detection/bios/bios.h @@ -0,0 +1,19 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_bios_bios +#define FF_INCLUDED_detection_bios_bios + +#include "fastfetch.h" + +typedef struct FFBiosResult +{ + FFstrbuf biosDate; + FFstrbuf biosRelease; + FFstrbuf biosVendor; + FFstrbuf biosVersion; + FFstrbuf error; +} FFBiosResult; + +void ffDetectBios(FFBiosResult* bios); + +#endif diff --git a/src/detection/bios/bios_android.c b/src/detection/bios/bios_android.c new file mode 100644 index 000000000..c767f3616 --- /dev/null +++ b/src/detection/bios/bios_android.c @@ -0,0 +1,11 @@ +#include "bios.h" + +void ffDetectBios(FFBiosResult* bios) +{ + ffStrbufInitS(&bios->error, "Not supported on Android"); + + ffStrbufInit(&bios->biosDate); + ffStrbufInit(&bios->biosRelease); + ffStrbufInit(&bios->biosVendor); + ffStrbufInit(&bios->biosVersion); +} diff --git a/src/detection/bios/bios_apple.c b/src/detection/bios/bios_apple.c new file mode 100644 index 000000000..f22dca253 --- /dev/null +++ b/src/detection/bios/bios_apple.c @@ -0,0 +1,11 @@ +#include "bios.h" + +void ffDetectBios(FFBiosResult* bios) +{ + ffStrbufInitS(&bios->error, "Not supported on macOS"); + + ffStrbufInit(&bios->biosDate); + ffStrbufInit(&bios->biosRelease); + ffStrbufInit(&bios->biosVendor); + ffStrbufInit(&bios->biosVersion); +} diff --git a/src/detection/bios/bios_linux.c b/src/detection/bios/bios_linux.c new file mode 100644 index 000000000..10bbab589 --- /dev/null +++ b/src/detection/bios/bios_linux.c @@ -0,0 +1,58 @@ +#include "bios.h" +#include "common/io.h" + +#include + +static bool hostValueSet(FFstrbuf* value) +{ + return + value->length > 0 && + ffStrbufStartsWithIgnCaseS(value, "To be filled") != true && + ffStrbufStartsWithIgnCaseS(value, "To be set") != true && + ffStrbufStartsWithIgnCaseS(value, "OEM") != true && + ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true && + ffStrbufIgnCaseCompS(value, "None") != 0 && + ffStrbufIgnCaseCompS(value, "System Product") != 0 && + ffStrbufIgnCaseCompS(value, "System Product Name") != 0 && + ffStrbufIgnCaseCompS(value, "System Product Version") != 0 && + ffStrbufIgnCaseCompS(value, "System Name") != 0 && + ffStrbufIgnCaseCompS(value, "System Version") != 0 && + ffStrbufIgnCaseCompS(value, "Default string") != 0 && + ffStrbufIgnCaseCompS(value, "Undefined") != 0 && + ffStrbufIgnCaseCompS(value, "Not Specified") != 0 && + ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 && + ffStrbufIgnCaseCompS(value, "INVALID") != 0 && + ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 && + ffStrbufIgnCaseCompS(value, "All Series") != 0 + ; +} + +static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) +{ + ffReadFileBuffer(devicesPath, buffer); + if(hostValueSet(buffer)) + return; + + ffReadFileBuffer(classPath, buffer); + if(hostValueSet(buffer)) + return; + + ffStrbufClear(buffer); +} + +void ffDetectBios(FFBiosResult* bios) +{ + ffStrbufInit(&bios->error); + + ffStrbufInit(&bios->biosDate); + getHostValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->biosDate); + + ffStrbufInit(&bios->biosRelease); + getHostValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->biosRelease); + + ffStrbufInit(&bios->biosVendor); + getHostValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->biosVendor); + + ffStrbufInit(&bios->biosVersion); + getHostValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->biosVersion); +} diff --git a/src/detection/bios/bios_windows.cpp b/src/detection/bios/bios_windows.cpp new file mode 100644 index 000000000..6f1dedbb8 --- /dev/null +++ b/src/detection/bios/bios_windows.cpp @@ -0,0 +1,38 @@ +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); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + + if(uReturn == 0) + { + ffStrbufInitS(&bios->error, "No Wmi result returned"); + pEnumerator->Release(); + return; + } + + ffGetWmiObjValue(pclsObj, L"Name", &bios->biosRelease); + ffGetWmiObjValue(pclsObj, L"ReleaseDate", &bios->biosDate); + ffGetWmiObjValue(pclsObj, L"Version", &bios->biosVersion); + ffGetWmiObjValue(pclsObj, L"Manufacturer", &bios->biosVendor); + + pclsObj->Release(); + pEnumerator->Release(); +} diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c new file mode 100644 index 000000000..8427c7cb2 --- /dev/null +++ b/src/detection/displayserver/displayserver_windows.c @@ -0,0 +1,14 @@ +#include "displayserver.h" + +void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) +{ + FF_UNUSED(instance); + + ffStrbufInitA(&ds->wmProcessName, 0); + ffStrbufInitA(&ds->wmPrettyName, 0); + ffStrbufInitA(&ds->wmProtocolName, 0); + ffStrbufInitA(&ds->deProcessName, 0); + ffStrbufInitA(&ds->dePrettyName, 0); + ffStrbufInitA(&ds->deVersion, 0); + ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 0); +} diff --git a/src/detection/host/host.h b/src/detection/host/host.h index 02a1b9e6a..73e192d70 100644 --- a/src/detection/host/host.h +++ b/src/detection/host/host.h @@ -14,10 +14,6 @@ typedef struct FFHostResult FFstrbuf productName; FFstrbuf productVersion; FFstrbuf productSku; - FFstrbuf biosDate; - FFstrbuf biosRelease; - FFstrbuf biosVendor; - FFstrbuf biosVersion; FFstrbuf boardName; FFstrbuf boardVendor; FFstrbuf boardVersion; @@ -25,6 +21,7 @@ typedef struct FFHostResult FFstrbuf chassisVendor; FFstrbuf chassisVersion; FFstrbuf sysVendor; + FFstrbuf error; } FFHostResult; const FFHostResult* ffDetectHost(); diff --git a/src/detection/host/host_android.c b/src/detection/host/host_android.c index 1f2f10c11..edf807e73 100644 --- a/src/detection/host/host_android.c +++ b/src/detection/host/host_android.c @@ -4,6 +4,8 @@ void ffDetectHostImpl(FFHostResult* host) { + ffStrbufInit(&host->error); + //Family ffStrbufInit(&host->productFamily); @@ -32,10 +34,6 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInitA(&host->productVersion, 0); ffStrbufInitA(&host->productSku, 0); - ffStrbufInitA(&host->biosDate, 0); - ffStrbufInitA(&host->biosRelease, 0); - ffStrbufInitA(&host->biosVendor, 0); - ffStrbufInitA(&host->biosVersion, 0); ffStrbufInitA(&host->boardName, 0); ffStrbufInitA(&host->boardVendor, 0); ffStrbufInitA(&host->boardVersion, 0); diff --git a/src/detection/host/host_apple.c b/src/detection/host/host_apple.c index f39edf0e0..d552bd232 100644 --- a/src/detection/host/host_apple.c +++ b/src/detection/host/host_apple.c @@ -112,16 +112,14 @@ static const char* getProductName(const FFstrbuf* hwModel) void ffDetectHostImpl(FFHostResult* host) { + ffStrbufInit(&host->error); + ffStrbufInit(&host->productName); ffStrbufInit(&host->productFamily); + ffStrbufInit(&host->productVersion); + ffStrbufInit(&host->productSku); ffStrbufInitA(&host->sysVendor, 0); - ffStrbufInitA(&host->productVersion, 0); - ffStrbufInitA(&host->productSku, 0); - ffStrbufInitA(&host->biosDate, 0); - ffStrbufInitA(&host->biosRelease, 0); - ffStrbufInitA(&host->biosVendor, 0); - ffStrbufInitA(&host->biosVersion, 0); ffStrbufInitA(&host->boardName, 0); ffStrbufInitA(&host->boardVendor, 0); ffStrbufInitA(&host->boardVersion, 0); diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c index 400d7f856..0bf9d7978 100644 --- a/src/detection/host/host_linux.c +++ b/src/detection/host/host_linux.c @@ -60,6 +60,8 @@ static void getHostProductName(FFstrbuf* name) void ffDetectHostImpl(FFHostResult* host) { + ffStrbufInit(&host->error); + ffStrbufInit(&host->productFamily); getHostValue("/sys/devices/virtual/dmi/id/product_family", "/sys/class/dmi/id/product_family", &host->productFamily); @@ -72,18 +74,6 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productSku); getHostValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku); - ffStrbufInit(&host->biosDate); - getHostValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &host->biosDate); - - ffStrbufInit(&host->biosRelease); - getHostValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &host->biosRelease); - - ffStrbufInit(&host->biosVendor); - getHostValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &host->biosVendor); - - ffStrbufInit(&host->biosVersion); - getHostValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &host->biosVersion); - ffStrbufInit(&host->boardName); getHostValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &host->boardName); diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp new file mode 100644 index 000000000..4a106cbd7 --- /dev/null +++ b/src/detection/host/host_windows.cpp @@ -0,0 +1,45 @@ +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->boardName); + ffStrbufInit(&host->boardVendor); + ffStrbufInit(&host->boardVersion); + ffStrbufInit(&host->chassisType); + ffStrbufInit(&host->chassisVendor); + ffStrbufInit(&host->chassisVersion); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + + if(uReturn == 0) + { + ffStrbufInitS(&host->error, "No Wmi result returned"); + pEnumerator->Release(); + return; + } + + ffGetWmiObjValue(pclsObj, L"Name", &host->productName); + ffGetWmiObjValue(pclsObj, L"Version", &host->productVersion); + ffGetWmiObjValue(pclsObj, L"SKUNumber", &host->productSku); + ffGetWmiObjValue(pclsObj, L"Vendor", &host->sysVendor); + + pclsObj->Release(); + pEnumerator->Release(); +} diff --git a/src/detection/terminalShell.c b/src/detection/terminalShell.c index 26c37e159..9ebe8bee1 100644 --- a/src/detection/terminalShell.c +++ b/src/detection/terminalShell.c @@ -159,7 +159,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) { const FFHostResult* host = ffDetectHost(); if(ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_WSL) == 0 || - ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS) == 0) + ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS) == 0) //TODO better WSL or MSYS detection term = "conhost"; } diff --git a/src/fastfetch.c b/src/fastfetch.c index dd6f7ff86..40d0eb0e6 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -71,15 +71,11 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "host-format") == 0) { - constructAndPrintCommandHelpFormat("host", "{2} {3}", 15, + constructAndPrintCommandHelpFormat("host", "{2} {3}", 11, "product family", "product name", "product version", "product sku", - "bios date", - "bios release", - "bios vendor", - "bios version", "board name", "board vendor", "board version", @@ -89,6 +85,15 @@ static inline void printCommandHelp(const char* command) "sys vendor" ); } + else if(strcasecmp(command, "bios-format") == 0) + { + constructAndPrintCommandHelpFormat("bios", "{2} {3}", 4, + "bios date", + "bios release", + "bios vendor", + "bios version" + ); + } else if(strcasecmp(command, "kernel-format") == 0) { constructAndPrintCommandHelpFormat("kernel", "{2}", 3, @@ -978,6 +983,12 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.host.outputFormat); else if(strcasecmp(key, "--host-error") == 0) optionParseString(key, value, &instance->config.host.errorFormat); + else if(strcasecmp(key, "--bios-key") == 0) + optionParseString(key, value, &instance->config.bios.key); + else if(strcasecmp(key, "--bios-format") == 0) + optionParseString(key, value, &instance->config.bios.outputFormat); + else if(strcasecmp(key, "--bios-error") == 0) + optionParseString(key, value, &instance->config.bios.errorFormat); else if(strcasecmp(key, "--kernel-key") == 0) optionParseString(key, value, &instance->config.kernel.key); else if(strcasecmp(key, "--kernel-format") == 0) @@ -1367,6 +1378,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char ffPrintOS(instance); else if(strcasecmp(line, "host") == 0) ffPrintHost(instance); + else if(strcasecmp(line, "bios") == 0) + ffPrintBios(instance); else if(strcasecmp(line, "kernel") == 0) ffPrintKernel(instance); else if(strcasecmp(line, "uptime") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index f466d59e5..e40ca95a9 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -94,6 +94,7 @@ typedef struct FFconfig FFModuleArgs os; FFModuleArgs host; + FFModuleArgs bios; FFModuleArgs kernel; FFModuleArgs uptime; FFModuleArgs processes; @@ -249,6 +250,7 @@ void ffPrintTitle(FFinstance* instance); void ffPrintSeparator(FFinstance* instance); void ffPrintOS(FFinstance* instance); void ffPrintHost(FFinstance* instance); +void ffPrintBios(FFinstance* instance); void ffPrintKernel(FFinstance* instance); void ffPrintUptime(FFinstance* instance); void ffPrintProcesses(FFinstance* instance); diff --git a/src/flashfetch.c b/src/flashfetch.c index e20b2aa1b..778fcca23 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -22,6 +22,7 @@ int main(int argc, char** argv) ffPrintSeparator(&instance); ffPrintOS(&instance); ffPrintHost(&instance); + //ffPrintBios(&instance); ffPrintKernel(&instance); ffPrintUptime(&instance); //ffPrintProcesses(&instance); diff --git a/src/modules/bios.c b/src/modules/bios.c new file mode 100644 index 000000000..3e443a389 --- /dev/null +++ b/src/modules/bios.c @@ -0,0 +1,42 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/caching.h" +#include "detection/bios/bios.h" + +#define FF_BIOS_MODULE_NAME "Bios" +#define FF_BIOS_NUM_FORMAT_ARGS 4 + +void ffPrintBios(FFinstance* instance) +{ + if(ffPrintFromCache(instance, FF_BIOS_MODULE_NAME, &instance->config.bios, FF_BIOS_NUM_FORMAT_ARGS)) + return; + + FFBiosResult result; + ffDetectBios(&result); + + if(result.error.length > 0) + { + ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "%*s", result.error.length, result.error.chars); + goto exit; + } + + if(result.biosRelease.length == 0) + { + ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "bios_release is not set."); + goto exit; + } + + ffPrintAndWriteToCache(instance, FF_BIOS_MODULE_NAME, &instance->config.bios, &result.biosRelease, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosDate}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosRelease}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVersion}, + }); + +exit: + ffStrbufDestroy(&result.biosDate); + ffStrbufDestroy(&result.biosRelease); + ffStrbufDestroy(&result.biosVendor); + ffStrbufDestroy(&result.biosVersion); + ffStrbufDestroy(&result.error); +} diff --git a/src/modules/host.c b/src/modules/host.c index 1a5b8dae6..c7bdd969e 100644 --- a/src/modules/host.c +++ b/src/modules/host.c @@ -4,7 +4,7 @@ #include "detection/host/host.h" #define FF_HOST_MODULE_NAME "Host" -#define FF_HOST_NUM_FORMAT_ARGS 15 +#define FF_HOST_NUM_FORMAT_ARGS 11 void ffPrintHost(FFinstance* instance) { @@ -13,6 +13,12 @@ void ffPrintHost(FFinstance* instance) const FFHostResult* host = ffDetectHost(); + if(host->error.length > 0) + { + ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "%*s", host->error.length, host->error.chars); + return; + } + if(host->productFamily.length == 0 && host->productName.length == 0) { ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "neither product_family nor product_name is set by O.E.M."); @@ -38,10 +44,6 @@ void ffPrintHost(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->biosDate}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->biosRelease}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->biosVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->biosVersion}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->boardName}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->boardVendor}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->boardVersion}, diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp new file mode 100644 index 000000000..a4938643d --- /dev/null +++ b/src/util/windows/wmi.cpp @@ -0,0 +1,199 @@ +#include "wmi.hpp" + +#include + +//https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer +//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes +static void CoUninitializeWrap() +{ + CoUninitialize(); +} + +static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) +{ + static char error[128]; + *((char**)lpContext) = error; + + HRESULT hres; + + // Initialize COM + hres = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + // Set general COM security levels + hres = CoInitializeSecurity( + nullptr, + -1, // COM authentication + nullptr, // Authentication services + nullptr, // Reserved + RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication + RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation + nullptr, // Authentication info + EOAC_NONE, // Additional capabilities + nullptr // Reserved + ); + + if (FAILED(hres)) + { + CoUninitialize(); + snprintf(error, sizeof(error), "Failed to initialize security. Error code = 0x%X", hres); + return FALSE; + } + + // Obtain the initial locator to WMI + IWbemLocator* pLoc = nullptr; + hres = CoCreateInstance( + CLSID_WbemLocator, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, + (LPVOID*) &pLoc); + + if (FAILED(hres)) + { + CoUninitialize(); + snprintf(error, sizeof(error), "Failed to create IWbemLocator object. Error code = 0x%X", hres); + return FALSE; + } + + // Connect to WMI through the IWbemLocator::ConnectServer method + IWbemServices* pSvc = nullptr; + + // Connect to the root\cimv2 namespace with + // the current user and obtain pointer pSvc + // to make IWbemServices calls. + hres = pLoc->ConnectServer( + bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace + nullptr, // User name. nullptr = current user + nullptr, // User password. nullptr = current + 0, // Locale. nullptr indicates current + 0, // Security flags. + 0, // Authority (for example, Kerberos) + 0, // Context object + &pSvc // pointer to IWbemServices proxy + ); + pLoc->Release(); + pLoc = nullptr; + + if (FAILED(hres)) + { + CoUninitialize(); + snprintf(error, sizeof(error), "Could not connect WMI server. Error code = 0x%X", hres); + return FALSE; + } + + // Set security levels on the proxy ------------------------- + hres = CoSetProxyBlanket( + pSvc, // Indicates the proxy to set + RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx + RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx + nullptr, // Server principal name + RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx + RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx + nullptr, // client identity + EOAC_NONE // proxy capabilities + ); + + if (FAILED(hres)) + { + pSvc->Release(); + CoUninitialize(); + snprintf(error, sizeof(error), "Could not set proxy blanket. Error code = 0x%X", hres); + return FALSE; + } + + *((IWbemServices**)lpContext) = pSvc; + atexit(CoUninitializeWrap); + return TRUE; +} + + +IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) +{ + static INIT_ONCE s_InitOnce = INIT_ONCE_STATIC_INIT; + const char* context; + if (InitOnceExecuteOnce(&s_InitOnce, &InitHandleFunction, nullptr, (void**)&context) == FALSE) + { + if(error) + ffStrbufInitS(error, context); + return nullptr; + } + + // Use the IWbemServices pointer to make requests of WMI + IEnumWbemClassObject* pEnumerator = nullptr; + HRESULT hres; + + hres = ((IWbemServices*)context)->ExecQuery( + bstr_t(L"WQL"), + bstr_t(queryStr), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + nullptr, + &pEnumerator); + + if (FAILED(hres)) + { + if(error) + ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%X", queryStr, hres); + return nullptr; + } + + return pEnumerator; +} + +void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { + int len = (int)SysStringLen(bstr); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, bstr, len, nullptr, 0, nullptr, nullptr); + ffStrbufEnsureFree(strbuf, (uint32_t)size_needed); + WideCharToMultiByte(CP_UTF8, 0, bstr, len, strbuf->chars, size_needed, nullptr, nullptr); + strbuf->length = (uint32_t)size_needed; +} + +bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) +{ + bool result = true; + + VARIANT vtProp; + VariantInit(&vtProp); + + CIMTYPE type; + if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt == VT_EMPTY || vtProp.vt == VT_NULL) + { + result = false; + } + else + { + switch(type) + { + case CIM_ILLEGAL: + case CIM_EMPTY: result = false; break; + case CIM_SINT8: ffStrbufAppendF(strbuf, "%d", (int)vtProp.cVal); break; + case CIM_SINT16: ffStrbufAppendF(strbuf, "%d", (int)vtProp.iVal); break; + case CIM_SINT32: ffStrbufAppendF(strbuf, "%d", (int)vtProp.intVal); break; + case CIM_SINT64: ffStrbufAppendF(strbuf, "%lld", vtProp.llVal); break; + case CIM_UINT8: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.bVal); break; + case CIM_UINT16: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uiVal); break; + case CIM_UINT32: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uintVal); break; + case CIM_UINT64: ffStrbufAppendF(strbuf, "%llu", vtProp.ullVal); break; + case CIM_REAL32: ffStrbufAppendF(strbuf, "%f", vtProp.fltVal); break; + case CIM_REAL64: ffStrbufAppendF(strbuf, "%f", vtProp.dblVal); break; + case CIM_BOOLEAN: ffStrbufAppendF(strbuf, "%s", vtProp.boolVal ? "True" : "False"); break; + case CIM_STRING: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break; + case CIM_DATETIME: { + ISWbemDateTime *pDateTime; + BSTR dateStr; + if(FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime)))) + result = false; + else if(FAILED(pDateTime->put_Value(vtProp.bstrVal))) + result = false; + else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr))) + result = false; + else + ffBstrToStrbuf(dateStr, strbuf); + break; + }; + + default: result = false; break; + } + } + VariantClear(&vtProp); + return result; +} diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp new file mode 100644 index 000000000..86d04099b --- /dev/null +++ b/src/util/windows/wmi.hpp @@ -0,0 +1,43 @@ +#pragma once + +#ifndef FF_INCLUDED_util_windows_wmi +#define FF_INCLUDED_util_windows_wmi + +#ifdef __cplusplus + +extern "C" { + #include "util/FFstrbuf.h" +} + +#include + +// is not usable in MSYS, so provide our simple bstr_t implementation +struct bstr_t +{ + explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {} + + ~bstr_t() noexcept { SysFreeString(_bstr); } + + explicit operator const wchar_t*() const noexcept { + return _bstr; + } + + operator BSTR() const noexcept { + return _bstr; + } + +private: + BSTR _bstr; +}; + +void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf); + +IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error); +bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf); + +#else + // Win32 COM headers requires C++ compiler + #error Must be included in C++ source file +#endif //__cplusplus + +#endif //FF_INCLUDED_util_windows_wmi From 230d2ac39d490ce9cd44dfa3c940a419f83ddda4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Oct 2022 17:03:30 +0800 Subject: [PATCH 004/311] Board: split out from host; add support for Windows --- CMakeLists.txt | 5 +++ src/common/init.c | 1 + src/detection/board/board.h | 18 +++++++++ src/detection/board/board_android.c | 10 +++++ src/detection/board/board_apple.c | 10 +++++ src/detection/board/board_linux.c | 55 +++++++++++++++++++++++++++ src/detection/board/board_windows.cpp | 36 ++++++++++++++++++ src/detection/host/host.h | 3 -- src/detection/host/host_android.c | 3 -- src/detection/host/host_apple.c | 3 -- src/detection/host/host_linux.c | 9 ----- src/detection/host/host_windows.cpp | 3 -- src/fastfetch.c | 15 ++++++-- src/fastfetch.h | 2 + src/flashfetch.c | 1 + src/modules/board.c | 40 +++++++++++++++++++ src/modules/host.c | 5 +-- 17 files changed, 190 insertions(+), 29 deletions(-) create mode 100644 src/detection/board/board.h create mode 100644 src/detection/board/board_android.c create mode 100644 src/detection/board/board_apple.c create mode 100644 src/detection/board/board_linux.c create mode 100644 src/detection/board/board_windows.cpp create mode 100644 src/modules/board.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dc7ee21c..a57e34519 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,6 +224,7 @@ set(LIBFASTFETCH_SRC src/modules/os.c src/modules/host.c src/modules/bios.c + src/modules/board.c src/modules/kernel.c src/modules/uptime.c src/modules/processes.c @@ -288,6 +289,7 @@ if(LINUX OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/host/host_linux.c src/detection/bios/bios_linux.c + src/detection/board/board_linux.c src/detection/os/os_linux.c src/detection/gpu/gpu_linux.c src/detection/battery/battery_linux.c @@ -307,6 +309,7 @@ if(WIN_MSYS) list(APPEND LIBFASTFETCH_SRC src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp + src/detection/board/board_windows.cpp src/detection/os/os_linux.c src/detection/gpu/gpu_linux.c src/detection/battery/battery_linux.c @@ -326,6 +329,7 @@ if(APPLE) src/util/apple/osascript.m src/detection/host/host_apple.c src/detection/bios/bios_apple.c + src/detection/board/board_apple.c src/detection/os/os_apple.m src/detection/cpu/cpu_apple.c src/detection/gpu/gpu_apple.c @@ -353,6 +357,7 @@ if(ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/host/host_android.c src/detection/bios/bios_android.c + src/detection/board/board_android.c src/detection/os/os_android.c src/detection/gpu/gpu_android.c src/detection/battery/battery_android.c diff --git a/src/common/init.c b/src/common/init.c index a1498c50f..8eb87dc58 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -163,6 +163,7 @@ static void defaultConfig(FFinstance* instance) initModuleArg(&instance->config.os); initModuleArg(&instance->config.host); initModuleArg(&instance->config.bios); + initModuleArg(&instance->config.board); initModuleArg(&instance->config.kernel); initModuleArg(&instance->config.uptime); initModuleArg(&instance->config.processes); diff --git a/src/detection/board/board.h b/src/detection/board/board.h new file mode 100644 index 000000000..15044469e --- /dev/null +++ b/src/detection/board/board.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_board_board +#define FF_INCLUDED_detection_board_board + +#include "fastfetch.h" + +typedef struct FFBoardResult +{ + FFstrbuf boardName; + FFstrbuf boardVendor; + FFstrbuf boardVersion; + FFstrbuf error; +} FFBoardResult; + +void ffDetectBoard(FFBoardResult* result); + +#endif diff --git a/src/detection/board/board_android.c b/src/detection/board/board_android.c new file mode 100644 index 000000000..d55dfe453 --- /dev/null +++ b/src/detection/board/board_android.c @@ -0,0 +1,10 @@ +#include "board.h" + +void ffDetectBoard(FFBoardResult* board) +{ + ffStrbufInitS(&board->error, "Not supported on Android"); + + ffStrbufInit(&board->boardName); + ffStrbufInit(&board->boardVendor); + ffStrbufInit(&board->boardVersion); +} diff --git a/src/detection/board/board_apple.c b/src/detection/board/board_apple.c new file mode 100644 index 000000000..76704dbd7 --- /dev/null +++ b/src/detection/board/board_apple.c @@ -0,0 +1,10 @@ +#include "board.h" + +void ffDetectBoard(FFBoardResult* board) +{ + ffStrbufInitS(&board->error, "Not supported on macOS"); + + ffStrbufInit(&board->boardName); + ffStrbufInit(&board->boardVendor); + ffStrbufInit(&board->boardVersion); +} diff --git a/src/detection/board/board_linux.c b/src/detection/board/board_linux.c new file mode 100644 index 000000000..8e92eec4e --- /dev/null +++ b/src/detection/board/board_linux.c @@ -0,0 +1,55 @@ +#include "board.h" +#include "common/io.h" + +#include + +static bool hostValueSet(FFstrbuf* value) +{ + return + value->length > 0 && + ffStrbufStartsWithIgnCaseS(value, "To be filled") != true && + ffStrbufStartsWithIgnCaseS(value, "To be set") != true && + ffStrbufStartsWithIgnCaseS(value, "OEM") != true && + ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true && + ffStrbufIgnCaseCompS(value, "None") != 0 && + ffStrbufIgnCaseCompS(value, "System Product") != 0 && + ffStrbufIgnCaseCompS(value, "System Product Name") != 0 && + ffStrbufIgnCaseCompS(value, "System Product Version") != 0 && + ffStrbufIgnCaseCompS(value, "System Name") != 0 && + ffStrbufIgnCaseCompS(value, "System Version") != 0 && + ffStrbufIgnCaseCompS(value, "Default string") != 0 && + ffStrbufIgnCaseCompS(value, "Undefined") != 0 && + ffStrbufIgnCaseCompS(value, "Not Specified") != 0 && + ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 && + ffStrbufIgnCaseCompS(value, "INVALID") != 0 && + ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 && + ffStrbufIgnCaseCompS(value, "All Series") != 0 + ; +} + +static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) +{ + ffReadFileBuffer(devicesPath, buffer); + if(hostValueSet(buffer)) + return; + + ffReadFileBuffer(classPath, buffer); + if(hostValueSet(buffer)) + return; + + ffStrbufClear(buffer); +} + +void ffDetectBoard(FFBoardResult* board) +{ + ffStrbufInit(&board->error); + + ffStrbufInit(&board->boardName); + getHostValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->boardName); + + ffStrbufInit(&board->boardVendor); + getHostValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &board->boardVendor); + + ffStrbufInit(&board->boardVersion); + getHostValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &board->boardVersion); +} diff --git a/src/detection/board/board_windows.cpp b/src/detection/board/board_windows.cpp new file mode 100644 index 000000000..5709a4eb1 --- /dev/null +++ b/src/detection/board/board_windows.cpp @@ -0,0 +1,36 @@ +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); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + + if(uReturn == 0) + { + ffStrbufInitS(&board->error, "No Wmi result returned"); + pEnumerator->Release(); + return; + } + + ffGetWmiObjValue(pclsObj, L"Product", &board->boardName); + ffGetWmiObjValue(pclsObj, L"Manufacturer", &board->boardVendor); + ffGetWmiObjValue(pclsObj, L"Version", &board->boardVersion); + + pclsObj->Release(); + pEnumerator->Release(); +} diff --git a/src/detection/host/host.h b/src/detection/host/host.h index 73e192d70..e66af41fb 100644 --- a/src/detection/host/host.h +++ b/src/detection/host/host.h @@ -14,9 +14,6 @@ typedef struct FFHostResult FFstrbuf productName; FFstrbuf productVersion; FFstrbuf productSku; - FFstrbuf boardName; - FFstrbuf boardVendor; - FFstrbuf boardVersion; FFstrbuf chassisType; FFstrbuf chassisVendor; FFstrbuf chassisVersion; diff --git a/src/detection/host/host_android.c b/src/detection/host/host_android.c index edf807e73..b45283eb3 100644 --- a/src/detection/host/host_android.c +++ b/src/detection/host/host_android.c @@ -34,9 +34,6 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInitA(&host->productVersion, 0); ffStrbufInitA(&host->productSku, 0); - ffStrbufInitA(&host->boardName, 0); - ffStrbufInitA(&host->boardVendor, 0); - ffStrbufInitA(&host->boardVersion, 0); ffStrbufInitA(&host->chassisType, 0); ffStrbufInitA(&host->chassisVendor, 0); ffStrbufInitA(&host->chassisVersion, 0); diff --git a/src/detection/host/host_apple.c b/src/detection/host/host_apple.c index d552bd232..f00946ad6 100644 --- a/src/detection/host/host_apple.c +++ b/src/detection/host/host_apple.c @@ -120,9 +120,6 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productSku); ffStrbufInitA(&host->sysVendor, 0); - ffStrbufInitA(&host->boardName, 0); - ffStrbufInitA(&host->boardVendor, 0); - ffStrbufInitA(&host->boardVersion, 0); ffStrbufInitA(&host->chassisType, 0); ffStrbufInitA(&host->chassisVendor, 0); ffStrbufInitA(&host->chassisVersion, 0); diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c index 0bf9d7978..c518da1ec 100644 --- a/src/detection/host/host_linux.c +++ b/src/detection/host/host_linux.c @@ -74,15 +74,6 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productSku); getHostValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku); - ffStrbufInit(&host->boardName); - getHostValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &host->boardName); - - ffStrbufInit(&host->boardVendor); - getHostValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &host->boardVendor); - - ffStrbufInit(&host->boardVersion); - getHostValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &host->boardVersion); - ffStrbufInit(&host->chassisType); getHostValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &host->chassisType); diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp index 4a106cbd7..3af7dadf1 100644 --- a/src/detection/host/host_windows.cpp +++ b/src/detection/host/host_windows.cpp @@ -12,9 +12,6 @@ extern "C" void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productVersion); ffStrbufInit(&host->productSku); ffStrbufInit(&host->sysVendor); - ffStrbufInit(&host->boardName); - ffStrbufInit(&host->boardVendor); - ffStrbufInit(&host->boardVersion); ffStrbufInit(&host->chassisType); ffStrbufInit(&host->chassisVendor); ffStrbufInit(&host->chassisVersion); diff --git a/src/fastfetch.c b/src/fastfetch.c index 40d0eb0e6..35ce52507 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -71,14 +71,11 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "host-format") == 0) { - constructAndPrintCommandHelpFormat("host", "{2} {3}", 11, + constructAndPrintCommandHelpFormat("host", "{2} {3}", 8, "product family", "product name", "product version", "product sku", - "board name", - "board vendor", - "board version", "chassis type", "chassis vendor", "chassis version", @@ -94,6 +91,14 @@ static inline void printCommandHelp(const char* command) "bios version" ); } + else if(strcasecmp(command, "board-format") == 0) + { + constructAndPrintCommandHelpFormat("board", "{2} {3}", 3, + "board name", + "board vendor", + "board version" + ); + } else if(strcasecmp(command, "kernel-format") == 0) { constructAndPrintCommandHelpFormat("kernel", "{2}", 3, @@ -1380,6 +1385,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char ffPrintHost(instance); else if(strcasecmp(line, "bios") == 0) ffPrintBios(instance); + else if(strcasecmp(line, "board") == 0) + ffPrintBoard(instance); else if(strcasecmp(line, "kernel") == 0) ffPrintKernel(instance); else if(strcasecmp(line, "uptime") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index e40ca95a9..372fb221b 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -95,6 +95,7 @@ typedef struct FFconfig FFModuleArgs os; FFModuleArgs host; FFModuleArgs bios; + FFModuleArgs board; FFModuleArgs kernel; FFModuleArgs uptime; FFModuleArgs processes; @@ -251,6 +252,7 @@ void ffPrintSeparator(FFinstance* instance); void ffPrintOS(FFinstance* instance); void ffPrintHost(FFinstance* instance); void ffPrintBios(FFinstance* instance); +void ffPrintBoard(FFinstance* instance); void ffPrintKernel(FFinstance* instance); void ffPrintUptime(FFinstance* instance); void ffPrintProcesses(FFinstance* instance); diff --git a/src/flashfetch.c b/src/flashfetch.c index 778fcca23..dea96af08 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -23,6 +23,7 @@ int main(int argc, char** argv) ffPrintOS(&instance); ffPrintHost(&instance); //ffPrintBios(&instance); + //ffPrintBoard(&instance); ffPrintKernel(&instance); ffPrintUptime(&instance); //ffPrintProcesses(&instance); diff --git a/src/modules/board.c b/src/modules/board.c new file mode 100644 index 000000000..8fe85735d --- /dev/null +++ b/src/modules/board.c @@ -0,0 +1,40 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/caching.h" +#include "detection/board/board.h" + +#define FF_BOARD_MODULE_NAME "Board" +#define FF_BOARD_NUM_FORMAT_ARGS 3 + +void ffPrintBoard(FFinstance* instance) +{ + if(ffPrintFromCache(instance, FF_BOARD_MODULE_NAME, &instance->config.board, FF_BOARD_NUM_FORMAT_ARGS)) + return; + + FFBoardResult result; + ffDetectBoard(&result); + + if(result.error.length > 0) + { + ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, "%*s", result.error.length, result.error.chars); + goto exit; + } + + if(result.boardName.length == 0) + { + ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, "board_name is not set."); + goto exit; + } + + ffPrintAndWriteToCache(instance, FF_BOARD_MODULE_NAME, &instance->config.board, &result.boardName, FF_BOARD_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVersion}, + }); + +exit: + ffStrbufDestroy(&result.boardName); + ffStrbufDestroy(&result.boardVendor); + ffStrbufDestroy(&result.boardVersion); + ffStrbufDestroy(&result.error); +} diff --git a/src/modules/host.c b/src/modules/host.c index c7bdd969e..8c3ec65d7 100644 --- a/src/modules/host.c +++ b/src/modules/host.c @@ -4,7 +4,7 @@ #include "detection/host/host.h" #define FF_HOST_MODULE_NAME "Host" -#define FF_HOST_NUM_FORMAT_ARGS 11 +#define FF_HOST_NUM_FORMAT_ARGS 8 void ffPrintHost(FFinstance* instance) { @@ -44,9 +44,6 @@ void ffPrintHost(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->boardName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->boardVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->boardVersion}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisType}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVendor}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVersion}, From 0d3d881c24f075fc9f5525210300b1b4ccf769fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Oct 2022 17:53:18 +0800 Subject: [PATCH 005/311] GPU: add support for Windows --- src/detection/gpu/gpu_windows.cpp | 44 +++++++++++++++++++++++++++++++ src/modules/gpu.c | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/detection/gpu/gpu_windows.cpp diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp new file mode 100644 index 000000000..90a6fd264 --- /dev/null +++ b/src/detection/gpu/gpu_windows.cpp @@ -0,0 +1,44 @@ +extern "C" { +#include "gpu.h" +} +#include "util/windows/wmi.hpp" + +extern "C" +const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +{ + FF_UNUSED(instance); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr); + + if(!pEnumerator) + return "Query WMI service failed"; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + { + FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); + + ffStrbufInit(&gpu->vendor); + ffGetWmiObjValue(pclsObj, L"AdapterCompatibility", &gpu->vendor); + if(ffStrbufStartsWithS(&gpu->vendor, "Intel ")) + { + //Intel returns "Intel Corporation", not sure about AMD + ffStrbufSetS(&gpu->vendor, "Intel"); + } + + ffStrbufInit(&gpu->name); + ffGetWmiObjValue(pclsObj, L"Name", &gpu->name); + + ffStrbufInit(&gpu->driver); + ffGetWmiObjValue(pclsObj, L"DriverVersion", &gpu->driver); + + gpu->temperature = FF_GPU_TEMP_UNSET; + gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; + } + + pclsObj->Release(); + pEnumerator->Release(); + return nullptr; +} diff --git a/src/modules/gpu.c b/src/modules/gpu.c index c98ca3af8..11507191a 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -14,7 +14,7 @@ static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, FFstrbuf output; ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length); - if(gpu->vendor.length > 0) + if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor)) { ffStrbufAppend(&output, &gpu->vendor); ffStrbufAppendC(&output, ' '); From e59f4e7e45ea0f820b6bc42b6030a6fa639bad4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Oct 2022 19:52:16 +0800 Subject: [PATCH 006/311] Resolution: add support for Windows --- CMakeLists.txt | 3 +- .../displayserver/displayserver_windows.c | 38 +++++++++++++++---- src/detection/wmtheme/wmtheme_linux.c | 2 +- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a57e34519..495d2794c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,7 +311,7 @@ if(WIN_MSYS) src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp src/detection/os/os_linux.c - src/detection/gpu/gpu_linux.c + src/detection/gpu/gpu_windows.cpp src/detection/battery/battery_linux.c src/detection/displayserver/displayserver_windows.c src/detection/terminalfont/terminalfont_linux.c @@ -448,6 +448,7 @@ elseif(WIN_MSYS) PRIVATE "-lwbemuuid" PRIVATE "-lole32" PRIVATE "-loleaut32" + PRIVATE "-ldwmapi" ) endif() diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index 8427c7cb2..a990e2e82 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -1,14 +1,38 @@ #include "displayserver.h" +#include +#include + void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) { FF_UNUSED(instance); - ffStrbufInitA(&ds->wmProcessName, 0); - ffStrbufInitA(&ds->wmPrettyName, 0); - ffStrbufInitA(&ds->wmProtocolName, 0); - ffStrbufInitA(&ds->deProcessName, 0); - ffStrbufInitA(&ds->dePrettyName, 0); - ffStrbufInitA(&ds->deVersion, 0); - ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 0); + BOOL enabled; + if(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled == TRUE) + { + ffStrbufInitS(&ds->wmProcessName, "dwm.exe"); + ffStrbufInitS(&ds->wmPrettyName, "Desktop Window Manager"); + } + else + { + ffStrbufInitS(&ds->wmProcessName, "internal"); + ffStrbufInitS(&ds->wmPrettyName, "internal"); + } + ffStrbufInit(&ds->wmProtocolName); + ffStrbufInit(&ds->deProcessName); + ffStrbufInit(&ds->dePrettyName); + ffStrbufInit(&ds->deVersion); + ffListInit(&ds->resolutions, sizeof(FFResolutionResult)); + + DISPLAY_DEVICEW displayDevice = { .cb = sizeof(DISPLAY_DEVICEW) }; + for(DWORD devNum = 0; EnumDisplayDevicesW(NULL, devNum, &displayDevice, 0) != 0; ++devNum) + { + if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE)) + continue; + DEVMODEW devMode = { .dmSize = sizeof(DEVMODEW) }; + if(EnumDisplaySettingsW(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode) == 0) + continue; + + ffdsAppendResolution(ds, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmDisplayFrequency); + } } diff --git a/src/detection/wmtheme/wmtheme_linux.c b/src/detection/wmtheme/wmtheme_linux.c index 0650d2f4a..19765c79a 100644 --- a/src/detection/wmtheme/wmtheme_linux.c +++ b/src/detection/wmtheme/wmtheme_linux.c @@ -224,6 +224,6 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) return detectOpenbox(instance, &wm->dePrettyName, themeOrError); ffStrbufAppendS(themeOrError, "Unknown WM: "); - ffStrbufAppend(themeOrError, &wm->dePrettyName); + ffStrbufAppend(themeOrError, &wm->wmPrettyName); return false; } From 8ea2014baf32480ce2073e90725021dd8c5c0795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Oct 2022 23:51:59 +0800 Subject: [PATCH 007/311] OpenGL: add support for Windows --- CMakeLists.txt | 6 + src/detection/opengl/opengl.h | 18 + src/detection/opengl/opengl_apple.c | 56 ++++ src/detection/opengl/opengl_linux.c | 369 +++++++++++++++++++++ src/detection/opengl/opengl_windows.c | 108 ++++++ src/modules/opengl.c | 459 ++------------------------ 6 files changed, 579 insertions(+), 437 deletions(-) create mode 100644 src/detection/opengl/opengl.h create mode 100644 src/detection/opengl/opengl_apple.c create mode 100644 src/detection/opengl/opengl_linux.c create mode 100644 src/detection/opengl/opengl_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 495d2794c..6a5122e76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,6 +302,7 @@ if(LINUX OR BSD) src/detection/media/media_linux.c src/detection/wmtheme/wmtheme_linux.c src/detection/font/font_linux.c + src/detection/opengl/opengl_linux.c ) endif() @@ -318,6 +319,7 @@ if(WIN_MSYS) src/detection/media/media_linux.c src/detection/wmtheme/wmtheme_linux.c src/detection/font/font_linux.c + src/detection/opengl/opengl_windows.c src/util/windows/wmi.cpp ) endif() @@ -343,6 +345,7 @@ if(APPLE) src/detection/wmtheme/wmtheme_apple.m src/detection/temps/temps_apple.c src/detection/font/font_apple.m + src/detection/opengl/opengl_apple.c ) endif() @@ -366,6 +369,7 @@ if(ANDROID) src/detection/media/media_android.c src/detection/wmtheme/wmtheme_android.c src/detection/font/font_android.c + src/detection/opengl/opengl_linux.c ) endif() @@ -449,6 +453,8 @@ elseif(WIN_MSYS) PRIVATE "-lole32" PRIVATE "-loleaut32" PRIVATE "-ldwmapi" + PRIVATE "-lopengl32" + PRIVATE "-lgdi32" ) endif() diff --git a/src/detection/opengl/opengl.h b/src/detection/opengl/opengl.h new file mode 100644 index 000000000..206347184 --- /dev/null +++ b/src/detection/opengl/opengl.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_opengl_opengl +#define FF_INCLUDED_detection_opengl_opengl + +#include "fastfetch.h" + +typedef struct FFOpenGLResult +{ + FFstrbuf version; + FFstrbuf renderer; + FFstrbuf vendor; + FFstrbuf slv; +} FFOpenGLResult; + +const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result); + +#endif diff --git a/src/detection/opengl/opengl_apple.c b/src/detection/opengl/opengl_apple.c new file mode 100644 index 000000000..4ccbb5fe6 --- /dev/null +++ b/src/detection/opengl/opengl_apple.c @@ -0,0 +1,56 @@ + +#include "fastfetch.h" +#include "opengl.h" + +#define GL_SILENCE_DEPRECATION +#include +#include // This brings in CGL, not GL + +static const char* glHandleResult(FFOpenGLResult* result) +{ + ffStrbufAppendS(&result->version, (const char*) glGetString(GL_VERSION)); + ffStrbufAppendS(&result->renderer, (const char*) glGetString(GL_RENDERER)); + ffStrbufAppendS(&result->vendor, (const char*) glGetString(GL_VENDOR)); + ffStrbufAppendS(&result->slv, (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); + return NULL; +} + +static const char* cglHandleContext(FFOpenGLResult* result, CGLContextObj context) +{ + if(CGLSetCurrentContext(context) != kCGLNoError) + return "CGLSetCurrentContext() failed"; + + return glHandleResult(result); +} + +static const char* cglHandlePixelFormat(FFOpenGLResult* result, CGLPixelFormatObj pixelFormat) +{ + CGLContextObj context; + + if(CGLCreateContext(pixelFormat, NULL, &context) != kCGLNoError) + return "CGLCreateContext() failed"; + + const char* error = cglHandleContext(result, context); + CGLDestroyContext(context); + return error; +} + +const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) +{ + FF_UNUSED(instance); + + CGLPixelFormatObj pixelFormat; + CGLPixelFormatAttribute attrs[] = { + kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core, + kCGLPFAAccelerated, + 0 + }; + + GLint num; + if (CGLChoosePixelFormat(attrs, &pixelFormat, &num) != kCGLNoError) + return "CGLChoosePixelFormat() failed"; + + const char* error = cglHandlePixelFormat(result, pixelFormat); + CGLDestroyPixelFormat(pixelFormat); + return error; +} diff --git a/src/detection/opengl/opengl_linux.c b/src/detection/opengl/opengl_linux.c new file mode 100644 index 000000000..6e5b8d503 --- /dev/null +++ b/src/detection/opengl/opengl_linux.c @@ -0,0 +1,369 @@ +#include "fastfetch.h" +#include "opengl.h" + +#include + +#if defined(FF_HAVE_EGL) || defined(FF_HAVE_GLX) || defined(FF_HAVE_OSMESA) +#define FF_HAVE_GL 1 + +#include "common/library.h" + +#include + +#define FF_OPENGL_BUFFER_WIDTH 1 +#define FF_OPENGL_BUFFER_HEIGHT 1 + +typedef struct GLData +{ + FF_LIBRARY_SYMBOL(glGetString) +} GLData; + +static const char* glHandleResult(FFOpenGLResult* result, const GLData* data) +{ + ffStrbufAppendS(&result->version, (const char*) data->ffglGetString(GL_VERSION)); + ffStrbufAppendS(&result->renderer, (const char*) data->ffglGetString(GL_RENDERER)); + ffStrbufAppendS(&result->vendor, (const char*) data->ffglGetString(GL_VENDOR)); + ffStrbufAppendS(&result->slv, (const char*) data->ffglGetString(GL_SHADING_LANGUAGE_VERSION)); + return NULL; +} + +#endif // FF_HAVE_GL + +#ifdef FF_HAVE_EGL +#include + +typedef struct EGLData +{ + GLData glData; + + FF_LIBRARY_SYMBOL(eglGetProcAddress) + FF_LIBRARY_SYMBOL(eglGetDisplay) + FF_LIBRARY_SYMBOL(eglInitialize) + FF_LIBRARY_SYMBOL(eglBindAPI) + FF_LIBRARY_SYMBOL(eglGetConfigs) + FF_LIBRARY_SYMBOL(eglCreatePbufferSurface) + FF_LIBRARY_SYMBOL(eglCreateContext) + FF_LIBRARY_SYMBOL(eglMakeCurrent) + FF_LIBRARY_SYMBOL(eglDestroyContext) + FF_LIBRARY_SYMBOL(eglDestroySurface) + FF_LIBRARY_SYMBOL(eglTerminate) + + EGLDisplay display; + EGLConfig config; + EGLSurface surface; + EGLContext context; +} EGLData; + +static const char* eglHandleContext(FFOpenGLResult* result, EGLData* data) +{ + if(data->ffeglMakeCurrent(data->display, data->surface, data->surface, data->context) != EGL_TRUE) + return "eglMakeCurrent returned EGL_FALSE"; + + return glHandleResult(result, &data->glData); +} + +static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data) +{ + data->context = data->ffeglCreateContext(data->display, data->config, EGL_NO_CONTEXT, (EGLint[]){EGL_NONE}); + if(data->context == EGL_NO_CONTEXT) + return "eglCreateContext returned EGL_NO_CONTEXT"; + + const char* error = eglHandleContext(result, data); + data->ffeglDestroyContext(data->display, data->context); + return error; +} + +static const char* eglHandleDisplay(FFOpenGLResult* result, EGLData* data) +{ + if(data->ffeglBindAPI(EGL_OPENGL_API) != EGL_TRUE) + return "eglBindAPI returned EGL_FALSE"; + + EGLint eglConfigCount; + data->ffeglGetConfigs(data->display, &data->config, 1, &eglConfigCount); + if(eglConfigCount == 0) + return "eglGetConfigs returned 0 configs"; + + data->surface = data->ffeglCreatePbufferSurface(data->display, data->config, (EGLint[]){ + EGL_WIDTH, FF_OPENGL_BUFFER_WIDTH, + EGL_HEIGHT, FF_OPENGL_BUFFER_HEIGHT, + EGL_NONE + }); + + if(data->surface == EGL_NO_SURFACE) + return "eglCreatePbufferSurface returned EGL_NO_SURFACE"; + + const char* error = eglHandleSurface(result, data); + data->ffeglDestroySurface(data->display, data->surface); + return error; +} + +static const char* eglHandleData(FFOpenGLResult* result, EGLData* data) +{ + data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) data->ffeglGetProcAddress("glGetString"); + if(!data->glData.ffglGetString) + return "eglGetProcAddress(glGetString) returned NULL"; + + data->display = data->ffeglGetDisplay(EGL_DEFAULT_DISPLAY); + if(data->display == EGL_NO_DISPLAY) + return "eglGetDisplay returned EGL_NO_DISPLAY"; + + EGLint major, minor; + if(data->ffeglInitialize(data->display, &major, &minor) == EGL_FALSE) + return "eglInitialize returned EGL_FALSE"; + + const char* error = eglHandleDisplay(result, data); + data->ffeglTerminate(data->display); + return error; +} + +static const char* eglPrint(FFinstance* instance, FFOpenGLResult* result) +{ + EGLData eglData; + + FF_LIBRARY_LOAD(egl, &instance->config.libEGL, "dlopen egl failed", "libEGL.so", 1); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglBindAPI); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetConfigs); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreatePbufferSurface); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreateContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglMakeCurrent); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroyContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroySurface); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglTerminate); + + const char* error = eglHandleData(result, &eglData); + dlclose(egl); + return error; +} + +#endif //FF_HAVE_EGL + +#ifdef FF_HAVE_GLX +#include + +typedef struct GLXData +{ + GLData glData; + + FF_LIBRARY_SYMBOL(glXGetProcAddress) + FF_LIBRARY_SYMBOL(XOpenDisplay) + FF_LIBRARY_SYMBOL(glXChooseVisual) + FF_LIBRARY_SYMBOL(XCreatePixmap); + FF_LIBRARY_SYMBOL(glXCreateGLXPixmap) + FF_LIBRARY_SYMBOL(glXCreateContext) + FF_LIBRARY_SYMBOL(glXMakeCurrent) + FF_LIBRARY_SYMBOL(glXDestroyContext) + FF_LIBRARY_SYMBOL(glXDestroyGLXPixmap) + FF_LIBRARY_SYMBOL(XFreePixmap) + FF_LIBRARY_SYMBOL(XCloseDisplay) + + Display* display; + XVisualInfo* visualInfo; + Pixmap pixmap; + GLXPixmap glxPixmap; + GLXContext context; +} GLXData; + +static const char* glxHandleContext(FFOpenGLResult* result, GLXData* data) +{ + if(data->ffglXMakeCurrent(data->display, data->glxPixmap, data->context) != True) + return "glXMakeCurrent returned False"; + + return glHandleResult(result, &data->glData); +} + +static const char* glxHandleGLXPixmap(FFOpenGLResult* result, GLXData* data) +{ + data->context = data->ffglXCreateContext(data->display, data->visualInfo, NULL, True); + if(data->context == NULL) + return "glXCreateContext returned NULL"; + + const char* error = glxHandleContext(result, data); + data->ffglXDestroyContext(data->display, data->context); + return error; +} + +static const char* glxHandlePixmap(FFOpenGLResult* result, GLXData* data) +{ + data->glxPixmap = data->ffglXCreateGLXPixmap(data->display, data->visualInfo, data->pixmap); + if(data->glxPixmap == None) + return "glXCreateGLXPixmap returned None"; + + const char* error = glxHandleGLXPixmap(result, data); + data->ffglXDestroyGLXPixmap(data->display, data->glxPixmap); + return error; +} + +static const char* glxHandleVisualInfo(FFOpenGLResult* result, GLXData* data) +{ + data->pixmap = data->ffXCreatePixmap(data->display, DefaultRootWindow(data->display), FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT, (unsigned int) data->visualInfo->depth); + if(data->pixmap == None) + return "XCreatePixmap returned None"; + + const char* error = glxHandlePixmap(result, data); + data->ffXFreePixmap(data->display, data->pixmap); + return error; +} + +static const char* glxHandleDisplay(FFOpenGLResult* result, GLXData* data) +{ + data->visualInfo = data->ffglXChooseVisual(data->display, DefaultScreen(data->display), (int[]){None}); + if(data->visualInfo == NULL) + return "glXChooseVisual returned NULL"; + + return glxHandleVisualInfo(result, data); +} + +static const char* glxHandleData(FFOpenGLResult* result, GLXData* data) +{ + data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) data->ffglXGetProcAddress((const GLubyte*) "glGetString"); + if(data->glData.ffglGetString == NULL) + return "glXGetProcAddress(glGetString) returned NULL"; + + data->display = data->ffXOpenDisplay(NULL); + if(data->display == NULL) + return "XOpenDisplay returned NULL"; + + const char* error = glxHandleDisplay(result, data); + data->ffXCloseDisplay(data->display); + return error; +} + +static const char* glxPrint(FFinstance* instance, FFOpenGLResult* result) +{ + GLXData data; + + FF_LIBRARY_LOAD(glx, &instance->config.libGLX, "dlopen glx failed", "libGLX.so", 1); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XCreatePixmap); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXCreateGLXPixmap); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXCreateContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXMakeCurrent); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXDestroyContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXDestroyGLXPixmap); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XFreePixmap); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XCloseDisplay); + + const char* error = glxHandleData(result, &data); + dlclose(glx); + return error; +} + +#endif //FF_HAVE_GLX + +#ifdef FF_HAVE_OSMESA +#include + +typedef struct OSMesaData +{ + GLData glData; + + FF_LIBRARY_SYMBOL(OSMesaGetProcAddress) + FF_LIBRARY_SYMBOL(OSMesaCreateContext) + FF_LIBRARY_SYMBOL(OSMesaMakeCurrent) + FF_LIBRARY_SYMBOL(OSMesaDestroyContext) + + OSMesaContext context; +} OSMesaData; + +static const char* osMesaHandleContext(FFOpenGLResult* result, OSMesaData* data) +{ + unsigned char buffer[FF_OPENGL_BUFFER_WIDTH * FF_OPENGL_BUFFER_HEIGHT * sizeof(uint32_t)]; // 4 bytes per pixel (RGBA) + + if(data->ffOSMesaMakeCurrent(data->context, buffer, GL_UNSIGNED_BYTE, FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT) != GL_TRUE) + return "OSMesaMakeCurrent returned GL_FALSE"; + + return glHandleResult(result, &data->glData); +} + +static const char* osMesaHandleData(FFOpenGLResult* result, OSMesaData* data) +{ + //The case to void* is required here, because OSMESAproc can't be cast to (__typeof__(data->glData.ffglGetString)) without a warning, even though it is the actual type. + data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) (void*) data->ffOSMesaGetProcAddress("glGetString"); + if(data->glData.ffglGetString == NULL) + return "OSMesaGetProcAddress(glGetString) returned NULL"; + + data->context = data->ffOSMesaCreateContext(OSMESA_RGBA, NULL); + if(data->context == NULL) + return "OSMesaCreateContext returned NULL"; + + const char* error = osMesaHandleContext(result, data); + data->ffOSMesaDestroyContext(data->context); + return error; +} + +static const char* osMesaPrint(FFinstance* instance, FFOpenGLResult* result) +{ + OSMesaData data; + + FF_LIBRARY_LOAD(osmesa, &instance->config.libOSMesa, "dlopen osmesa failed", "libOSMesa.so", 8); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaDestroyContext); + + const char* error = osMesaHandleData(result, &data); + dlclose(osmesa); + return error; +} + +#endif //FF_HAVE_OSMESA + +const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) +{ + #if FF_HAVE_GL + + if(instance->config.glType == FF_GL_TYPE_GLX) + { + #ifdef FF_HAVE_GLX + return glxPrint(instance, result); + #else + return "fastfetch was compiled without glx support"; + #endif + } + + if(instance->config.glType == FF_GL_TYPE_EGL) + { + #ifdef FF_HAVE_EGL + return eglPrint(instance, result); + #else + return "fastfetch was compiled without egl support"; + #endif + } + + if(instance->config.glType == FF_GL_TYPE_OSMESA) + { + #ifdef FF_HAVE_OSMESA + return osMesaPrint(instance, result); + #else + return "fastfetch was compiled without osmesa support"; + #endif + } + + const char* error = ""; // not NULL dummy value + + #ifdef FF_HAVE_EGL + error = eglPrint(instance, result); + #endif + + #ifdef FF_HAVE_GLX + if(error != NULL) + error = glxPrint(instance, result); + #endif + + //We don't use osmesa in auto mode here, because it is a software implementation, + //that doesn't reflect the opengl supported by the hardware + + return error; + + #else + + FF_UNUSED(instance, result); + return "Fastfetch was built without gl support."; + + #endif //FF_HAVE_GL +} diff --git a/src/detection/opengl/opengl_windows.c b/src/detection/opengl/opengl_windows.c new file mode 100644 index 000000000..92e56b974 --- /dev/null +++ b/src/detection/opengl/opengl_windows.c @@ -0,0 +1,108 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "opengl.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include +#include +#ifndef GL_SHADING_LANGUAGE_VERSION // For WGL + #define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#endif + +static const char* glHandleResult(FFOpenGLResult* result) +{ + ffStrbufAppendS(&result->version, (const char*) glGetString(GL_VERSION)); + ffStrbufAppendS(&result->renderer, (const char*) glGetString(GL_RENDERER)); + ffStrbufAppendS(&result->vendor, (const char*) glGetString(GL_VENDOR)); + ffStrbufAppendS(&result->slv, (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); + return NULL; +} + +const char* wglHandleContext(FFOpenGLResult* result, HDC hdc, HGLRC context) +{ + if(wglMakeCurrent(hdc, context) == FALSE) + return "wglMakeCurrent() failed"; + return glHandleResult(result); +} + +const char* wglHandlePixelFormat(FFOpenGLResult* result, HWND hWnd) +{ + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags + PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. + 32, // Colordepth of the framebuffer. + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 24, // Number of bits for the depthbuffer + 8, // Number of bits for the stencilbuffer + 0, // Number of Aux buffers in the framebuffer. + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + HDC hdc = GetDC(hWnd); + + if(SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd) == FALSE) + return "SetPixelFormat() failed"; + + HGLRC context = wglCreateContext(hdc); + if(context == NULL) + return "wglCreateContext() failed"; + + const char* error = wglHandleContext(result, hdc, context); + wglDeleteContext(context); + + return error; +} + +typedef struct WGLData +{ + FFOpenGLResult* result; + const char* error; +} WGLData; + +LRESULT CALLBACK wglHandleWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case WM_CREATE: { + WGLData* wglData = (WGLData*)((CREATESTRUCT*)lParam)->lpCreateParams; + wglData->error = wglHandlePixelFormat(wglData->result, hWnd); + PostQuitMessage(0); + return 0; + } + default: + return DefWindowProcW(hWnd, message, wParam, lParam); + } +} + +const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) +{ + FF_UNUSED(instance); + + MSG msg = {0}; + WNDCLASSW wc = { + .lpfnWndProc = wglHandleWndProc, + .hInstance = NULL, + .hbrBackground = (HBRUSH)COLOR_BACKGROUND, + .lpszClassName = L"ogl_version_check", + .style = CS_OWNDC, + }; + if(!RegisterClassW(&wc)) + return "RegisterClassW() failed"; + + WGLData data = { .result = result }; + HWND hWnd = CreateWindowW(wc.lpszClassName, L"ogl_version_check", 0, 0, 0, 1, 1, NULL, NULL, NULL, &data); + + while(GetMessageW(&msg, hWnd, 0, 0) > 0) + DispatchMessage(&msg); + + return data.error; +} diff --git a/src/modules/opengl.c b/src/modules/opengl.c index 78d0b4846..61e78451b 100644 --- a/src/modules/opengl.c +++ b/src/modules/opengl.c @@ -1,457 +1,42 @@ #include "fastfetch.h" #include "common/printing.h" -#include "common/parsing.h" - -#include +#include "detection/opengl/opengl.h" #define FF_OPENGL_MODULE_NAME "OpenGL" #define FF_OPENGL_NUM_FORMAT_ARGS 4 -#if defined(FF_HAVE_EGL) || defined(FF_HAVE_GLX) || defined(FF_HAVE_OSMESA) || defined(__APPLE__) -#define FF_HAVE_GL 1 - -#include "common/library.h" - -#ifdef __APPLE__ - #define GL_SILENCE_DEPRECATION - #include -#else - #include -#endif - -#define FF_OPENGL_BUFFER_WIDTH 1 -#define FF_OPENGL_BUFFER_HEIGHT 1 - -typedef struct GLData +void ffPrintOpenGL(FFinstance* instance) { - FF_LIBRARY_SYMBOL(glGetString) -} GLData; + FFOpenGLResult result; + ffStrbufInit(&result.version); + ffStrbufInit(&result.renderer); + ffStrbufInit(&result.vendor); + ffStrbufInit(&result.slv); -static const char* glHandlePrint(FFinstance* instance, const GLData* data) -{ - const char* version = (const char*) data->ffglGetString(GL_VERSION); - if(!ffStrSet(version)) - return "glGetString(GL_VERSION) returned NULL"; - - const char* renderer = (const char*) data->ffglGetString(GL_RENDERER); - const char* vendor = (const char*) data->ffglGetString(GL_VENDOR); - const char* slv = (const char*) data->ffglGetString(GL_SHADING_LANGUAGE_VERSION); + const char* error = ffDetectOpenGL(instance, &result); + if(error) + { + ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, "%s", error); + return; + } if(instance->config.openGL.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL.key); - puts(version); + puts(result.version.chars); } else { ffPrintFormat(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, FF_OPENGL_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRING, version}, - {FF_FORMAT_ARG_TYPE_STRING, renderer}, - {FF_FORMAT_ARG_TYPE_STRING, vendor}, - {FF_FORMAT_ARG_TYPE_STRING, slv} + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.renderer}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.slv} }); } - return NULL; -} - -#endif // FF_HAVE_GL - -#ifdef FF_HAVE_EGL -#include - -typedef struct EGLData -{ - GLData glData; - - FF_LIBRARY_SYMBOL(eglGetProcAddress) - FF_LIBRARY_SYMBOL(eglGetDisplay) - FF_LIBRARY_SYMBOL(eglInitialize) - FF_LIBRARY_SYMBOL(eglBindAPI) - FF_LIBRARY_SYMBOL(eglGetConfigs) - FF_LIBRARY_SYMBOL(eglCreatePbufferSurface) - FF_LIBRARY_SYMBOL(eglCreateContext) - FF_LIBRARY_SYMBOL(eglMakeCurrent) - FF_LIBRARY_SYMBOL(eglDestroyContext) - FF_LIBRARY_SYMBOL(eglDestroySurface) - FF_LIBRARY_SYMBOL(eglTerminate) - - EGLDisplay display; - EGLConfig config; - EGLSurface surface; - EGLContext context; -} EGLData; - -static const char* eglHandleContext(FFinstance* instance, EGLData* data) -{ - if(data->ffeglMakeCurrent(data->display, data->surface, data->surface, data->context) != EGL_TRUE) - return "eglMakeCurrent returned EGL_FALSE"; - - return glHandlePrint(instance, &data->glData); -} - -static const char* eglHandleSurface(FFinstance* instance, EGLData* data) -{ - data->context = data->ffeglCreateContext(data->display, data->config, EGL_NO_CONTEXT, (EGLint[]){EGL_NONE}); - if(data->context == EGL_NO_CONTEXT) - return "eglCreateContext returned EGL_NO_CONTEXT"; - - const char* error = eglHandleContext(instance, data); - data->ffeglDestroyContext(data->display, data->context); - return error; -} - -static const char* eglHandleDisplay(FFinstance* instance, EGLData* data) -{ - if(data->ffeglBindAPI(EGL_OPENGL_API) != EGL_TRUE) - return "eglBindAPI returned EGL_FALSE"; - - EGLint eglConfigCount; - data->ffeglGetConfigs(data->display, &data->config, 1, &eglConfigCount); - if(eglConfigCount == 0) - return "eglGetConfigs returned 0 configs"; - - data->surface = data->ffeglCreatePbufferSurface(data->display, data->config, (EGLint[]){ - EGL_WIDTH, FF_OPENGL_BUFFER_WIDTH, - EGL_HEIGHT, FF_OPENGL_BUFFER_HEIGHT, - EGL_NONE - }); - - if(data->surface == EGL_NO_SURFACE) - return "eglCreatePbufferSurface returned EGL_NO_SURFACE"; - - const char* error = eglHandleSurface(instance, data); - data->ffeglDestroySurface(data->display, data->surface); - return error; -} - -static const char* eglHandleData(FFinstance* instance, EGLData* data) -{ - data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) data->ffeglGetProcAddress("glGetString"); - if(!data->glData.ffglGetString) - return "eglGetProcAddress(glGetString) returned NULL"; - - data->display = data->ffeglGetDisplay(EGL_DEFAULT_DISPLAY); - if(data->display == EGL_NO_DISPLAY) - return "eglGetDisplay returned EGL_NO_DISPLAY"; - - EGLint major, minor; - if(data->ffeglInitialize(data->display, &major, &minor) == EGL_FALSE) - return "eglInitialize returned EGL_FALSE"; - - const char* error = eglHandleDisplay(instance, data); - data->ffeglTerminate(data->display); - return error; -} - -static const char* eglPrint(FFinstance* instance) -{ - EGLData eglData; - - FF_LIBRARY_LOAD(egl, &instance->config.libEGL, "dlopen egl failed", "libEGL.so", 1); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglBindAPI); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetConfigs); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreatePbufferSurface); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreateContext); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglMakeCurrent); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroyContext); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroySurface); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglTerminate); - - const char* error = eglHandleData(instance, &eglData); - dlclose(egl); - return error; -} - -#endif //FF_HAVE_EGL - -#ifdef FF_HAVE_GLX -#include - -typedef struct GLXData -{ - GLData glData; - - FF_LIBRARY_SYMBOL(glXGetProcAddress) - FF_LIBRARY_SYMBOL(XOpenDisplay) - FF_LIBRARY_SYMBOL(glXChooseVisual) - FF_LIBRARY_SYMBOL(XCreatePixmap); - FF_LIBRARY_SYMBOL(glXCreateGLXPixmap) - FF_LIBRARY_SYMBOL(glXCreateContext) - FF_LIBRARY_SYMBOL(glXMakeCurrent) - FF_LIBRARY_SYMBOL(glXDestroyContext) - FF_LIBRARY_SYMBOL(glXDestroyGLXPixmap) - FF_LIBRARY_SYMBOL(XFreePixmap) - FF_LIBRARY_SYMBOL(XCloseDisplay) - - Display* display; - XVisualInfo* visualInfo; - Pixmap pixmap; - GLXPixmap glxPixmap; - GLXContext context; -} GLXData; - -static const char* glxHandleContext(FFinstance* instance, GLXData* data) -{ - if(data->ffglXMakeCurrent(data->display, data->glxPixmap, data->context) != True) - return "glXMakeCurrent returned False"; - - return glHandlePrint(instance, &data->glData); -} - -static const char* glxHandleGLXPixmap(FFinstance* instance, GLXData* data) -{ - data->context = data->ffglXCreateContext(data->display, data->visualInfo, NULL, True); - if(data->context == NULL) - return "glXCreateContext returned NULL"; - - const char* error = glxHandleContext(instance, data); - data->ffglXDestroyContext(data->display, data->context); - return error; -} - -static const char* glxHandlePixmap(FFinstance* instance, GLXData* data) -{ - data->glxPixmap = data->ffglXCreateGLXPixmap(data->display, data->visualInfo, data->pixmap); - if(data->glxPixmap == None) - return "glXCreateGLXPixmap returned None"; - - const char* error = glxHandleGLXPixmap(instance, data); - data->ffglXDestroyGLXPixmap(data->display, data->glxPixmap); - return error; -} - -static const char* glxHandleVisualInfo(FFinstance* instance, GLXData* data) -{ - data->pixmap = data->ffXCreatePixmap(data->display, DefaultRootWindow(data->display), FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT, (unsigned int) data->visualInfo->depth); - if(data->pixmap == None) - return "XCreatePixmap returned None"; - - const char* error = glxHandlePixmap(instance, data); - data->ffXFreePixmap(data->display, data->pixmap); - return error; -} - -static const char* glxHandleDisplay(FFinstance* instance, GLXData* data) -{ - data->visualInfo = data->ffglXChooseVisual(data->display, DefaultScreen(data->display), (int[]){None}); - if(data->visualInfo == NULL) - return "glXChooseVisual returned NULL"; - - return glxHandleVisualInfo(instance, data); -} - -static const char* glxHandleData(FFinstance* instance, GLXData* data) -{ - data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) data->ffglXGetProcAddress((const GLubyte*) "glGetString"); - if(data->glData.ffglGetString == NULL) - return "glXGetProcAddress(glGetString) returned NULL"; - - data->display = data->ffXOpenDisplay(NULL); - if(data->display == NULL) - return "XOpenDisplay returned NULL"; - - const char* error = glxHandleDisplay(instance, data); - data->ffXCloseDisplay(data->display); - return error; -} - -static const char* glxPrint(FFinstance* instance) -{ - GLXData data; - - FF_LIBRARY_LOAD(glx, &instance->config.libGLX, "dlopen glx failed", "libGLX.so", 1); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XCreatePixmap); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXCreateGLXPixmap); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXCreateContext); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXMakeCurrent); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXDestroyContext); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXDestroyGLXPixmap); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XFreePixmap); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XCloseDisplay); - - const char* error = glxHandleData(instance, &data); - dlclose(glx); - return error; -} - -#endif //FF_HAVE_GLX - -#ifdef FF_HAVE_OSMESA -#include - -typedef struct OSMesaData -{ - GLData glData; - - FF_LIBRARY_SYMBOL(OSMesaGetProcAddress) - FF_LIBRARY_SYMBOL(OSMesaCreateContext) - FF_LIBRARY_SYMBOL(OSMesaMakeCurrent) - FF_LIBRARY_SYMBOL(OSMesaDestroyContext) - - OSMesaContext context; -} OSMesaData; - -static const char* osMesaHandleContext(FFinstance* instance, OSMesaData* data) -{ - unsigned char buffer[FF_OPENGL_BUFFER_WIDTH * FF_OPENGL_BUFFER_HEIGHT * sizeof(uint32_t)]; // 4 bytes per pixel (RGBA) - - if(data->ffOSMesaMakeCurrent(data->context, buffer, GL_UNSIGNED_BYTE, FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT) != GL_TRUE) - return "OSMesaMakeCurrent returned GL_FALSE"; - - return glHandlePrint(instance, &data->glData); -} - -static const char* osMesaHandleData(FFinstance* instance, OSMesaData* data) -{ - //The case to void* is required here, because OSMESAproc can't be cast to (__typeof__(data->glData.ffglGetString)) without a warning, even though it is the actual type. - data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) (void*) data->ffOSMesaGetProcAddress("glGetString"); - if(data->glData.ffglGetString == NULL) - return "OSMesaGetProcAddress(glGetString) returned NULL"; - - data->context = data->ffOSMesaCreateContext(OSMESA_RGBA, NULL); - if(data->context == NULL) - return "OSMesaCreateContext returned NULL"; - - const char* error = osMesaHandleContext(instance, data); - data->ffOSMesaDestroyContext(data->context); - return error; -} - -static const char* osMesaPrint(FFinstance* instance) -{ - OSMesaData data; - - FF_LIBRARY_LOAD(osmesa, &instance->config.libOSMesa, "dlopen osmesa failed", "libOSMesa.so", 8); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaDestroyContext); - - const char* error = osMesaHandleData(instance, &data); - dlclose(osmesa); - return error; -} - -#endif //FF_HAVE_OSMESA - -#ifdef __APPLE__ -#include // This brings in CGL, not GL - -typedef struct CGLData -{ - CGLPixelFormatObj pixelFormat; - CGLContextObj context; -} CGLData; - -static const char* cglHandleContext(FFinstance* instance, CGLData* data) -{ - if(CGLSetCurrentContext(data->context) != kCGLNoError) - return "CGLSetCurrentContext() failed"; - - GLData glData; - glData.ffglGetString = glGetString; - - return glHandlePrint(instance, &glData); -} - -static const char* cglHandlePixelFormat(FFinstance* instance, CGLData* data) -{ - if(CGLCreateContext(data->pixelFormat, NULL, &data->context) != kCGLNoError) - return "CGLCreateContext() failed"; - - const char* error = cglHandleContext(instance, data); - CGLDestroyContext(data->context); - return error; -} - -static const char* cglPrint(FFinstance* instance) -{ - CGLData data; - - CGLPixelFormatAttribute attrs[] = { - kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core, - kCGLPFAAccelerated, - 0 - }; - - GLint num; - if (CGLChoosePixelFormat(attrs, &data.pixelFormat, &num) != kCGLNoError) - return "CGLChoosePixelFormat() failed"; - - const char* error = cglHandlePixelFormat(instance, &data); - CGLDestroyPixelFormat(data.pixelFormat); - return error; -} - -#elif FF_HAVE_GL - -static const char* glPrint(FFinstance* instance) -{ - if(instance->config.glType == FF_GL_TYPE_GLX) - { - #ifdef FF_HAVE_GLX - return glxPrint(instance); - #else - return "fastfetch was compiled without glx support"; - #endif - } - - if(instance->config.glType == FF_GL_TYPE_EGL) - { - #ifdef FF_HAVE_EGL - return eglPrint(instance); - #else - return "fastfetch was compiled without egl support"; - #endif - } - - if(instance->config.glType == FF_GL_TYPE_OSMESA) - { - #ifdef FF_HAVE_OSMESA - return osMesaPrint(instance); - #else - return "fastfetch was compiled without osmesa support"; - #endif - } - - const char* error = ""; // not NULL dummy value - - #ifdef FF_HAVE_EGL - error = eglPrint(instance); - #endif - - #ifdef FF_HAVE_GLX - if(error != NULL) - error = glxPrint(instance); - #endif - - //We don't use osmesa in auto mode here, because it is a software implementation, - //that doesn't reflect the opengl supported by the hardware - - return error; -} - -#endif // !__APPLE__ && FF_HAVE_GL - -void ffPrintOpenGL(FFinstance* instance) -{ - const char* error; - - #ifndef FF_HAVE_GL - error = "Fastfetch was built without gl support."; - #elif __APPLE__ - error = cglPrint(instance); - #else - error = glPrint(instance); - #endif - - if(error != NULL) - ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, "%s", error); + ffStrbufDestroy(&result.version); + ffStrbufDestroy(&result.renderer); + ffStrbufDestroy(&result.vendor); + ffStrbufDestroy(&result.slv); } From bedd6a1d5d0776615ca75f9bebf6da100bd26ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 01:23:28 +0800 Subject: [PATCH 008/311] Battery: add support for Windows --- CMakeLists.txt | 2 +- src/detection/battery/battery_android.c | 6 +- src/detection/battery/battery_windows.cpp | 70 +++++++++++++++++++++++ src/util/windows/wmi.cpp | 31 ++++++++++ src/util/windows/wmi.hpp | 1 + 5 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 src/detection/battery/battery_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a5122e76..f646f91d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -313,7 +313,7 @@ if(WIN_MSYS) src/detection/board/board_windows.cpp src/detection/os/os_linux.c src/detection/gpu/gpu_windows.cpp - src/detection/battery/battery_linux.c + src/detection/battery/battery_windows.cpp src/detection/displayserver/displayserver_windows.c src/detection/terminalfont/terminalfont_linux.c src/detection/media/media_linux.c diff --git a/src/detection/battery/battery_android.c b/src/detection/battery/battery_android.c index 2fc2b1d85..6a59625d7 100644 --- a/src/detection/battery/battery_android.c +++ b/src/detection/battery/battery_android.c @@ -1,10 +1,8 @@ #include "fastfetch.h" -#include "common/io.h" #include "battery.h" -#include - -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { +const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) +{ FF_UNUSED(instance, results) return "Unimplemented"; } diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp new file mode 100644 index 000000000..9c84a3bf7 --- /dev/null +++ b/src/detection/battery/battery_windows.cpp @@ -0,0 +1,70 @@ +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 + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery", nullptr); + + if(!pEnumerator) + return "Query WMI service failed"; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + { + BatteryResult* battery = (BatteryResult*)ffListAdd(results); + + ffStrbufInit(&battery->manufacturer); + ffGetWmiObjValue(pclsObj, L"SystemName", &battery->manufacturer); + + ffStrbufInit(&battery->modelName); + ffGetWmiObjValue(pclsObj, L"Name", &battery->modelName); + + int64_t chemistry; + ffGetWmiObjInteger(pclsObj, 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; + } + + int64_t capacity; + ffGetWmiObjInteger(pclsObj, L"EstimatedChargeRemaining", &capacity); + ffStrbufInitF(&battery->capacity, "%d", (int)capacity); + + int64_t batteryStatus; + ffGetWmiObjInteger(pclsObj, 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; + } + + battery->temperature = FF_BATTERY_TEMP_UNSET; + } + + pclsObj->Release(); + pEnumerator->Release(); + return nullptr; +} diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index a4938643d..30ba20a4f 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -197,3 +197,34 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu VariantClear(&vtProp); return result; } + +bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* integer) +{ + bool result = true; + + VARIANT vtProp; + VariantInit(&vtProp); + + CIMTYPE type; + if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr))) + { + result = false; + } + else + { + switch(type) + { + case CIM_SINT8: *integer = vtProp.cVal; break; + case CIM_SINT16: *integer = vtProp.iVal; break; + case CIM_SINT32: *integer = vtProp.intVal; break; + case CIM_SINT64: *integer = vtProp.llVal; break; + case CIM_UINT8: *integer = (int64_t)vtProp.bVal; break; + case CIM_UINT16: *integer = (int64_t)vtProp.uiVal; break; + case CIM_UINT32: *integer = (int64_t)vtProp.uintVal; break; + case CIM_UINT64: *integer = (int64_t)vtProp.ullVal; break; + default: result = false; + } + } + VariantClear(&vtProp); + return result; +} diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 86d04099b..827fc88c6 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -34,6 +34,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf); IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error); bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf); +bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* result); #else // Win32 COM headers requires C++ compiler From a0a46ab73ff9cbb5e9608e781f704088dc3a9ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 14:45:02 +0800 Subject: [PATCH 009/311] WMTheme: add support for WIndows --- CMakeLists.txt | 2 +- src/detection/wmtheme/wmtheme_windows.c | 41 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/detection/wmtheme/wmtheme_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f646f91d2..fbbd97bb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -317,7 +317,7 @@ if(WIN_MSYS) src/detection/displayserver/displayserver_windows.c src/detection/terminalfont/terminalfont_linux.c src/detection/media/media_linux.c - src/detection/wmtheme/wmtheme_linux.c + src/detection/wmtheme/wmtheme_windows.c src/detection/font/font_linux.c src/detection/opengl/opengl_windows.c src/util/windows/wmi.cpp diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c new file mode 100644 index 000000000..7611f05da --- /dev/null +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -0,0 +1,41 @@ +#include "fastfetch.h" +#include "wmtheme.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +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) + { + ffStrbufAppendS(themeOrError, "RegOpenKeyExW() failed"); + return false; + } + + bool result = true; + int SystemUsesLightTheme = 1; + DWORD bufSize = sizeof(SystemUsesLightTheme); + + 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(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"); + +exit: + RegCloseKey(hKey); + return result; +} From c0daeb16dffaded1c529e198e1b8e704bb448d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 17:47:49 +0800 Subject: [PATCH 010/311] Users: add support for Windows --- CMakeLists.txt | 28 +++++++++++----- src/detection/users/users.h | 10 ++++++ src/detection/users/users_linux.c | 36 ++++++++++++++++++++ src/detection/users/users_windows.cpp | 42 +++++++++++++++++++++++ src/modules/users.c | 48 ++++++++------------------- src/util/windows/wmi.cpp | 6 ++-- 6 files changed, 125 insertions(+), 45 deletions(-) create mode 100644 src/detection/users/users.h create mode 100644 src/detection/users/users_linux.c create mode 100644 src/detection/users/users_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fbbd97bb1..f28955d12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,19 +269,21 @@ if(BSD OR APPLE) ) endif() -if(LINUX OR ANDROID OR WIN_MSYS) +if(LINUX OR ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c ) endif() -if(LINUX OR ANDROID OR BSD OR WIN_MSYS) +if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c src/detection/poweradapter/poweradapter_linux.c src/detection/temps/temps_linux.c + src/detection/users/users_linux.c + src/detection/opengl/opengl_linux.c ) endif() @@ -302,7 +304,6 @@ if(LINUX OR BSD) src/detection/media/media_linux.c src/detection/wmtheme/wmtheme_linux.c src/detection/font/font_linux.c - src/detection/opengl/opengl_linux.c ) endif() @@ -311,16 +312,27 @@ if(WIN_MSYS) src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp - src/detection/os/os_linux.c src/detection/gpu/gpu_windows.cpp src/detection/battery/battery_windows.cpp src/detection/displayserver/displayserver_windows.c - src/detection/terminalfont/terminalfont_linux.c - src/detection/media/media_linux.c src/detection/wmtheme/wmtheme_windows.c - src/detection/font/font_linux.c src/detection/opengl/opengl_windows.c + src/detection/users/users_windows.cpp src/util/windows/wmi.cpp + + # Shared + src/detection/terminalfont/terminalfont_linux.c + src/detection/poweradapter/poweradapter_linux.c + + # TODO + src/detection/os/os_linux.c + src/detection/media/media_linux.c + src/detection/font/font_linux.c + src/detection/cpu/cpu_linux.c + src/detection/memory/memory_linux.c + src/detection/cpuUsage/cpuUsage_linux.c + src/detection/disk/disk_linux.c + src/detection/temps/temps_linux.c ) endif() @@ -345,6 +357,7 @@ if(APPLE) src/detection/wmtheme/wmtheme_apple.m src/detection/temps/temps_apple.c src/detection/font/font_apple.m + src/detection/users/users_linux.c src/detection/opengl/opengl_apple.c ) endif() @@ -369,7 +382,6 @@ if(ANDROID) src/detection/media/media_android.c src/detection/wmtheme/wmtheme_android.c src/detection/font/font_android.c - src/detection/opengl/opengl_linux.c ) endif() diff --git a/src/detection/users/users.h b/src/detection/users/users.h new file mode 100644 index 000000000..8842e16a2 --- /dev/null +++ b/src/detection/users/users.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_users_users +#define FF_INCLUDED_detection_users_users + +#include "fastfetch.h" + +void ffDetectUsers(FFlist* users /* List of FFstrbuf */, FFstrbuf* error); + +#endif diff --git a/src/detection/users/users_linux.c b/src/detection/users/users_linux.c new file mode 100644 index 000000000..b1dcee8ed --- /dev/null +++ b/src/detection/users/users_linux.c @@ -0,0 +1,36 @@ +#include "fastfetch.h" +#include "users.h" + +#if FF_HAVE_UTMPX_H + #include +#else + //for Android compatibility + #include + #define utmpx utmp + #define setutxent setutent + #define getutxent getutent +#endif + +void ffDetectUsers(FFlist* users, FFstrbuf* error) +{ + struct utmpx* n = NULL; + setutxent(); + +next: + while((n = getutxent())) + { + if(n->ut_type != USER_PROCESS) + continue; + + for(uint32_t i = 0; i < users->length; ++i) + { + if(ffStrbufCompS((FFstrbuf*)ffListGet(users, i), n->ut_user) == 0) + goto next; + } + + ffStrbufInitS((FFstrbuf*)ffListAdd(users), n->ut_user); + } + + if(users->length == 0) + ffStrbufAppendS(error, "Unable to detect users"); +} diff --git a/src/detection/users/users_windows.cpp b/src/detection/users/users_windows.cpp new file mode 100644 index 000000000..7728c1ff3 --- /dev/null +++ b/src/detection/users/users_windows.cpp @@ -0,0 +1,42 @@ +extern "C" { +#include "users.h" +} +#include "util/windows/wmi.hpp" + +void ffDetectUsers(FFlist* users, FFstrbuf* error) +{ + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Antecedent FROM Win32_LoggedOnUser", error); + + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + +next: + while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + { + FFstrbuf antecedent; + ffStrbufInit(&antecedent); + ffGetWmiObjValue(pclsObj, 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"); + + pclsObj->Release(); + pEnumerator->Release(); +} diff --git a/src/modules/users.c b/src/modules/users.c index c1b85f8da..1c78571b2 100644 --- a/src/modules/users.c +++ b/src/modules/users.c @@ -1,48 +1,25 @@ #include "fastfetch.h" #include "common/printing.h" - -#if FF_HAVE_UTMPX_H - #include -#else - //for Android compatibility - #include - #define utmpx utmp - #define setutxent setutent - #define getutxent getutent -#endif +#include "detection/users/users.h" #define FF_USERS_MODULE_NAME "Users" #define FF_USERS_NUM_FORMAT_ARGS 1 void ffPrintUsers(FFinstance* instance) { - struct utmpx* n = NULL; - setutxent(); - FFlist users; - ffListInit(&users, sizeof(n->ut_user) + 1); + ffListInit(&users, sizeof(FFstrbuf)); -next: - while((n = getutxent())) - { - if(n->ut_type == USER_PROCESS) - { - for(uint32_t i = 0; i < users.length; ++i) - { - if(strcmp((const char*)ffListGet(&users, i), n->ut_user) == 0) - goto next; - } - - char* dest = ffListAdd(&users); - strncpy(dest, n->ut_user, sizeof(n->ut_user)); - dest[sizeof(n->ut_user)] = '\0'; - } - } - - if(users.length == 0) + FFstrbuf error; + ffStrbufInit(&error); + + ffDetectUsers(&users, &error); + + if(error.length > 0) { + ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, "%*s", error.length, error.chars); ffListDestroy(&users); - ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, "Unable to detect users"); + ffStrbufDestroy(&error); return; } @@ -52,8 +29,11 @@ next: { if(i > 0) ffStrbufAppendS(&result, ", "); - ffStrbufAppendS(&result, (const char*)ffListGet(&users, i)); + FFstrbuf* user = (FFstrbuf*)ffListGet(&users, i); + ffStrbufAppend(&result, user); + ffStrbufDestroy(user); } + ffListDestroy(&users); if(instance->config.users.outputFormat.length == 0) diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 30ba20a4f..b79fb33a4 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -145,6 +145,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { ffStrbufEnsureFree(strbuf, (uint32_t)size_needed); WideCharToMultiByte(CP_UTF8, 0, bstr, len, strbuf->chars, size_needed, nullptr, nullptr); strbuf->length = (uint32_t)size_needed; + strbuf->chars[size_needed] = '\0'; } bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) @@ -176,7 +177,6 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu case CIM_REAL32: ffStrbufAppendF(strbuf, "%f", vtProp.fltVal); break; case CIM_REAL64: ffStrbufAppendF(strbuf, "%f", vtProp.dblVal); break; case CIM_BOOLEAN: ffStrbufAppendF(strbuf, "%s", vtProp.boolVal ? "True" : "False"); break; - case CIM_STRING: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break; case CIM_DATETIME: { ISWbemDateTime *pDateTime; BSTR dateStr; @@ -190,8 +190,8 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu ffBstrToStrbuf(dateStr, strbuf); break; }; - - default: result = false; break; + case CIM_STRING: + default: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break; } } VariantClear(&vtProp); From 015ad4a30703d6384de219a9fadd7f1f1ba673cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 18:21:10 +0800 Subject: [PATCH 011/311] Fix possible memleaks --- src/common/caching.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/caching.c b/src/common/caching.c index 12a34c82b..14551b120 100644 --- a/src/common/caching.c +++ b/src/common/caching.c @@ -99,7 +99,10 @@ static bool printCachedValue(FFinstance* instance, const char* moduleName, const ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length if(content.length == 0) + { + ffStrbufDestroy(&content); return false; + } uint8_t moduleCounter = 1; From ad03c42a289f61433fdb6782926a439318722703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 20:01:42 +0800 Subject: [PATCH 012/311] OS: add support for Windows --- CMakeLists.txt | 2 +- src/detection/os/os_windows.cpp | 72 +++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/detection/os/os_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f28955d12..a2078097f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,6 +318,7 @@ if(WIN_MSYS) src/detection/wmtheme/wmtheme_windows.c src/detection/opengl/opengl_windows.c src/detection/users/users_windows.cpp + src/detection/os/os_windows.cpp src/util/windows/wmi.cpp # Shared @@ -325,7 +326,6 @@ if(WIN_MSYS) src/detection/poweradapter/poweradapter_linux.c # TODO - src/detection/os/os_linux.c src/detection/media/media_linux.c src/detection/font/font_linux.c src/detection/cpu/cpu_linux.c diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp new file mode 100644 index 000000000..5a20cbf2b --- /dev/null +++ b/src/detection/os/os_windows.cpp @@ -0,0 +1,72 @@ +extern "C" { +#include "os.h" +} +#include "util/windows/wmi.hpp" + +extern "C" +void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) +{ + ffStrbufInit(&os->name); + ffStrbufInit(&os->prettyName); + ffStrbufInit(&os->id); + ffStrbufInit(&os->idLike); + ffStrbufInit(&os->variant); + ffStrbufInit(&os->variantID); + ffStrbufInit(&os->version); + ffStrbufInit(&os->versionID); + ffStrbufInit(&os->codename); + ffStrbufInit(&os->buildID); + ffStrbufInit(&os->systemName); + ffStrbufInit(&os->architecture); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Caption, Version, BuildNumber, OSArchitecture FROM Win32_OperatingSystem", nullptr); + + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + pEnumerator->Release(); + return; + } + + ffGetWmiObjValue(pclsObj, L"Caption", &os->variant); // Microsoft Windows 11 家庭中文版 + if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows ")) + { + ffStrbufAppendS(&os->name, "Microsoft Windows"); + ffStrbufAppendS(&os->prettyName, "Windows"); + + ffStrbufSubstrAfter(&os->variant, strlen("Microsoft Windows ") - 1); // 11 家庭中文版 + uint32_t index = ffStrbufFirstIndexC(&os->variant, ' '); + ffStrbufAppendNS(&os->version, index, os->variant.chars); + ffStrbufSubstrAfter(&os->variant, index); + } + else + { + // Unknown Windows name, please report this + ffStrbufAppend(&os->name, &os->variant); + ffStrbufClear(&os->variant); + } + + #ifdef __CYGWIN__ + ffStrbufAppendS(&os->id, "MSYS2"); + #else + // Enable this after we have Windows logo support + ffStrbufAppendF(&os->id, "Windows %*s", &os->version.length, &os->version.chars); + #endif + + ffGetWmiObjValue(pclsObj, L"BuildNumber", &os->buildID); + ffGetWmiObjValue(pclsObj, L"OSArchitecture", &os->architecture); + + #ifdef __CYGWIN__ + ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); + #else + ffStrbufSetS(&os->systemName, "Windows"); + #endif + + pclsObj->Release(); + pEnumerator->Release(); +} From 8849107260f09e8268b19eb046ac8f269ff49836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 22:07:48 +0800 Subject: [PATCH 013/311] Processes: add support for Windows --- CMakeLists.txt | 3 ++ src/detection/processes/processes.h | 10 ++++++ src/detection/processes/processes_apple.c | 18 ++++++++++ src/detection/processes/processes_linux.c | 12 +++++++ src/detection/processes/processes_windows.cpp | 30 +++++++++++++++++ src/modules/processes.c | 33 ++++++------------- 6 files changed, 83 insertions(+), 23 deletions(-) create mode 100644 src/detection/processes/processes.h create mode 100644 src/detection/processes/processes_apple.c create mode 100644 src/detection/processes/processes_linux.c create mode 100644 src/detection/processes/processes_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a2078097f..2bb2f1604 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,6 +284,7 @@ if(LINUX OR ANDROID OR BSD) src/detection/temps/temps_linux.c src/detection/users/users_linux.c src/detection/opengl/opengl_linux.c + src/detection/processes/processes_linux.c ) endif() @@ -319,6 +320,7 @@ if(WIN_MSYS) src/detection/opengl/opengl_windows.c src/detection/users/users_windows.cpp src/detection/os/os_windows.cpp + src/detection/processes/processes_windows.cpp src/util/windows/wmi.cpp # Shared @@ -359,6 +361,7 @@ if(APPLE) src/detection/font/font_apple.m src/detection/users/users_linux.c src/detection/opengl/opengl_apple.c + src/detection/processes/processes_apple.c ) endif() diff --git a/src/detection/processes/processes.h b/src/detection/processes/processes.h new file mode 100644 index 000000000..bfc4bce6c --- /dev/null +++ b/src/detection/processes/processes.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_processes_processes +#define FF_INCLUDED_detection_processes_processes + +#include "fastfetch.h" + +uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error); + +#endif diff --git a/src/detection/processes/processes_apple.c b/src/detection/processes/processes_apple.c new file mode 100644 index 000000000..32a251b1a --- /dev/null +++ b/src/detection/processes/processes_apple.c @@ -0,0 +1,18 @@ +#include "processes.h" + +#include + +uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) +{ + FF_UNUSED(instance); + + int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; + size_t length; + + if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0) + { + ffStrbufAppend(error, "sysctl() failed"); + return 0; + } + return (uint32_t)(length / sizeof(struct kinfo_proc)); +} diff --git a/src/detection/processes/processes_linux.c b/src/detection/processes/processes_linux.c new file mode 100644 index 000000000..da197b03e --- /dev/null +++ b/src/detection/processes/processes_linux.c @@ -0,0 +1,12 @@ +#include "processes.h" + +uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) +{ + #if FF_HAVE_SYSINFO_H + FF_UNUSED(error); + return (uint32_t) instance->state.sysinfo.procs; + #else + ffStrbufAppendS(error, "Unimplemented"); + return 0; + #endif +} diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp new file mode 100644 index 000000000..e6539f370 --- /dev/null +++ b/src/detection/processes/processes_windows.cpp @@ -0,0 +1,30 @@ +extern "C" { +#include "processes.h" +} +#include "util/windows/wmi.hpp" + +uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) +{ + FF_UNUSED(instance); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error); + + if(!pEnumerator) + return 0; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + ffStrbufAppendS(error, "No Wmi result returned"); + pEnumerator->Release(); + return 0; + } + + int64_t result = 0; + ffGetWmiObjInteger(pclsObj, L"NumberOfProcesses", &result); + pclsObj->Release(); + pEnumerator->Release(); + return (uint32_t)result; +} diff --git a/src/modules/processes.c b/src/modules/processes.c index d424487d8..fa71a7611 100644 --- a/src/modules/processes.c +++ b/src/modules/processes.c @@ -1,47 +1,34 @@ #include "fastfetch.h" #include "common/printing.h" +#include "detection/processes/processes.h" #define FF_PROCESSES_MODULE_NAME "Processes" #define FF_PROCESSES_NUM_FORMAT_ARGS 1 -#ifdef __APPLE__ - #include -#endif - void ffPrintProcesses(FFinstance* instance) { - #if __APPLE__ - int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; - size_t length; + FFstrbuf error; + ffStrbufInit(&error); + uint32_t numProcesses = ffDetectProcesses(instance, &error); - if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0) - { - ffPrintError(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, "sysctl() failed"); - return; - } - uint16_t numProcesses = (uint16_t)(length / sizeof(struct kinfo_proc)); - #elif FF_HAVE_SYSINFO_H - uint16_t numProcesses = (uint16_t) instance->state.sysinfo.procs; - #else - uint16_t numProcesses = 0; - #endif - - if(numProcesses == 0) + if(error.length > 0) { - ffPrintError(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, "Could not get number of processes"); + ffPrintError(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, "%*s", error.length, error.chars); + ffStrbufDestroy(&error); return; } + ffStrbufDestroy(&error); if(instance->config.processes.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes.key); - printf("%hu\n", numProcesses); + printf("%u\n", numProcesses); } else { ffPrintFormat(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, FF_PROCESSES_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT16, &numProcesses} + {FF_FORMAT_ARG_TYPE_UINT, &numProcesses} }); } } From 49921f5ed19e65d40c8cb7ecec243f6b99e135e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Oct 2022 22:56:56 +0800 Subject: [PATCH 014/311] Disk: add support for Windows Also major refactoring of util/windows/wmi --- CMakeLists.txt | 4 +- src/detection/battery/battery_windows.cpp | 16 +- src/detection/bios/bios_windows.cpp | 8 +- src/detection/board/board_windows.cpp | 6 +- src/detection/disk/disk.c | 55 +++++++ src/detection/disk/disk.h | 10 ++ src/detection/disk/disk_apple.m | 4 +- src/detection/disk/disk_linux.c | 6 +- src/detection/disk/disk_windows.cpp | 48 ++++++ src/detection/gpu/gpu_windows.cpp | 6 +- src/detection/host/host_windows.cpp | 8 +- src/detection/os/os_windows.cpp | 6 +- src/detection/processes/processes_windows.cpp | 4 +- src/detection/users/users_windows.cpp | 2 +- src/modules/disk.c | 97 ++++------- src/util/windows/wmi.cpp | 153 +++++++++++++----- src/util/windows/wmi.hpp | 6 +- 17 files changed, 300 insertions(+), 139 deletions(-) create mode 100644 src/detection/disk/disk.c create mode 100644 src/detection/disk/disk_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bb2f1604..6b0060dff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -280,6 +280,7 @@ if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c + src/detection/disk/disk.c src/detection/poweradapter/poweradapter_linux.c src/detection/temps/temps_linux.c src/detection/users/users_linux.c @@ -321,6 +322,7 @@ if(WIN_MSYS) src/detection/users/users_windows.cpp src/detection/os/os_windows.cpp src/detection/processes/processes_windows.cpp + src/detection/disk/disk_windows.cpp src/util/windows/wmi.cpp # Shared @@ -333,7 +335,6 @@ if(WIN_MSYS) src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c src/detection/cpuUsage/cpuUsage_linux.c - src/detection/disk/disk_linux.c src/detection/temps/temps_linux.c ) endif() @@ -356,6 +357,7 @@ if(APPLE) src/detection/terminalfont/terminalfont_apple.m src/detection/media/media_apple.m src/detection/disk/disk_apple.m + src/detection/disk/disk.c src/detection/wmtheme/wmtheme_apple.m src/detection/temps/temps_apple.c src/detection/font/font_apple.m diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp index 9c84a3bf7..48084720a 100644 --- a/src/detection/battery/battery_windows.cpp +++ b/src/detection/battery/battery_windows.cpp @@ -21,13 +21,13 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) BatteryResult* battery = (BatteryResult*)ffListAdd(results); ffStrbufInit(&battery->manufacturer); - ffGetWmiObjValue(pclsObj, L"SystemName", &battery->manufacturer); + ffGetWmiObjString(pclsObj, L"SystemName", &battery->manufacturer); ffStrbufInit(&battery->modelName); - ffGetWmiObjValue(pclsObj, L"Name", &battery->modelName); + ffGetWmiObjString(pclsObj, L"Name", &battery->modelName); - int64_t chemistry; - ffGetWmiObjInteger(pclsObj, L"Chemistry", &chemistry); + uint64_t chemistry; + ffGetWmiObjUnsigned(pclsObj, L"Chemistry", &chemistry); switch(chemistry) { case 1: ffStrbufInitS(&battery->technology, "Other"); break; @@ -40,12 +40,12 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) case 8: ffStrbufInitS(&battery->technology, "Lithium Polymer"); break; } - int64_t capacity; - ffGetWmiObjInteger(pclsObj, L"EstimatedChargeRemaining", &capacity); + uint64_t capacity; + ffGetWmiObjUnsigned(pclsObj, L"EstimatedChargeRemaining", &capacity); ffStrbufInitF(&battery->capacity, "%d", (int)capacity); - int64_t batteryStatus; - ffGetWmiObjInteger(pclsObj, L"BatteryStatus", &batteryStatus); + uint64_t batteryStatus; + ffGetWmiObjUnsigned(pclsObj, L"BatteryStatus", &batteryStatus); switch(batteryStatus) { case 1: ffStrbufInitS(&battery->status, "Discharging"); break; diff --git a/src/detection/bios/bios_windows.cpp b/src/detection/bios/bios_windows.cpp index 6f1dedbb8..d04726ebb 100644 --- a/src/detection/bios/bios_windows.cpp +++ b/src/detection/bios/bios_windows.cpp @@ -28,10 +28,10 @@ extern "C" void ffDetectBios(FFBiosResult* bios) return; } - ffGetWmiObjValue(pclsObj, L"Name", &bios->biosRelease); - ffGetWmiObjValue(pclsObj, L"ReleaseDate", &bios->biosDate); - ffGetWmiObjValue(pclsObj, L"Version", &bios->biosVersion); - ffGetWmiObjValue(pclsObj, L"Manufacturer", &bios->biosVendor); + ffGetWmiObjString(pclsObj, L"Name", &bios->biosRelease); + ffGetWmiObjString(pclsObj, L"ReleaseDate", &bios->biosDate); + ffGetWmiObjString(pclsObj, L"Version", &bios->biosVersion); + ffGetWmiObjString(pclsObj, L"Manufacturer", &bios->biosVendor); pclsObj->Release(); pEnumerator->Release(); diff --git a/src/detection/board/board_windows.cpp b/src/detection/board/board_windows.cpp index 5709a4eb1..895d6f8ed 100644 --- a/src/detection/board/board_windows.cpp +++ b/src/detection/board/board_windows.cpp @@ -27,9 +27,9 @@ extern "C" void ffDetectBoard(FFBoardResult* board) return; } - ffGetWmiObjValue(pclsObj, L"Product", &board->boardName); - ffGetWmiObjValue(pclsObj, L"Manufacturer", &board->boardVendor); - ffGetWmiObjValue(pclsObj, L"Version", &board->boardVersion); + ffGetWmiObjString(pclsObj, L"Product", &board->boardName); + ffGetWmiObjString(pclsObj, L"Manufacturer", &board->boardVendor); + ffGetWmiObjString(pclsObj, L"Version", &board->boardVersion); pclsObj->Release(); pEnumerator->Release(); diff --git a/src/detection/disk/disk.c b/src/detection/disk/disk.c new file mode 100644 index 000000000..325eab362 --- /dev/null +++ b/src/detection/disk/disk.c @@ -0,0 +1,55 @@ +#include "fastfetch.h" +#include "disk.h" + +#include + +void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result) +{ + ffStrbufInitS(&result->path, folderPath); + result->used = result->total = 0; + ffStrbufInit(&result->error); + + struct statvfs newFs; + + if(fs == NULL) + { + fs = &newFs; + int ret = statvfs(folderPath, fs); + if(ret != 0) + { + ffStrbufAppendF(&result->error, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret); + return; + } + } + + result->total = fs->f_blocks * fs->f_frsize; + + if(result->total == 0) + { + ffStrbufAppendF(&result->error, "statvfs for %s returned size 0", folderPath); + return; + } + + result->used = result->total - (fs->f_bavail * fs->f_frsize); + result->files = (uint32_t) (fs->f_files - fs->f_ffree); +} + +bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders) +{ + ffStrbufTrim(&instance->config.diskFolders, ':'); + if(instance->config.diskFolders.length == 0) + return false; + + uint32_t startIndex = 0; + while(startIndex < instance->config.diskFolders.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':'); + instance->config.diskFolders.chars[colonIndex] = '\0'; + + ffDetectDiskWithStatvfs(instance->config.diskFolders.chars + startIndex, NULL, (FFDiskResult*)ffListAdd(folders)); + + startIndex = colonIndex + 1; + } + + return true; +} diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index aaf34a608..06b00b666 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -5,6 +5,16 @@ #include "fastfetch.h" +typedef struct FFDiskResult +{ + FFstrbuf path; + uint64_t used; + uint64_t total; + uint32_t files; + FFstrbuf error; +} FFDiskResult; + const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders); +bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders); #endif diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index 95d5fd8ec..391ec457f 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -2,6 +2,8 @@ #import +void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result); + const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) { NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil]; @@ -18,7 +20,7 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) if(removable.boolValue && !instance->config.diskRemovable) continue; - ffStrbufInitS((FFstrbuf *)ffListAdd(folders), [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]); + ffDetectDiskWithStatvfs([url.relativePath cStringUsingEncoding:NSUTF8StringEncoding], NULL, (FFDiskResult*)ffListAdd(folders)); } return NULL; diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 80d5808c4..eb8ceb0f3 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -2,6 +2,8 @@ #include +void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result); + const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) { FF_UNUSED(instance); @@ -11,12 +13,12 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) if(rootRet != 0) return "statvfs(\"/\") failed"; - ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_ROOT"/"); + ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot, (FFDiskResult*)ffListAdd(folders)); struct statvfs fsHome; int homeRet = statvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome); if(homeRet == 0 && (fsRoot.f_fsid != fsHome.f_fsid)) - ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_HOME); + ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome, (FFDiskResult*)ffListAdd(folders)); return NULL; } diff --git a/src/detection/disk/disk_windows.cpp b/src/detection/disk/disk_windows.cpp new file mode 100644 index 000000000..3a7fb20a0 --- /dev/null +++ b/src/detection/disk/disk_windows.cpp @@ -0,0 +1,48 @@ +extern "C" { +#include "disk.h" +} +#include "util/windows/wmi.hpp" + +const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) +{ + FF_UNUSED(instance); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, DriveType, FreeSpace, Size FROM Win32_LogicalDisk", nullptr); + + if(!pEnumerator) + return "Query WMI service failed"; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + { + uint64_t driveType; + ffGetWmiObjUnsigned(pclsObj, L"DriveType", &driveType); + if(driveType == 2 && !instance->config.diskRemovable) + continue; + + FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); + + ffStrbufInit(&folder->path); + ffGetWmiObjString(pclsObj, L"Name", &folder->path); + + uint64_t free; + ffGetWmiObjUnsigned(pclsObj, L"Size", &folder->total); + ffGetWmiObjUnsigned(pclsObj, L"FreeSpace", &free); + folder->used = folder->total - free; + + folder->files = 0; //Unsupported + + ffStrbufInit(&folder->error); + } + + pclsObj->Release(); + pEnumerator->Release(); + return nullptr; +} + +bool ffDiskDetectDiskFolders(FFinstance*, FFlist*) +{ + return false; // Unsupported +} diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index 90a6fd264..443ad422e 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -21,7 +21,7 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); ffStrbufInit(&gpu->vendor); - ffGetWmiObjValue(pclsObj, L"AdapterCompatibility", &gpu->vendor); + ffGetWmiObjString(pclsObj, L"AdapterCompatibility", &gpu->vendor); if(ffStrbufStartsWithS(&gpu->vendor, "Intel ")) { //Intel returns "Intel Corporation", not sure about AMD @@ -29,10 +29,10 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) } ffStrbufInit(&gpu->name); - ffGetWmiObjValue(pclsObj, L"Name", &gpu->name); + ffGetWmiObjString(pclsObj, L"Name", &gpu->name); ffStrbufInit(&gpu->driver); - ffGetWmiObjValue(pclsObj, L"DriverVersion", &gpu->driver); + ffGetWmiObjString(pclsObj, L"DriverVersion", &gpu->driver); gpu->temperature = FF_GPU_TEMP_UNSET; gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp index 3af7dadf1..34141cf72 100644 --- a/src/detection/host/host_windows.cpp +++ b/src/detection/host/host_windows.cpp @@ -32,10 +32,10 @@ extern "C" void ffDetectHostImpl(FFHostResult* host) return; } - ffGetWmiObjValue(pclsObj, L"Name", &host->productName); - ffGetWmiObjValue(pclsObj, L"Version", &host->productVersion); - ffGetWmiObjValue(pclsObj, L"SKUNumber", &host->productSku); - ffGetWmiObjValue(pclsObj, L"Vendor", &host->sysVendor); + ffGetWmiObjString(pclsObj, L"Name", &host->productName); + ffGetWmiObjString(pclsObj, L"Version", &host->productVersion); + ffGetWmiObjString(pclsObj, L"SKUNumber", &host->productSku); + ffGetWmiObjString(pclsObj, L"Vendor", &host->sysVendor); pclsObj->Release(); pEnumerator->Release(); diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 5a20cbf2b..77f6644bf 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -33,7 +33,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) return; } - ffGetWmiObjValue(pclsObj, L"Caption", &os->variant); // Microsoft Windows 11 家庭中文版 + ffGetWmiObjString(pclsObj, L"Caption", &os->variant); // Microsoft Windows 11 家庭中文版 if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows ")) { ffStrbufAppendS(&os->name, "Microsoft Windows"); @@ -58,8 +58,8 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufAppendF(&os->id, "Windows %*s", &os->version.length, &os->version.chars); #endif - ffGetWmiObjValue(pclsObj, L"BuildNumber", &os->buildID); - ffGetWmiObjValue(pclsObj, L"OSArchitecture", &os->architecture); + ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); + ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); #ifdef __CYGWIN__ ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp index e6539f370..5d491d16e 100644 --- a/src/detection/processes/processes_windows.cpp +++ b/src/detection/processes/processes_windows.cpp @@ -22,8 +22,8 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) return 0; } - int64_t result = 0; - ffGetWmiObjInteger(pclsObj, L"NumberOfProcesses", &result); + uint64_t result = 0; + ffGetWmiObjUnsigned(pclsObj, L"NumberOfProcesses", &result); pclsObj->Release(); pEnumerator->Release(); return (uint32_t)result; diff --git a/src/detection/users/users_windows.cpp b/src/detection/users/users_windows.cpp index 7728c1ff3..43a6fb3d2 100644 --- a/src/detection/users/users_windows.cpp +++ b/src/detection/users/users_windows.cpp @@ -18,7 +18,7 @@ next: { FFstrbuf antecedent; ffStrbufInit(&antecedent); - ffGetWmiObjValue(pclsObj, L"Antecedent", &antecedent); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME" + ffGetWmiObjString(pclsObj, 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, '"'); diff --git a/src/modules/disk.c b/src/modules/disk.c index ea92f7e89..22751e097 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -8,111 +8,76 @@ #define FF_DISK_MODULE_NAME "Disk" #define FF_DISK_NUM_FORMAT_ARGS 4 -static void createKey(FFinstance* instance, const char* folderPath, FFstrbuf* key) +static void printFolder(FFinstance* instance, FFDiskResult* folder) { + FFstrbuf key; + ffStrbufInit(&key); + if(instance->config.disk.key.length == 0) { - ffStrbufAppendS(key, FF_DISK_MODULE_NAME); - if(folderPath != NULL) - ffStrbufAppendF(key, " (%s)", folderPath); + ffStrbufAppendF(&key, "%s (%*s)", FF_DISK_MODULE_NAME, folder->path.length, folder->path.chars); } else { - ffParseFormatString(key, &instance->config.disk.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, folderPath} + ffParseFormatString(&key, &instance->config.disk.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &folder->path} }); } -} -static void printStatvfs(FFinstance* instance, const FFstrbuf* key, const char* folderPath, struct statvfs* fs) -{ - uint64_t total = fs->f_blocks * fs->f_frsize; - - if(total == 0) - { - ffPrintErrorString(instance, key->chars, 0, NULL, &instance->config.disk.errorFormat, "statvfs for %s returned size 0", folderPath); - return; - } - - uint64_t used = total - (fs->f_bavail * fs->f_frsize); - uint32_t files = (uint32_t) (fs->f_files - fs->f_ffree); - uint8_t percentage = (uint8_t) ((used / (long double) total) * 100.0); + uint8_t percentage = (uint8_t) ((folder->used / (long double) folder->total) * 100.0); FFstrbuf usedPretty; ffStrbufInit(&usedPretty); - ffParseSize(used, instance->config.binaryPrefixType, &usedPretty); + ffParseSize(folder->used, instance->config.binaryPrefixType, &usedPretty); FFstrbuf totalPretty; ffStrbufInit(&totalPretty); - ffParseSize(total, instance->config.binaryPrefixType, &totalPretty); + ffParseSize(folder->total, instance->config.binaryPrefixType, &totalPretty); if(instance->config.disk.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, key->chars, 0, NULL); + ffPrintLogoAndKey(instance, key.chars, 0, NULL); printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, percentage); } else { - ffPrintFormatString(instance, key->chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, - {FF_FORMAT_ARG_TYPE_UINT, &files}, + {FF_FORMAT_ARG_TYPE_UINT, &folder->files}, }); } + ffStrbufDestroy(&key); ffStrbufDestroy(&totalPretty); ffStrbufDestroy(&usedPretty); } -static void printFolder(FFinstance* instance, const char* folderPath) -{ - FFstrbuf key; - ffStrbufInit(&key); - createKey(instance, folderPath, &key); - - struct statvfs fs; - int ret = statvfs(folderPath, &fs); - if(ret != 0) - { - ffPrintErrorString(instance, key.chars, 0, NULL, &instance->config.disk.errorFormat, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret); - ffStrbufDestroy(&key); - return; - } - - printStatvfs(instance, &key, folderPath, &fs); - ffStrbufDestroy(&key); -} - void ffPrintDisk(FFinstance* instance) { - ffStrbufTrim(&instance->config.diskFolders, ':'); + FFlist folders; + ffListInit(&folders, sizeof(FFDiskResult)); - if(instance->config.diskFolders.length == 0) + const char* error = NULL; + + if(!ffDiskDetectDiskFolders(instance, &folders)) + error = ffDiskAutodetectFolders(instance, &folders); + + if(error) + { + ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", error); + } + else { - FFlist folders; - ffListInit(&folders, sizeof(FFstrbuf)); - const char* error = ffDiskAutodetectFolders(instance, &folders); - if(error) - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", error); for(uint32_t i = 0; i < folders.length; ++i) { - FFstrbuf* folder = (FFstrbuf*)ffListGet(&folders, i); - printFolder(instance, folder->chars); - ffStrbufDestroy(folder); + FFDiskResult* folder = (FFDiskResult*)ffListGet(&folders, i); + printFolder(instance, folder); + ffStrbufDestroy(&folder->path); + ffStrbufDestroy(&folder->error); } - ffListDestroy(&folders); - return; } - uint32_t startIndex = 0; - while(startIndex < instance->config.diskFolders.length) - { - uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':'); - instance->config.diskFolders.chars[colonIndex] = '\0'; - - printFolder(instance, instance->config.diskFolders.chars + startIndex); - - startIndex = colonIndex + 1; - } + ffListDestroy(&folders); } diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index b79fb33a4..845a3dda4 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -1,6 +1,7 @@ #include "wmi.hpp" #include +#include //https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer //https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes @@ -148,7 +149,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { strbuf->chars[size_needed] = '\0'; } -bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) +bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) { bool result = true; @@ -156,49 +157,49 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu VariantInit(&vtProp); CIMTYPE type; - if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt == VT_EMPTY || vtProp.vt == VT_NULL) + if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt != VT_BSTR) { result = false; } else { - switch(type) + switch(vtProp.vt) { - case CIM_ILLEGAL: - case CIM_EMPTY: result = false; break; - case CIM_SINT8: ffStrbufAppendF(strbuf, "%d", (int)vtProp.cVal); break; - case CIM_SINT16: ffStrbufAppendF(strbuf, "%d", (int)vtProp.iVal); break; - case CIM_SINT32: ffStrbufAppendF(strbuf, "%d", (int)vtProp.intVal); break; - case CIM_SINT64: ffStrbufAppendF(strbuf, "%lld", vtProp.llVal); break; - case CIM_UINT8: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.bVal); break; - case CIM_UINT16: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uiVal); break; - case CIM_UINT32: ffStrbufAppendF(strbuf, "%u", (unsigned)vtProp.uintVal); break; - case CIM_UINT64: ffStrbufAppendF(strbuf, "%llu", vtProp.ullVal); break; - case CIM_REAL32: ffStrbufAppendF(strbuf, "%f", vtProp.fltVal); break; - case CIM_REAL64: ffStrbufAppendF(strbuf, "%f", vtProp.dblVal); break; - case CIM_BOOLEAN: ffStrbufAppendF(strbuf, "%s", vtProp.boolVal ? "True" : "False"); break; - case CIM_DATETIME: { - ISWbemDateTime *pDateTime; - BSTR dateStr; - if(FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime)))) - result = false; - else if(FAILED(pDateTime->put_Value(vtProp.bstrVal))) - result = false; - else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr))) - result = false; + case VT_BSTR: + if(type == CIM_DATETIME) + { + ISWbemDateTime *pDateTime; + BSTR dateStr; + if(FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime)))) + result = false; + else if(FAILED(pDateTime->put_Value(vtProp.bstrVal))) + result = false; + else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr))) + result = false; + else + ffBstrToStrbuf(dateStr, strbuf); + } else - ffBstrToStrbuf(dateStr, strbuf); + { + ffBstrToStrbuf(vtProp.bstrVal, strbuf); + } + break; + + case VT_LPSTR: + ffStrbufAppendS(strbuf, vtProp.pcVal); + break; + + case VT_LPWSTR: // TODO + default: + result = false; break; - }; - case CIM_STRING: - default: ffBstrToStrbuf(vtProp.bstrVal, strbuf); break; } } VariantClear(&vtProp); return result; } -bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* integer) +bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integer) { bool result = true; @@ -212,16 +213,90 @@ bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* inte } else { - switch(type) + switch(vtProp.vt) { - case CIM_SINT8: *integer = vtProp.cVal; break; - case CIM_SINT16: *integer = vtProp.iVal; break; - case CIM_SINT32: *integer = vtProp.intVal; break; - case CIM_SINT64: *integer = vtProp.llVal; break; - case CIM_UINT8: *integer = (int64_t)vtProp.bVal; break; - case CIM_UINT16: *integer = (int64_t)vtProp.uiVal; break; - case CIM_UINT32: *integer = (int64_t)vtProp.uintVal; break; - case CIM_UINT64: *integer = (int64_t)vtProp.ullVal; break; + case VT_BSTR: *integer = wcstoll(vtProp.bstrVal, nullptr, 10); break; + case VT_I1: *integer = vtProp.cVal; break; + case VT_I2: *integer = vtProp.iVal; break; + case VT_INT: + case VT_I4: *integer = vtProp.intVal; break; + case VT_I8: *integer = vtProp.llVal; break; + case VT_UI1: *integer = (int64_t)vtProp.bVal; break; + case VT_UI2: *integer = (int64_t)vtProp.uiVal; break; + case VT_UINT: + case VT_UI4: *integer = (int64_t)vtProp.uintVal; break; + case VT_UI8: *integer = (int64_t)vtProp.ullVal; break; + case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break; + default: result = false; + } + } + VariantClear(&vtProp); + return result; +} + +bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* integer) +{ + bool result = true; + + VARIANT vtProp; + VariantInit(&vtProp); + + if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) + { + result = false; + } + else + { + switch(vtProp.vt) + { + case VT_BSTR: *integer = wcstoull(vtProp.bstrVal, nullptr, 10); break; + case VT_I1: *integer = (uint64_t)vtProp.cVal; break; + case VT_I2: *integer = (uint64_t)vtProp.iVal; break; + case VT_INT: + case VT_I4: *integer = (uint64_t)vtProp.intVal; break; + case VT_I8: *integer = (uint64_t)vtProp.llVal; break; + case VT_UI1: *integer = vtProp.bVal; break; + case VT_UI2: *integer = vtProp.uiVal; break; + case VT_UINT: + case VT_UI4: *integer = vtProp.uintVal; break; + case VT_UI8: *integer = vtProp.ullVal; break; + case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break; + default: result = false; + } + } + VariantClear(&vtProp); + return result; +} + +bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real) +{ + bool result = true; + + VARIANT vtProp; + VariantInit(&vtProp); + + if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) + { + result = false; + } + else + { + switch(vtProp.vt) + { + case VT_BSTR: *real = wcstod(vtProp.bstrVal, nullptr); break; + case VT_I1: *real = vtProp.cVal; break; + case VT_I2: *real = vtProp.iVal; break; + case VT_INT: + case VT_I4: *real = vtProp.intVal; break; + case VT_I8: *real = (double)vtProp.llVal; break; + case VT_UI1: *real = vtProp.bVal; break; + case VT_UI2: *real = vtProp.uiVal; break; + case VT_UINT: + case VT_UI4: *real = vtProp.uintVal; break; + case VT_UI8: *real = (double)vtProp.ullVal; break; + case VT_R4: *real = vtProp.fltVal; break; + case VT_R8: *real = vtProp.dblVal; break; + case VT_BOOL: *real = vtProp.boolVal != VARIANT_FALSE; break; default: result = false; } } diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 827fc88c6..53122dfa2 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -33,8 +33,10 @@ private: void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf); IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error); -bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf); -bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* result); +bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf); +bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integer); +bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* integer); +bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real); #else // Win32 COM headers requires C++ compiler From a7e93faac83505d9d377905ff9f48e747ed7d754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 7 Oct 2022 01:36:32 +0800 Subject: [PATCH 015/311] Disk: print if a folder removable; improve performance --- src/detection/disk/disk.c | 1 + src/detection/disk/disk.h | 1 + src/detection/disk/disk_apple.m | 4 +++- src/detection/disk/disk_windows.cpp | 19 +++++++++++++------ src/modules/disk.c | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/detection/disk/disk.c b/src/detection/disk/disk.c index 325eab362..7d469c2ba 100644 --- a/src/detection/disk/disk.c +++ b/src/detection/disk/disk.c @@ -32,6 +32,7 @@ void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskR result->used = result->total - (fs->f_bavail * fs->f_frsize); result->files = (uint32_t) (fs->f_files - fs->f_ffree); + result->removable = false; //To be set at other place } bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders) diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index 06b00b666..a68347fde 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -11,6 +11,7 @@ typedef struct FFDiskResult uint64_t used; uint64_t total; uint32_t files; + bool removable; FFstrbuf error; } FFDiskResult; diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index 391ec457f..b79d03e86 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -20,7 +20,9 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) if(removable.boolValue && !instance->config.diskRemovable) continue; - ffDetectDiskWithStatvfs([url.relativePath cStringUsingEncoding:NSUTF8StringEncoding], NULL, (FFDiskResult*)ffListAdd(folders)); + FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); + ffDetectDiskWithStatvfs([url.relativePath cStringUsingEncoding:NSUTF8StringEncoding], NULL, folder); + folder->removable = removable.boolValue; } return NULL; diff --git a/src/detection/disk/disk_windows.cpp b/src/detection/disk/disk_windows.cpp index 3a7fb20a0..dce2f92eb 100644 --- a/src/detection/disk/disk_windows.cpp +++ b/src/detection/disk/disk_windows.cpp @@ -7,7 +7,10 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) { FF_UNUSED(instance); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, DriveType, FreeSpace, Size FROM Win32_LogicalDisk", nullptr); + const wchar_t* query = instance->config.diskRemovable + ? L"SELECT Name, DriveType, FreeSpace, Size FROM Win32_LogicalDisk" + : L"SELECT Name, FreeSpace, Size FROM Win32_LogicalDisk WHERE DriveType != 2"; + IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr); if(!pEnumerator) return "Query WMI service failed"; @@ -17,11 +20,6 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) { - uint64_t driveType; - ffGetWmiObjUnsigned(pclsObj, L"DriveType", &driveType); - if(driveType == 2 && !instance->config.diskRemovable) - continue; - FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); ffStrbufInit(&folder->path); @@ -32,6 +30,15 @@ const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) ffGetWmiObjUnsigned(pclsObj, L"FreeSpace", &free); folder->used = folder->total - free; + if(instance->config.diskRemovable) + { + uint64_t driveType; + ffGetWmiObjUnsigned(pclsObj, L"DriveType", &driveType); + folder->removable = driveType == 2; + } + else + folder->removable = false; + folder->files = 0; //Unsupported ffStrbufInit(&folder->error); diff --git a/src/modules/disk.c b/src/modules/disk.c index 22751e097..8f97f54ba 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -37,7 +37,7 @@ static void printFolder(FFinstance* instance, FFDiskResult* folder) if(instance->config.disk.outputFormat.length == 0) { ffPrintLogoAndKey(instance, key.chars, 0, NULL); - printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, percentage); + printf("%s / %s (%u%%)%s\n", usedPretty.chars, totalPretty.chars, percentage, folder->removable ? " [Removable]" : ""); } else { From 32d3edc69012ea5de6f355361ae01150307017e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 7 Oct 2022 15:57:09 +0800 Subject: [PATCH 016/311] CPU: add support for Windows --- CMakeLists.txt | 2 +- src/detection/cpu/cpu_windows.cpp | 51 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/detection/cpu/cpu_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b0060dff..2a4bec5c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,6 +314,7 @@ if(WIN_MSYS) src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp + src/detection/cpu/cpu_windows.cpp src/detection/gpu/gpu_windows.cpp src/detection/battery/battery_windows.cpp src/detection/displayserver/displayserver_windows.c @@ -332,7 +333,6 @@ if(WIN_MSYS) # TODO src/detection/media/media_linux.c src/detection/font/font_linux.c - src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c src/detection/cpuUsage/cpuUsage_linux.c src/detection/temps/temps_linux.c diff --git a/src/detection/cpu/cpu_windows.cpp b/src/detection/cpu/cpu_windows.cpp new file mode 100644 index 000000000..250212cfc --- /dev/null +++ b/src/detection/cpu/cpu_windows.cpp @@ -0,0 +1,51 @@ +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); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, ThreadCount, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3", nullptr); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + pEnumerator->Release(); + return; + } + + ffGetWmiObjString(pclsObj, L"Name", &cpu->name); + ffGetWmiObjString(pclsObj, L"Manufacturer", &cpu->vendor); + + uint64_t value; + + ffGetWmiObjUnsigned(pclsObj, L"NumberOfCores", &value); + cpu->coresPhysical = (uint16_t)value; + ffGetWmiObjUnsigned(pclsObj, L"NumberOfLogicalProcessors", &value); + cpu->coresLogical = (uint16_t)value; + ffGetWmiObjUnsigned(pclsObj, L"ThreadCount", &value); + cpu->coresOnline = (uint16_t)value; + ffGetWmiObjUnsigned(pclsObj, L"CurrentClockSpeed", &value); //There's no MinClockSpeed in Win32_Processor + cpu->frequencyMin = (double)value / 1000.0; + ffGetWmiObjUnsigned(pclsObj, L"MaxClockSpeed", &value); + cpu->frequencyMax = (double)value / 1000.0; + + pclsObj->Release(); + pEnumerator->Release(); +} From 174d885649d5cc45a77e93f928ca735617d531cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 7 Oct 2022 16:52:52 +0800 Subject: [PATCH 017/311] CpuUsage: add support for Windows --- CMakeLists.txt | 2 +- src/detection/cpuUsage/cpuUsage.h | 5 ++- src/detection/cpuUsage/cpuUsage_apple.c | 6 ++-- src/detection/cpuUsage/cpuUsage_linux.c | 7 ++-- src/detection/cpuUsage/cpuUsage_windows.c | 20 +++++++++++ src/modules/cpuUsage.c | 41 +++++++++++++++++------ 6 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 src/detection/cpuUsage/cpuUsage_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a4bec5c4..bb027e73d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -324,6 +324,7 @@ if(WIN_MSYS) src/detection/os/os_windows.cpp src/detection/processes/processes_windows.cpp src/detection/disk/disk_windows.cpp + src/detection/cpuUsage/cpuUsage_windows.c src/util/windows/wmi.cpp # Shared @@ -334,7 +335,6 @@ if(WIN_MSYS) src/detection/media/media_linux.c src/detection/font/font_linux.c src/detection/memory/memory_linux.c - src/detection/cpuUsage/cpuUsage_linux.c src/detection/temps/temps_linux.c ) endif() diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index cddd1866b..131fb77f2 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -3,6 +3,9 @@ #ifndef FF_INCLUDED_detection_cpu_cpuUsage #define FF_INCLUDED_detection_cpu_cpuUsage -const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll); +#include + +// We need to use uint64_t because sizeof(long) == 4 on Windows +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll); #endif diff --git a/src/detection/cpuUsage/cpuUsage_apple.c b/src/detection/cpuUsage/cpuUsage_apple.c index e170a7ceb..38a6b4865 100644 --- a/src/detection/cpuUsage/cpuUsage_apple.c +++ b/src/detection/cpuUsage/cpuUsage_apple.c @@ -4,7 +4,7 @@ #include #include -const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll) +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) { natural_t numCPUs = 0U; processor_info_array_t cpuInfo; @@ -21,8 +21,8 @@ const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll) + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_SYSTEM] + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_NICE]; integer_t total = inUse + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_IDLE]; - *inUseAll += inUse; - *totalAll += total; + *inUseAll += (uint64_t)inUse; + *totalAll += (uint64_t)total; } return NULL; } diff --git a/src/detection/cpuUsage/cpuUsage_linux.c b/src/detection/cpuUsage/cpuUsage_linux.c index c3e9b37aa..8667fd526 100644 --- a/src/detection/cpuUsage/cpuUsage_linux.c +++ b/src/detection/cpuUsage/cpuUsage_linux.c @@ -2,16 +2,17 @@ #include "cpuUsage.h" #include +#include -const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll) +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) { - long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; + uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; FILE* procStat = fopen("/proc/stat", "r"); if(procStat == NULL) return "fopen(\"""/proc/stat\", \"r\") == NULL"; - if (fscanf(procStat, "cpu%ld%ld%ld%ld%ld%ld%ld", &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) + if (fscanf(procStat, "cpu%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) { fclose(procStat); return "fscanf() failed"; diff --git a/src/detection/cpuUsage/cpuUsage_windows.c b/src/detection/cpuUsage/cpuUsage_windows.c new file mode 100644 index 000000000..1aa9ba3f6 --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage_windows.c @@ -0,0 +1,20 @@ +#include "fastfetch.h" +#include "cpuUsage.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +static inline uint64_t fileTimeToUint64(const FILETIME* ft) { + return (((uint64_t)ft->dwHighDateTime) << 32) | ((uint64_t)ft->dwLowDateTime); +} + +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) +{ + FILETIME idleTime, kernelTime, userTime; + if(GetSystemTimes(&idleTime, &kernelTime, &userTime) == 0) + return "GetSystemTimes() failed"; + + *inUseAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime); + *totalAll = *inUseAll + fileTimeToUint64(&idleTime); + return NULL; +} diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c index a41735c82..501072f7b 100644 --- a/src/modules/cpuUsage.c +++ b/src/modules/cpuUsage.c @@ -1,20 +1,39 @@ #include "fastfetch.h" #include "common/printing.h" #include "detection/cpuUsage/cpuUsage.h" -#include -#include + +#if defined(_WIN32) || defined(__CYGWIN__) + #include + #include +#else + #include + #include +#endif #define FF_CPU_USAGE_MODULE_NAME "CPU Usage" #define FF_CPU_USAGE_NUM_FORMAT_ARGS 1 -time_t getTimeInMs() +static inline uint64_t getTimeInMs() { - struct timeval timeNow; - gettimeofday(&timeNow, NULL); - return (timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000); + #if defined(_WIN32) || defined(__CYGWIN__) + return GetTickCount64(); + #else + struct timeval timeNow; + gettimeofday(&timeNow, NULL); + return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000)); + #endif } -static long inUseAll1, totalAll1, startTime; +static inline void sleepInMs(uint32_t msec) +{ + #if defined(_WIN32) || defined(__CYGWIN__) + SleepEx(msec, TRUE); + #else + nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL); + #endif +} + +static uint64_t inUseAll1, totalAll1, startTime; void ffPrepareCPUUsage() { @@ -30,16 +49,16 @@ void ffPrintCPUUsage(FFinstance* instance) error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1); if(error) goto error; - nanosleep(&(struct timespec){ 1, 0 }, NULL); + sleepInMs(1000); } else { - time_t duration = getTimeInMs() - startTime; + uint64_t duration = getTimeInMs() - startTime; if(duration < 1000) - nanosleep(&(struct timespec){ 0, (1000 - duration) * 1000000L }, NULL); + sleepInMs(1000 - (uint32_t) duration); } - long inUseAll2, totalAll2; + uint64_t inUseAll2, totalAll2; error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2); if(error) From a57e334d7331b19fa27b84b7e823af0995b4d2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 7 Oct 2022 19:02:27 +0800 Subject: [PATCH 018/311] CpuUsage: support no wait detection on Windows --- CMakeLists.txt | 2 + src/common/time.h | 35 +++++++++++ src/detection/cpuUsage/cpuUsage.c | 58 +++++++++++++++++++ src/detection/cpuUsage/cpuUsage.h | 7 ++- .../cpuUsage/cpuUsage_nowait_windows.cpp | 26 +++++++++ src/modules/cpuUsage.c | 58 +------------------ 6 files changed, 127 insertions(+), 59 deletions(-) create mode 100644 src/common/time.h create mode 100644 src/detection/cpuUsage/cpuUsage.c create mode 100644 src/detection/cpuUsage/cpuUsage_nowait_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bb027e73d..d91d298e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,6 +211,7 @@ set(LIBFASTFETCH_SRC src/detection/host/host.c src/detection/os/os.c src/detection/cpu/cpu.c + src/detection/cpuUsage/cpuUsage.c src/detection/gpu/gpu.c src/detection/memory/memory.c src/detection/font/font.c @@ -325,6 +326,7 @@ if(WIN_MSYS) src/detection/processes/processes_windows.cpp src/detection/disk/disk_windows.cpp src/detection/cpuUsage/cpuUsage_windows.c + src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/util/windows/wmi.cpp # Shared diff --git a/src/common/time.h b/src/common/time.h new file mode 100644 index 000000000..8b4dcd76e --- /dev/null +++ b/src/common/time.h @@ -0,0 +1,35 @@ +#pragma once + +#ifndef FF_INCLUDED_common_time +#define FF_INCLUDED_common_time + +#include +#if defined(_WIN32) || defined(__CYGWIN__) + #include + #include +#else + #include + #include +#endif + +static inline uint64_t ffTimeGetTick() //In msec +{ + #if defined(_WIN32) || defined(__CYGWIN__) + return GetTickCount64(); + #else + struct timeval timeNow; + gettimeofday(&timeNow, NULL); + return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000)); + #endif +} + +static inline void ffTimeSleep(uint32_t msec) +{ + #if defined(_WIN32) || defined(__CYGWIN__) + SleepEx(msec, TRUE); + #else + nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL); + #endif +} + +#endif diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuUsage/cpuUsage.c new file mode 100644 index 000000000..61aaaf817 --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage.c @@ -0,0 +1,58 @@ +#include "fastfetch.h" +#include "cpuUsage.h" + +#ifndef FF_DETECTION_CPUUSAGE_NOWAIT + +#include "common/time.h" + +#include + +// We need to use uint64_t because sizeof(long) == 4 on Windows +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll); + +static uint64_t inUseAll1, totalAll1, startTime; + +void ffPrepareCPUUsage() +{ + startTime = ffTimeGetTick(); + ffGetCpuUsageInfo(&inUseAll1, &totalAll1); +} + +const char* ffGetCpuUsageResult(double* result) +{ + const char* error = NULL; + if(startTime == 0) + { + error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1); + if(error) + return error; + ffTimeSleep(1000); + } + else + { + uint64_t duration = ffTimeGetTick() - startTime; + if(duration < 1000) + ffTimeSleep(1000 - (uint32_t) duration); + } + + uint64_t inUseAll2, totalAll2; + error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2); + if(error) + return error; + + *result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100; + + return NULL; +} + +#else //FF_DETECTION_CPUUSAGE_NOWAIT + +const char* ffGetCpuUsageResultNoWait(double* result); + +void ffPrepareCPUUsage() {} + +const char* ffGetCpuUsageResult(double* result) { + return ffGetCpuUsageResultNoWait(result); +} + +#endif //FF_DETECTION_CPUUSAGE_NOWAIT diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index 131fb77f2..f1a963992 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -3,9 +3,10 @@ #ifndef FF_INCLUDED_detection_cpu_cpuUsage #define FF_INCLUDED_detection_cpu_cpuUsage -#include +#if defined(_WIN32) || defined(__CYGWIN__) + #define FF_DETECTION_CPUUSAGE_NOWAIT 1 +#endif -// We need to use uint64_t because sizeof(long) == 4 on Windows -const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll); +const char* ffGetCpuUsageResult(double* result); #endif diff --git a/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp b/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp new file mode 100644 index 000000000..19af6ffbe --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp @@ -0,0 +1,26 @@ +extern "C" { +#include "cpuUsage.h" +} +#include "util/windows/wmi.hpp" + +extern "C" const char* ffGetCpuUsageResultNoWait(double* result) +{ + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT LoadPercentage FROM Win32_Processor", nullptr); + if(!pEnumerator) + return "Query WMI service failed"; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + pEnumerator->Release(); + return "No WMI result returned"; + } + + ffGetWmiObjReal(pclsObj, L"LoadPercentage", result); + + pclsObj->Release(); + pEnumerator->Release(); + return NULL; +} diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c index 501072f7b..db8ea2e5d 100644 --- a/src/modules/cpuUsage.c +++ b/src/modules/cpuUsage.c @@ -2,74 +2,20 @@ #include "common/printing.h" #include "detection/cpuUsage/cpuUsage.h" -#if defined(_WIN32) || defined(__CYGWIN__) - #include - #include -#else - #include - #include -#endif - #define FF_CPU_USAGE_MODULE_NAME "CPU Usage" #define FF_CPU_USAGE_NUM_FORMAT_ARGS 1 -static inline uint64_t getTimeInMs() -{ - #if defined(_WIN32) || defined(__CYGWIN__) - return GetTickCount64(); - #else - struct timeval timeNow; - gettimeofday(&timeNow, NULL); - return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000)); - #endif -} - -static inline void sleepInMs(uint32_t msec) -{ - #if defined(_WIN32) || defined(__CYGWIN__) - SleepEx(msec, TRUE); - #else - nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL); - #endif -} - -static uint64_t inUseAll1, totalAll1, startTime; - -void ffPrepareCPUUsage() -{ - startTime = getTimeInMs(); - ffGetCpuUsageInfo(&inUseAll1, &totalAll1); -} - void ffPrintCPUUsage(FFinstance* instance) { - const char* error = NULL; - if(startTime == 0) - { - error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1); - if(error) - goto error; - sleepInMs(1000); - } - else - { - uint64_t duration = getTimeInMs() - startTime; - if(duration < 1000) - sleepInMs(1000 - (uint32_t) duration); - } - - uint64_t inUseAll2, totalAll2; - error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2); + double cpuPercent = 0.0/0.0; + const char* error = ffGetCpuUsageResult(&cpuPercent); if(error) { - error: ffPrintError(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpu, "%s", error); return; } - double cpuPercent = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100; - if(instance->config.cpuUsage.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage.key); From 0a55071f886904c43ba22d1f264a01cdf29e2fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 7 Oct 2022 20:12:48 +0800 Subject: [PATCH 019/311] Memory: add support for Windows --- CMakeLists.txt | 2 +- src/detection/memory/memory_windows.cpp | 67 +++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/detection/memory/memory_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d91d298e9..23c98ec5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -327,6 +327,7 @@ if(WIN_MSYS) src/detection/disk/disk_windows.cpp src/detection/cpuUsage/cpuUsage_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp + src/detection/memory/memory_windows.cpp src/util/windows/wmi.cpp # Shared @@ -336,7 +337,6 @@ if(WIN_MSYS) # TODO src/detection/media/media_linux.c src/detection/font/font_linux.c - src/detection/memory/memory_linux.c src/detection/temps/temps_linux.c ) endif() diff --git a/src/detection/memory/memory_windows.cpp b/src/detection/memory/memory_windows.cpp new file mode 100644 index 000000000..91a42ef3c --- /dev/null +++ b/src/detection/memory/memory_windows.cpp @@ -0,0 +1,67 @@ +extern "C" { +#include "memory.h" +} +#include "util/windows/wmi.hpp" + +void detectRam(FFMemoryStorage* ram) +{ + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + ffStrbufInitS(&ram->error, "No WMI result returned"); + pEnumerator->Release(); + return; + } + + //KB + ffGetWmiObjUnsigned(pclsObj, L"TotalVisibleMemorySize", &ram->bytesTotal); + uint64_t bytesFree; + ffGetWmiObjUnsigned(pclsObj, L"FreePhysicalMemory", &bytesFree); + ram->bytesUsed = ram->bytesTotal - bytesFree; + + pclsObj->Release(); + pEnumerator->Release(); + + ram->bytesTotal *= 1024; + ram->bytesUsed *= 1024; +} + +void detectSwap(FFMemoryStorage* swap) +{ + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + ffStrbufInitS(&swap->error, "No WMI result returned"); + pEnumerator->Release(); + return; + } + + //MB + ffGetWmiObjUnsigned(pclsObj, L"AllocatedBaseSize", &swap->bytesTotal); + ffGetWmiObjUnsigned(pclsObj, L"CurrentUsage", &swap->bytesUsed); + + pclsObj->Release(); + pEnumerator->Release(); + + swap->bytesTotal *= 1024 * 1024; + swap->bytesUsed *= 1024 * 1024; +} + +extern "C" +void ffDetectMemoryImpl(FFMemoryResult* memory) +{ + detectRam(&memory->ram); + detectSwap(&memory->swap); +} From cc490294e9ae2906cd1f97d518ed514742d24664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 7 Oct 2022 22:04:41 +0800 Subject: [PATCH 020/311] Font: add support for Windows --- CMakeLists.txt | 2 +- src/detection/font/font.h | 7 +++-- src/detection/font/font_windows.cpp | 44 +++++++++++++++++++++++++++++ src/modules/font.c | 10 +++++++ 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/detection/font/font_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 23c98ec5e..87824b5f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -328,6 +328,7 @@ if(WIN_MSYS) src/detection/cpuUsage/cpuUsage_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp + src/detection/font/font_windows.cpp src/util/windows/wmi.cpp # Shared @@ -336,7 +337,6 @@ if(WIN_MSYS) # TODO src/detection/media/media_linux.c - src/detection/font/font_linux.c src/detection/temps/temps_linux.c ) endif() diff --git a/src/detection/font/font.h b/src/detection/font/font.h index fa02bbd37..3cef2507f 100644 --- a/src/detection/font/font.h +++ b/src/detection/font/font.h @@ -12,9 +12,10 @@ typedef struct FFFontResult FFstrbuf error; /** - * Linux / BSD: QT, GTK2, GTK3, GTK4 - * MacOS: System, User, Monospace, Application - * Other: Unset, Unset, Unset, Unset + * Linux / BSD: QT, GTK2, GTK3, GTK4 + * MacOS: System, User, Monospace, Application + * Windows: Desktop, User, Unset, Unset + * Other: Unset, Unset, Unset, Unset */ FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS]; } FFFontResult; diff --git a/src/detection/font/font_windows.cpp b/src/detection/font/font_windows.cpp new file mode 100644 index 000000000..1d4196bde --- /dev/null +++ b/src/detection/font/font_windows.cpp @@ -0,0 +1,44 @@ +extern "C" { +#include "font.h" +#include "common/font.h" +} +#include "util/windows/wmi.hpp" + +#include + +extern "C" +void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) +{ + wchar_t query[256] = {}; + swprintf(query, 256, L"SELECT IconTitleFaceName, IconTitleSize FROM Win32_Desktop WHERE Name LIKE '%%\\\\%s'", instance->state.passwd->pw_name); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, &result->error); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + + if(uReturn == 0) + { + ffStrbufInitS(&result->error, "No WMI result returned"); + pEnumerator->Release(); + return; + } + + FFstrbuf fontName; + ffStrbufInit(&fontName); + ffGetWmiObjString(pclsObj, L"IconTitleFaceName", &fontName); + + uint64_t fontSize; + ffGetWmiObjUnsigned(pclsObj, L"IconTitleSize", &fontSize); + + ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize); + + ffStrbufDestroy(&fontName); + + pclsObj->Release(); + pEnumerator->Release(); +} diff --git a/src/modules/font.c b/src/modules/font.c index bcf8fd14d..74de29d23 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -40,6 +40,16 @@ static void printFont(const FFFontResult* font) printf("%s [User]", font->fonts[1].chars); } +#elif defined(_WIN32) || defined(__CYGWIN__) + +static void printFont(const FFFontResult* font) +{ + if(font->fonts[0].length > 0) + { + printf("%s [Desktop]", font->fonts[0].chars); + } +} + #else static void printFont(const FFFontResult* font) From 8246c6e61df8d92f8b0fbae434b7eeffc994b08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 15:06:03 +0800 Subject: [PATCH 021/311] Windows: builds without exceptions and RTTI which removes libstdc++ dependency --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87824b5f7..abe6a1199 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") if(WIN_MSYS) set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti") endif() # Used for dlopen finding dylibs installed by homebrew From 09a2f96cf0c60a78423f781ba5d17cfebddf838d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 16:04:55 +0800 Subject: [PATCH 022/311] TerminalShell: add support for Windows --- CMakeLists.txt | 20 ++- .../{processing.c => processing_linux.c} | 0 src/common/processing_windows.c | 69 ++++++++ src/detection/host/host_linux.c | 2 - src/detection/terminalfont/terminalfont.c | 2 +- .../terminalfont/terminalfont_android.c | 2 +- .../terminalfont/terminalfont_apple.m | 2 +- .../terminalfont/terminalfont_linux.c | 2 +- .../{ => terminalshell}/terminalshell.h | 0 .../terminalshell_linux.c} | 13 +- .../terminalshell/terminalshell_windows.cpp | 149 ++++++++++++++++++ src/logo/logo.c | 2 +- src/modules/locale.c | 1 - src/modules/shell.c | 4 +- src/modules/terminal.c | 8 +- 15 files changed, 249 insertions(+), 27 deletions(-) rename src/common/{processing.c => processing_linux.c} (100%) create mode 100644 src/common/processing_windows.c rename src/detection/{ => terminalshell}/terminalshell.h (100%) rename src/detection/{terminalShell.c => terminalshell/terminalshell_linux.c} (96%) create mode 100644 src/detection/terminalshell/terminalshell_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index abe6a1199..3877d1a81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,7 +191,6 @@ set(LIBFASTFETCH_SRC src/common/caching.c src/common/properties.c src/common/font.c - src/common/processing.c src/common/format.c src/common/parsing.c src/common/settings.c @@ -204,7 +203,6 @@ set(LIBFASTFETCH_SRC src/logo/image/im6.c src/detection/qt.c src/detection/gtk.c - src/detection/terminalShell.c src/detection/vulkan.c src/detection/datetime.c src/detection/title.c @@ -264,6 +262,15 @@ set(LIBFASTFETCH_SRC src/modules/users.c ) +if(LINUX OR APPLE OR ANDROID OR BSD) + list(APPEND LIBFASTFETCH_SRC + src/detection/users/users_linux.c + src/common/processing_linux.c + src/detection/disk/disk.c + src/detection/terminalShell/terminalShell_linux.c + ) +endif() + if(BSD OR APPLE) list(APPEND LIBFASTFETCH_SRC src/common/sysctl.c @@ -281,10 +288,8 @@ if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c - src/detection/disk/disk.c src/detection/poweradapter/poweradapter_linux.c src/detection/temps/temps_linux.c - src/detection/users/users_linux.c src/detection/opengl/opengl_linux.c src/detection/processes/processes_linux.c ) @@ -312,6 +317,7 @@ endif() if(WIN_MSYS) list(APPEND LIBFASTFETCH_SRC + src/common/processing_linux.c src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp @@ -329,13 +335,13 @@ if(WIN_MSYS) src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp src/detection/font/font_windows.cpp + src/detection/terminalShell/terminalShell_linux.c + src/detection/terminalShell/terminalShell_windows.cpp src/util/windows/wmi.cpp # Shared src/detection/terminalfont/terminalfont_linux.c src/detection/poweradapter/poweradapter_linux.c - - # TODO src/detection/media/media_linux.c src/detection/temps/temps_linux.c ) @@ -359,11 +365,9 @@ if(APPLE) src/detection/terminalfont/terminalfont_apple.m src/detection/media/media_apple.m src/detection/disk/disk_apple.m - src/detection/disk/disk.c src/detection/wmtheme/wmtheme_apple.m src/detection/temps/temps_apple.c src/detection/font/font_apple.m - src/detection/users/users_linux.c src/detection/opengl/opengl_apple.c src/detection/processes/processes_apple.c ) diff --git a/src/common/processing.c b/src/common/processing_linux.c similarity index 100% rename from src/common/processing.c rename to src/common/processing_linux.c diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c new file mode 100644 index 000000000..f3bb64a2d --- /dev/null +++ b/src/common/processing_windows.c @@ -0,0 +1,69 @@ +#include "fastfetch.h" +#include "common/processing.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +//We can't use this native version yet because we still use POSIX path ( eg /usr/bin/fish ) at a lot of places. +const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) +{ + SECURITY_ATTRIBUTES saAttr = { + .nLength = sizeof(SECURITY_ATTRIBUTES), + .lpSecurityDescriptor = NULL, + .bInheritHandle = TRUE, + }; + + HANDLE hChildStdoutRead, hChildStdoutWrite; + if (!CreatePipe(&hChildStdoutRead, &hChildStdoutWrite, &saAttr, 0)) + return "CreatePipe() failed"; + + if (!SetHandleInformation(hChildStdoutRead, HANDLE_FLAG_INHERIT, 0)) + return "SetHandleInformation(hChildStdoutRead) failed"; + + PROCESS_INFORMATION piProcInfo = {0}; + STARTUPINFOA siStartInfo = { + .cb = sizeof(siStartInfo), + .dwFlags = STARTF_USESTDHANDLES, + .hStdOutput = hChildStdoutWrite, + }; + + FFstrbuf cmdline; + ffStrbufInit(&cmdline); + for(char* const* parg = argv; *parg; ++parg) + { + if(cmdline.length > 0) + ffStrbufAppendC(&cmdline, ' '); + ffStrbufAppendF(&cmdline, "\"%s\"", * parg); + } + + 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 + + CloseHandle(hChildStdoutWrite); + if(!success) + { + CloseHandle(hChildStdoutRead); + return "CreateProcessA() failed"; + } + + char str[128]; + DWORD nRead; + while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0) + { + ffStrbufAppendNS(buffer, nRead, str); + if(nRead < sizeof(str)) + break; + } + + CloseHandle(hChildStdoutRead); + return NULL; +} diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c index c518da1ec..ef9cfbf5e 100644 --- a/src/detection/host/host_linux.c +++ b/src/detection/host/host_linux.c @@ -95,7 +95,5 @@ 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); - else if(getenv("MSYSTEM") != NULL && strcmp(getenv("MSYSTEM"), "MSYS") == 0) - ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS); } } diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 1eff1738f..66ab7965c 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -2,7 +2,7 @@ #include "common/properties.h" #include "common/processing.h" #include "detection/internal.h" -#include "detection/terminalshell.h" +#include "detection/terminalshell/terminalshell.h" static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { FFstrbuf fontName; diff --git a/src/detection/terminalfont/terminalfont_android.c b/src/detection/terminalfont/terminalfont_android.c index 8211ab1d2..24a9baacd 100644 --- a/src/detection/terminalfont/terminalfont_android.c +++ b/src/detection/terminalfont/terminalfont_android.c @@ -1,6 +1,6 @@ #include "fastfetch.h" #include "terminalfont.h" -#include "detection/terminalshell.h" +#include "detection/terminalshell/terminalshell.h" #include "common/io.h" #include diff --git a/src/detection/terminalfont/terminalfont_apple.m b/src/detection/terminalfont/terminalfont_apple.m index ffe0064af..fb8c2769b 100644 --- a/src/detection/terminalfont/terminalfont_apple.m +++ b/src/detection/terminalfont/terminalfont_apple.m @@ -1,6 +1,6 @@ #include "terminalfont.h" #include "common/font.h" -#include "detection/terminalshell.h" +#include "detection/terminalshell/terminalshell.h" #include "util/apple/osascript.h" #include diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 24a62e9d5..74392b55e 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -2,7 +2,7 @@ #include "common/settings.h" #include "common/properties.h" #include "common/parsing.h" -#include "detection/terminalshell.h" +#include "detection/terminalshell/terminalshell.h" #include "detection/displayserver/displayserver.h" static const char* getSystemMonospaceFont(const FFinstance* instance) diff --git a/src/detection/terminalshell.h b/src/detection/terminalshell/terminalshell.h similarity index 100% rename from src/detection/terminalshell.h rename to src/detection/terminalshell/terminalshell.h diff --git a/src/detection/terminalShell.c b/src/detection/terminalshell/terminalshell_linux.c similarity index 96% rename from src/detection/terminalShell.c rename to src/detection/terminalshell/terminalshell_linux.c index 9ebe8bee1..a2c0a4eac 100644 --- a/src/detection/terminalShell.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -1,9 +1,9 @@ #include "fastfetch.h" #include "detection/host/host.h" -#include "detection/terminalshell.h" #include "common/io.h" #include "common/parsing.h" #include "common/processing.h" +#include "terminalshell.h" #include #include @@ -94,6 +94,7 @@ static void getTerminalShell(FFTerminalShellResult* result, const char* pid) strcasecmp(name, "ksh") == 0 || strcasecmp(name, "fish") == 0 || strcasecmp(name, "dash") == 0 || + strcasecmp(name, "pwsh") == 0 || strcasecmp(name, "git-shell") == 0 ) { ffStrbufAppendS(&result->shellProcessName, name); @@ -256,13 +257,19 @@ static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* versio getShellVersionBash(exe, version); else if(strcasecmp(exeName, "zsh") == 0) getShellVersionZsh(exe, version); - else if(strcasecmp(exeName, "fish") == 0) + else if(strcasecmp(exeName, "fish") == 0 || strcasecmp(exeName, "pwsh") == 0) getShellVersionFish(exe, version); else getShellVersionGeneric(exe, exeName, version); } -const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) +const FFTerminalShellResult* +#if defined(__CYGWIN__) || defined(_WIN32) + ffDetectTerminalShellPosix +#else + ffDetectTerminalShell +#endif +(const FFinstance* instance) { FF_UNUSED(instance); diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp new file mode 100644 index 000000000..fdaf98a77 --- /dev/null +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -0,0 +1,149 @@ +extern "C" { +#include "terminalshell.h" +#include "common/processing.h" +} +#include "util/windows/wmi.hpp" + +#include +#include +#include + +struct ProcessInfo +{ + uint32_t pid; + FFstrbuf psName; +}; + +static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe) +{ + wchar_t query[256] = {}; + swprintf(query, 256, L"SELECT Name, ParentProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId = %" PRIu32, pid); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr); + if(!pEnumerator) + return false; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + pEnumerator->Release(); + return false; + } + + if(ppid) + { + uint64_t value; + ffGetWmiObjUnsigned(pclsObj, L"ParentProcessId", &value); + *ppid = (uint32_t) value; + } + + if(pname) + ffGetWmiObjString(pclsObj, L"Name", pname); + + if(exe) + ffGetWmiObjString(pclsObj, L"ExecutablePath", exe); + + pclsObj->Release(); + pEnumerator->Release(); + return true; +} + +static void getShellVersion(FFstrbuf* exe, FFstrbuf* version) +{ + char* const argv[] = { exe->chars, "--version", NULL }; + ffProcessAppendStdOut(version, argv); + ffStrbufTrimRight(version, '\n'); + ffStrbufSubstrAfterLastC(version, ' '); +} + +static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) +{ + uint32_t ppid; + + if(!getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe)) + return 0; + result->shellExeName = result->shellExe.chars + ffStrbufLastIndexC(&result->shellExe, '\\') + 1; + + if(ffStrbufEndsWithIgnCaseS(&result->shellProcessName, ".exe")) + ffStrbufSubstrBefore(&result->shellProcessName, result->shellProcessName.length - 4); + + if(ffStrbufIgnCaseCompS(&result->shellProcessName, "pwsh") == 0) + { + ffStrbufSetS(&result->shellProcessName, "PowerShell"); + getShellVersion(&result->shellExe, &result->shellVersion); + } + else if(ffStrbufIgnCaseCompS(&result->shellProcessName, "powershell") == 0) + ffStrbufSetS(&result->shellProcessName, "Windows PowerShell"); + + return ppid; +} + +static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) +{ + uint32_t ppid; + + if(!getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe)) + return 0; + result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\'); + + if(ffStrbufEndsWithIgnCaseS(&result->terminalProcessName, ".exe")) + result->terminalProcessName.length -= 4; + + if(ffStrbufIgnCaseCompS(&result->terminalProcessName, "WindowsTerminal")) + ffStrbufSetS(&result->terminalProcessName, "Windows Terminal"); + else if(ffStrbufIgnCaseCompS(&result->terminalProcessName, "conhost")) + ffStrbufSetS(&result->terminalProcessName, "Console Window Host"); + + return ppid; +} + +#ifdef __CYGWIN__ + extern "C" + const FFTerminalShellResult* ffDetectTerminalShellPosix(const FFinstance* instance); +#endif + +const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) +{ + #ifdef __CYGWIN__ + // This is hacky. + // When running inside MSYS2, the real Windows parent process doesn't exist and we must find it in Linux way ( /proc/self/xxx ) + // When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way + if(getenv("MSYSTEM")) + return ffDetectTerminalShellPosix(instance); + #endif + + static FFTerminalShellResult result; + static bool init = false; + if(init) + return &result; + init = true; + + ffStrbufInit(&result.shellProcessName); + ffStrbufInitA(&result.shellExe, 128); + result.shellExeName = result.shellExe.chars; + ffStrbufInit(&result.shellVersion); + + ffStrbufInit(&result.terminalProcessName); + ffStrbufInitA(&result.terminalExe, 128); + result.terminalExeName = result.terminalExe.chars; + + ffStrbufInit(&result.userShellExe); + result.userShellExeName = result.userShellExe.chars; + ffStrbufInit(&result.userShellVersion); + + uint32_t ppid = GetCurrentProcessId(); + if(!getProcessInfo(ppid, &ppid, nullptr, nullptr)) + return &result; + + ppid = getShellInfo(&result, ppid); + if(ppid == 0) + return &result; + + ppid = getTerminalInfo(&result, ppid); + if(ppid == 0) + return &result; + + return &result; +} diff --git a/src/logo/logo.c b/src/logo/logo.c index e0340d571..93667ddd3 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -2,7 +2,7 @@ #include "common/io.h" #include "common/printing.h" #include "detection/os/os.h" -#include "detection/terminalshell.h" +#include "detection/terminalshell/terminalshell.h" #include #include diff --git a/src/modules/locale.c b/src/modules/locale.c index 1d1c27456..954e29383 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -2,7 +2,6 @@ #include "common/properties.h" #include "common/printing.h" #include "common/caching.h" -#include "common/processing.h" #include "common/parsing.h" #include diff --git a/src/modules/shell.c b/src/modules/shell.c index 3ea71f05e..b9486bc2c 100644 --- a/src/modules/shell.c +++ b/src/modules/shell.c @@ -1,6 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" -#include "detection/terminalshell.h" +#include "detection/terminalshell/terminalshell.h" #define FF_SHELL_MODULE_NAME "Shell" #define FF_SHELL_NUM_FORMAT_ARGS 7 @@ -18,7 +18,7 @@ void ffPrintShell(FFinstance* instance) if(instance->config.shell.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell.key); - fputs(result->shellExeName, stdout); + ffStrbufWriteTo(&result->shellProcessName, stdout); if(result->shellVersion.length > 0) { diff --git a/src/modules/terminal.c b/src/modules/terminal.c index 4d930a445..c89afbb78 100644 --- a/src/modules/terminal.c +++ b/src/modules/terminal.c @@ -1,6 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" -#include "detection/terminalshell.h" +#include "detection/terminalshell/terminalshell.h" #include @@ -20,11 +20,7 @@ void ffPrintTerminal(FFinstance* instance) if(instance->config.terminal.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal.key); - - if(strncmp(result->terminalExeName, result->terminalProcessName.chars, result->terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName - puts(result->terminalExeName); - else - ffStrbufPutTo(&result->terminalProcessName, stdout); + ffStrbufPutTo(&result->terminalProcessName, stdout); } else { From 89850535aeada15349a210151ec9618ac981006f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 16:07:59 +0800 Subject: [PATCH 023/311] Windows: replace __CYGWIN__ with __MSYS__ --- src/common/init.c | 2 +- src/common/time.h | 6 +++--- src/detection/cpuUsage/cpuUsage.h | 2 +- src/detection/os/os_windows.cpp | 4 ++-- src/detection/terminalshell/terminalshell_linux.c | 2 +- src/detection/terminalshell/terminalshell_windows.cpp | 4 ++-- src/modules/font.c | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 8eb87dc58..d34d78f65 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -259,7 +259,7 @@ void ffInitInstance(FFinstance* instance) defaultConfig(instance); } -#if !defined(__ANDROID__) && !defined(__CYGWIN__) +#if !defined(__ANDROID__) && !defined(_WIN32) && !defined(__MSYS__) static void* connectDisplayServerThreadMain(void* instance) { diff --git a/src/common/time.h b/src/common/time.h index 8b4dcd76e..7569d40e2 100644 --- a/src/common/time.h +++ b/src/common/time.h @@ -4,7 +4,7 @@ #define FF_INCLUDED_common_time #include -#if defined(_WIN32) || defined(__CYGWIN__) +#if defined(_WIN32) || defined(__MSYS__) #include #include #else @@ -14,7 +14,7 @@ static inline uint64_t ffTimeGetTick() //In msec { - #if defined(_WIN32) || defined(__CYGWIN__) + #if defined(_WIN32) || defined(__MSYS__) return GetTickCount64(); #else struct timeval timeNow; @@ -25,7 +25,7 @@ static inline uint64_t ffTimeGetTick() //In msec static inline void ffTimeSleep(uint32_t msec) { - #if defined(_WIN32) || defined(__CYGWIN__) + #if defined(_WIN32) || defined(__MSYS__) SleepEx(msec, TRUE); #else nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL); diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index f1a963992..0c76275c0 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -3,7 +3,7 @@ #ifndef FF_INCLUDED_detection_cpu_cpuUsage #define FF_INCLUDED_detection_cpu_cpuUsage -#if defined(_WIN32) || defined(__CYGWIN__) +#if defined(_WIN32) || defined(__MSYS__) #define FF_DETECTION_CPUUSAGE_NOWAIT 1 #endif diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 77f6644bf..7a0c54665 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -51,7 +51,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufClear(&os->variant); } - #ifdef __CYGWIN__ + #ifdef __MSYS__ ffStrbufAppendS(&os->id, "MSYS2"); #else // Enable this after we have Windows logo support @@ -61,7 +61,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); - #ifdef __CYGWIN__ + #ifdef __MSYS__ ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); #else ffStrbufSetS(&os->systemName, "Windows"); diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index a2c0a4eac..2897a7c8e 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -264,7 +264,7 @@ static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* versio } const FFTerminalShellResult* -#if defined(__CYGWIN__) || defined(_WIN32) +#if defined(__MSYS__) || defined(_WIN32) ffDetectTerminalShellPosix #else ffDetectTerminalShell diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index fdaf98a77..9ef0d9c6b 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -99,14 +99,14 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) return ppid; } -#ifdef __CYGWIN__ +#ifdef __MSYS__ extern "C" const FFTerminalShellResult* ffDetectTerminalShellPosix(const FFinstance* instance); #endif const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { - #ifdef __CYGWIN__ + #ifdef __MSYS__ // This is hacky. // When running inside MSYS2, the real Windows parent process doesn't exist and we must find it in Linux way ( /proc/self/xxx ) // When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way diff --git a/src/modules/font.c b/src/modules/font.c index 74de29d23..176243adf 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -40,7 +40,7 @@ static void printFont(const FFFontResult* font) printf("%s [User]", font->fonts[1].chars); } -#elif defined(_WIN32) || defined(__CYGWIN__) +#elif defined(_WIN32) || defined(__MSYS__) static void printFont(const FFFontResult* font) { From af6b7dd81b6fe64334d9f2cda3a43aa07dcc5d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 17:41:25 +0800 Subject: [PATCH 024/311] Packages: add support for Windows --- CMakeLists.txt | 3 + src/common/io.h | 2 + src/detection/packages/packages.h | 32 ++ src/detection/packages/packages_linux.c | 448 ++++++++++++++++++++ src/detection/packages/packages_windows.c | 41 ++ src/fastfetch.c | 3 +- src/modules/packages.c | 477 +--------------------- 7 files changed, 540 insertions(+), 466 deletions(-) create mode 100644 src/detection/packages/packages.h create mode 100644 src/detection/packages/packages_linux.c create mode 100644 src/detection/packages/packages_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3877d1a81..ee36893a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,6 +268,7 @@ if(LINUX OR APPLE OR ANDROID OR BSD) src/common/processing_linux.c src/detection/disk/disk.c src/detection/terminalShell/terminalShell_linux.c + src/detection/packages/packages_linux.c ) endif() @@ -337,6 +338,8 @@ if(WIN_MSYS) src/detection/font/font_windows.cpp src/detection/terminalShell/terminalShell_linux.c src/detection/terminalShell/terminalShell_windows.cpp + src/detection/packages/packages_linux.c + src/detection/packages/packages_windows.c src/util/windows/wmi.cpp # Shared diff --git a/src/common/io.h b/src/common/io.h index 35a70675f..a6ecbc5ac 100644 --- a/src/common/io.h +++ b/src/common/io.h @@ -3,6 +3,8 @@ #ifndef FF_INCLUDED_common_io #define FF_INCLUDED_common_io +#include "fastfetch.h" + #include //mode_t bool ffWriteFDBuffer(int fd, const FFstrbuf* content); diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h new file mode 100644 index 000000000..9ecfdb7e9 --- /dev/null +++ b/src/detection/packages/packages.h @@ -0,0 +1,32 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_packages_packages +#define FF_INCLUDED_detection_packages_packages + +#include "fastfetch.h" + +typedef struct FFPackageCounts +{ + uint32_t pacman; + uint32_t dpkg; + uint32_t rpm; + uint32_t emerge; + uint32_t xbps; + uint32_t nixSystem; + uint32_t nixDefault; + uint32_t apk; + uint32_t pkg; + uint32_t flatpak; + uint32_t snap; + uint32_t brew; + uint32_t port; + uint32_t scoop; + + FFstrbuf pacmanBranch; + + uint32_t nixUser; +} FFPackageCounts; + +void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts); + +#endif diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c new file mode 100644 index 000000000..cf20d28dd --- /dev/null +++ b/src/detection/packages/packages_linux.c @@ -0,0 +1,448 @@ +#include "common/io.h" +#include "common/properties.h" +#include "common/settings.h" +#include "common/processing.h" +#include "common/parsing.h" +#include "detection/os/os.h" + +#include "packages.h" + +#include +#include +#include +#include + +static uint32_t getNumElements(const char* dirname, unsigned char type) +{ + DIR* dirp = opendir(dirname); + if(dirp == NULL) + return 0; + + uint32_t num_elements = 0; + + struct dirent *entry; + while((entry = readdir(dirp)) != NULL) { + if(entry->d_type == type) + ++num_elements; + } + + if(type == DT_DIR) + num_elements -= 2; // accounting for . and .. + + closedir(dirp); + + return num_elements; +} + +#ifndef __APPLE__ + +static uint32_t getNumStrings(const char* filename, const char* needle) +{ + FILE* file = fopen(filename, "r"); + if(file == NULL) + return 0; + + uint32_t count = 0; + + char* line = NULL; + size_t len = 0; + + while(getline(&line, &len, file) != EOF) + { + if(strstr(line, needle) != NULL) + ++count; + } + + if(line != NULL) + free(line); + + fclose(file); + + return count; +} + +#ifndef __ANDROID__ + +static uint32_t countFilesRecursive(FFstrbuf* baseDirPath, const char* filename) +{ + uint32_t baseDirPathLength = baseDirPath->length; + + ffStrbufAppendC(baseDirPath, '/'); + ffStrbufAppendS(baseDirPath, filename); + bool exists = ffFileExists(baseDirPath->chars, S_IFREG); + ffStrbufSubstrBefore(baseDirPath, baseDirPathLength); + if(exists) + return 1; + + DIR* dirp = opendir(baseDirPath->chars); + if(dirp == NULL) + return 0; + + ffStrbufAppendC(baseDirPath, '/'); + baseDirPathLength = baseDirPath->length; + + uint32_t sum = 0; + + struct dirent *entry; + while((entry = readdir(dirp)) != NULL) { + // According to the PMS, neither category nor package name can begin with '.', so no need to check for . or .. specifically + if(entry->d_type != DT_DIR || entry->d_name[0] == '.') + continue; + + ffStrbufAppendS(baseDirPath, entry->d_name); + sum += countFilesRecursive(baseDirPath, filename); + ffStrbufSubstrBefore(baseDirPath, baseDirPathLength); + } + + closedir(dirp); + return sum; +} + +static uint32_t getNixPackages(char* path) +{ + //Nix detection is kinda slow, so we only do it if the dir exists + if(!ffFileExists(path, S_IFDIR)) + return 0; + + FFstrbuf output; + ffStrbufInitA(&output, 128); + + //https://github.com/LinusDierheimer/fastfetch/issues/195#issuecomment-1191748222 + FFstrbuf command; + ffStrbufInitA(&command, 255); + ffStrbufAppendS(&command, "for x in $(nix-store --query --requisites "); + ffStrbufAppendS(&command, path); + ffStrbufAppendS(&command, "); do if [ -d $x ]; then echo $x ; fi ; done | cut -d- -f2- | egrep '([0-9]{1,}\\.)+[0-9]{1,}' | egrep -v '\\-doc$|\\-man$|\\-info$|\\-dev$|\\-bin$|^nixos-system-nixos-' | uniq"); + + ffProcessAppendStdOut(&output, (char* const[]) { + "sh", + "-c", + command.chars, + NULL + }); + + //Each package is a new line in the output. If at least one line is found, add 1 for the last line. + uint32_t result = ffStrbufCountC(&output, '\n'); + if(result > 0) + result++; + + ffStrbufDestroy(&output); + return result; +} + +static uint32_t getXBPS(FFstrbuf* baseDir) +{ + DIR* dir = opendir(baseDir->chars); + if(dir == NULL) + return 0; + + uint32_t result = 0; + + struct dirent *entry; + while((entry = readdir(dir)) != NULL) + { + if(entry->d_type != DT_REG || strncasecmp(entry->d_name, "pkgdb-", 6) != 0) + continue; + + ffStrbufAppendC(baseDir, '/'); + ffStrbufAppendS(baseDir, entry->d_name); + result = getNumStrings(baseDir->chars, "installed"); + break; + } + + closedir(dir); + return result; +} + +#endif // !__ANDROID__ + +#else // !__APPLE__ + +static uint32_t countBrewPackages(FFstrbuf* baseDir) +{ + uint32_t result = 0; + uint32_t baseDirLength = baseDir->length; + + ffStrbufAppendS(baseDir, "/Caskroom"); + result += getNumElements(baseDir->chars, DT_DIR); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + ffStrbufAppendS(baseDir, "/Cellar"); + result += getNumElements(baseDir->chars, DT_DIR); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + return result; +} + +static uint32_t getBrewPackages(FFstrbuf* baseDir) +{ + uint32_t result = 0; + uint32_t baseDirLength = baseDir->length; + + const char* prefix = getenv("HOMEBREW_PREFIX"); + bool prefixSet = ffStrSet(prefix); + + if(prefixSet) + { + ffStrbufAppendS(baseDir, prefix); + result += countBrewPackages(baseDir); + ffStrbufSubstrBefore(baseDir, baseDirLength); + } + + ffStrbufAppendS(baseDir, "/opt/homebrew"); + if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) + result += countBrewPackages(baseDir); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + ffStrbufAppendS(baseDir, "/usr/local"); + if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) + result += countBrewPackages(baseDir); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + return result; +} + +static uint32_t countMacPortsPackages(FFstrbuf* baseDir) +{ + uint32_t result = 0; + uint32_t baseDirLength = baseDir->length; + + ffStrbufAppendS(baseDir, "/var/macports/software"); + result += getNumElements(baseDir->chars, DT_DIR); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + return result; +} + +static uint32_t getMacPortsPackages(FFstrbuf* baseDir) +{ + uint32_t result = 0; + uint32_t baseDirLength = baseDir->length; + + const char* prefix = getenv("MACPORTS_PREFIX"); + bool prefixSet = ffStrSet(prefix); + + if(prefixSet) + { + ffStrbufAppendS(baseDir, prefix); + result += countMacPortsPackages(baseDir); + ffStrbufSubstrBefore(baseDir, baseDirLength); + } + + ffStrbufAppendS(baseDir, "/opt/local"); + if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) + result += countMacPortsPackages(baseDir); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + return result; +} + +#endif // __APPLE__ + +#ifdef FF_HAVE_RPM +#include "common/library.h" +#include +#include +#include +#include + +static uint32_t getRpmFromLibrpm(const FFinstance* instance) +{ + FF_LIBRARY_LOAD(rpm, &instance->config.librpm, 0, "librpm.so", 12) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbGetIteratorCount, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbFreeIterator, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsFree, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmlogSetMask, 0) + + // Don't print any error messages + ffrpmlogSetMask(RPMLOG_MASK(RPMLOG_EMERG)); + + if(ffrpmReadConfigFiles(NULL, NULL) != 0) + { + dlclose(rpm); + return 0; + } + + rpmts ts = ffrpmtsCreate(); + if(ts == NULL) + { + dlclose(rpm); + return 0; + } + + rpmdbMatchIterator mi = ffrpmtsInitIterator(ts, RPMDBI_LABEL, NULL, 0); + if(mi == NULL) + { + ffrpmtsFree(ts); + dlclose(rpm); + return 0; + } + + int count = ffrpmdbGetIteratorCount(mi); + + ffrpmdbFreeIterator(mi); + ffrpmtsFree(ts); + dlclose(rpm); + + return count > 0 ? (uint32_t) count : 0; +} + +#endif //FF_HAVE_RPM + +static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, FFPackageCounts* packageCounts) +{ + #if defined(__APPLE__) || defined(__ANDROID__) + FF_UNUSED(instance); + #endif + + #ifndef __APPLE__ //Linux desktop and Android + + uint32_t baseDirLength = baseDir->length; + + //pacman + ffStrbufAppendS(baseDir, "/var/lib/pacman/local"); + packageCounts->pacman += getNumElements(baseDir->chars, DT_DIR); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //dpkg + ffStrbufAppendS(baseDir, "/var/lib/dpkg/status"); + packageCounts->dpkg += getNumStrings(baseDir->chars, "Status: "); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + #ifndef __ANDROID__ //Linux Desktop + + //rpm + ffStrbufAppendS(baseDir, "/var/lib/rpm/rmpdb.sqlite"); + packageCounts->rpm += (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, "SELECT count(blob) FROM Packages"); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //emerge + ffStrbufAppendS(baseDir, "/var/db/pkg"); + packageCounts->emerge += countFilesRecursive(baseDir, "SIZE"); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //xps + ffStrbufAppendS(baseDir, "/var/db/xbps"); + packageCounts->xbps += getXBPS(baseDir); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //nix system + ffStrbufAppendS(baseDir, "/run/current-system"); + packageCounts->nixSystem += getNixPackages(baseDir->chars); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //nix default + ffStrbufAppendS(baseDir, "/nix/var/nix/profiles/default"); + packageCounts->nixDefault += getNixPackages(baseDir->chars); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //apk + ffStrbufAppendS(baseDir, "/lib/apk/db/installed"); + packageCounts->apk += getNumStrings(baseDir->chars, "C:Q"); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //flatpak + ffStrbufAppendS(baseDir, "/var/lib/flatpak/app"); + packageCounts->flatpak += getNumElements(baseDir->chars, DT_DIR); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //snap + ffStrbufAppendS(baseDir, "/snap"); + uint32_t snap = getNumElements(baseDir->chars, DT_DIR); + if(snap > 0) + packageCounts->snap += (snap - 1); //Accounting for the /snap/bin folder + ffStrbufSubstrBefore(baseDir, baseDirLength); + + //pacman branch + ffStrbufAppendS(baseDir, "/etc/pacman-mirrors.conf"); + if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0) + ffStrbufAppendS(&packageCounts->pacmanBranch, "stable"); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + #endif // !__ANDROID__ + + #else // !__APPLE__ + + //brew + packageCounts->brew += getBrewPackages(baseDir); + packageCounts->port += getMacPortsPackages(baseDir); + + #endif // __APPLE__ + + #ifdef __FreeBSD__ + + ffStrbufAppendS(baseDir, "/var/db/pkg/local.sqlite"); + packageCounts->pkg += (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, "SELECT count(id) FROM packages"); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + #endif // __FreeBSD__ +} + +static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDir, FFPackageCounts* packageCounts) +{ + uint32_t baseDirLength = baseDir->length; + + ffStrbufAppendS(baseDir, "/bedrock/strata"); + + DIR* dir = opendir(baseDir->chars); + if(dir == NULL) + { + ffStrbufSubstrBefore(baseDir, baseDirLength); + getPackageCounts(instance, baseDir, packageCounts); + return; + } + + ffStrbufAppendC(baseDir, '/'); + baseDirLength = baseDir->length; + + struct dirent* entry; + while((entry = readdir(dir)) != NULL) + { + if(entry->d_type != DT_DIR) + continue; + + ffStrbufAppendS(baseDir, entry->d_name); + getPackageCounts(instance, baseDir, packageCounts); + ffStrbufSubstrBefore(baseDir, baseDirLength); + } + + closedir(dir); +} + +void +#ifdef __MSYS__ +ffDetectPackagesPosix +#else +ffDetectPackages +#endif +(FFinstance* instance, FFPackageCounts* counts) +{ + FFstrbuf baseDir; + ffStrbufInitA(&baseDir, 512); + ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT); + + if(ffStrbufIgnCaseCompS(&ffDetectOS(instance)->id, "bedrock") == 0) + getPackageCountsBedrock(instance, &baseDir, counts); + else + getPackageCounts(instance, &baseDir, counts); + + // If SQL failed, we can still try with librpm. + // This is needed on openSUSE, which seems to use a proprietary database file + // This method doesn't work on bedrock, so we do it here. + #ifdef FF_HAVE_RPM + if(counts->rpm == 0) + counts->rpm = getRpmFromLibrpm(instance); + #endif + + #if !defined(__ANDROID__) && !defined(__APPLE__) + //nix user + ffStrbufSetS(&baseDir, instance->state.passwd->pw_dir); + ffStrbufAppendS(&baseDir, "/.nix-profile"); + counts->nixUser = getNixPackages(baseDir.chars); + #endif + + ffStrbufDestroy(&baseDir); +} diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c new file mode 100644 index 000000000..53d45d351 --- /dev/null +++ b/src/detection/packages/packages_windows.c @@ -0,0 +1,41 @@ +#include "packages.h" + +#include +#include + +static uint32_t getNumElements(const char* searchPath /* including `\*` suffix */, DWORD type) +{ + uint32_t counter = 0; + WIN32_FIND_DATAA wfd; + HANDLE hFind = FindFirstFileA(searchPath, &wfd); + + if (hFind != INVALID_HANDLE_VALUE) + { + do // Managed to locate and create an handle to that folder. + { + if(wfd.dwFileAttributes & type) + counter++; + } while (FindNextFileA(hFind, &wfd) == TRUE); + FindClose(hFind); + } + + return counter; +} + +#ifdef __MSYS__ + void ffDetectPackagesPosix(const FFinstance* instance, FFPackageCounts* counts); +#endif + +void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts) +{ + #ifdef __MSYS__ + //We have pacman and maybe others in MSYS, but not package managers for Windows + if(getenv("MSYSTEM")) + return ffDetectPackagesPosix(instance, counts); + #endif + + FFstrbuf scoopPath; + ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); + counts->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY) - 3; // . .. scoop + ffStrbufDestroy(&scoopPath); +} diff --git a/src/fastfetch.c b/src/fastfetch.c index 35ce52507..6b1553a4b 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -124,7 +124,7 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "packages-format") == 0) { - constructAndPrintCommandHelpFormat("packages", "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (xbps), {8} (nix-system), {9} (nix-user), {10} (nix-default), {11} (apk), {12} (pkg), {13} (flatpak), {14} (snap), {15} (brew), {16} (port)", 16, + constructAndPrintCommandHelpFormat("packages", "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (xbps), {8} (nix-system), {9} (nix-user), {10} (nix-default), {11} (apk), {12} (pkg), {13} (flatpak), {14} (snap), {15} (brew), {16} (port), {17} (scoop)", 17, "Number of all packages", "Number of pacman packages", "Pacman branch on manjaro", @@ -141,6 +141,7 @@ static inline void printCommandHelp(const char* command) "Number of snap packages", "Number of brew packages", "Number of macports packages" + "Number of scoop packages" ); } else if(strcasecmp(command, "shell-format") == 0) diff --git a/src/modules/packages.c b/src/modules/packages.c index 5ddba446a..cacfa5cc5 100644 --- a/src/modules/packages.c +++ b/src/modules/packages.c @@ -1,473 +1,18 @@ #include "fastfetch.h" -#include "common/io.h" -#include "common/properties.h" #include "common/printing.h" -#include "common/settings.h" -#include "common/processing.h" -#include "common/parsing.h" -#include "detection/os/os.h" - -#include -#include -#include -#include +#include "detection/packages/packages.h" #define FF_PACKAGES_MODULE_NAME "Packages" -#define FF_PACKAGES_NUM_FORMAT_ARGS 16 +#define FF_PACKAGES_NUM_FORMAT_ARGS 17 -typedef struct PackageCounts -{ - uint32_t pacman; - uint32_t dpkg; - uint32_t rpm; - uint32_t emerge; - uint32_t xbps; - uint32_t nixSystem; - uint32_t nixDefault; - uint32_t apk; - uint32_t pkg; - uint32_t flatpak; - uint32_t snap; - uint32_t brew; - uint32_t port; - - FFstrbuf pacmanBranch; -} PackageCounts; - -static uint32_t getNumElements(const char* dirname, unsigned char type) -{ - DIR* dirp = opendir(dirname); - if(dirp == NULL) - return 0; - - uint32_t num_elements = 0; - - struct dirent *entry; - while((entry = readdir(dirp)) != NULL) { - if(entry->d_type == type) - ++num_elements; - } - - if(type == DT_DIR) - num_elements -= 2; // accounting for . and .. - - closedir(dirp); - - return num_elements; -} - -#ifndef __APPLE__ - -static uint32_t getNumStrings(const char* filename, const char* needle) -{ - FILE* file = fopen(filename, "r"); - if(file == NULL) - return 0; - - uint32_t count = 0; - - char* line = NULL; - size_t len = 0; - - while(getline(&line, &len, file) != EOF) - { - if(strstr(line, needle) != NULL) - ++count; - } - - if(line != NULL) - free(line); - - fclose(file); - - return count; -} - -#ifndef __ANDROID__ - -static uint32_t countFilesRecursive(FFstrbuf* baseDirPath, const char* filename) -{ - uint32_t baseDirPathLength = baseDirPath->length; - - ffStrbufAppendC(baseDirPath, '/'); - ffStrbufAppendS(baseDirPath, filename); - bool exists = ffFileExists(baseDirPath->chars, S_IFREG); - ffStrbufSubstrBefore(baseDirPath, baseDirPathLength); - if(exists) - return 1; - - DIR* dirp = opendir(baseDirPath->chars); - if(dirp == NULL) - return 0; - - ffStrbufAppendC(baseDirPath, '/'); - baseDirPathLength = baseDirPath->length; - - uint32_t sum = 0; - - struct dirent *entry; - while((entry = readdir(dirp)) != NULL) { - // According to the PMS, neither category nor package name can begin with '.', so no need to check for . or .. specifically - if(entry->d_type != DT_DIR || entry->d_name[0] == '.') - continue; - - ffStrbufAppendS(baseDirPath, entry->d_name); - sum += countFilesRecursive(baseDirPath, filename); - ffStrbufSubstrBefore(baseDirPath, baseDirPathLength); - } - - closedir(dirp); - return sum; -} - -static uint32_t getNixPackages(char* path) -{ - //Nix detection is kinda slow, so we only do it if the dir exists - if(!ffFileExists(path, S_IFDIR)) - return 0; - - FFstrbuf output; - ffStrbufInitA(&output, 128); - - //https://github.com/LinusDierheimer/fastfetch/issues/195#issuecomment-1191748222 - FFstrbuf command; - ffStrbufInitA(&command, 255); - ffStrbufAppendS(&command, "for x in $(nix-store --query --requisites "); - ffStrbufAppendS(&command, path); - ffStrbufAppendS(&command, "); do if [ -d $x ]; then echo $x ; fi ; done | cut -d- -f2- | egrep '([0-9]{1,}\\.)+[0-9]{1,}' | egrep -v '\\-doc$|\\-man$|\\-info$|\\-dev$|\\-bin$|^nixos-system-nixos-' | uniq"); - - ffProcessAppendStdOut(&output, (char* const[]) { - "sh", - "-c", - command.chars, - NULL - }); - - //Each package is a new line in the output. If at least one line is found, add 1 for the last line. - uint32_t result = ffStrbufCountC(&output, '\n'); - if(result > 0) - result++; - - ffStrbufDestroy(&output); - return result; -} - -static uint32_t getXBPS(FFstrbuf* baseDir) -{ - DIR* dir = opendir(baseDir->chars); - if(dir == NULL) - return 0; - - uint32_t result = 0; - - struct dirent *entry; - while((entry = readdir(dir)) != NULL) - { - if(entry->d_type != DT_REG || strncasecmp(entry->d_name, "pkgdb-", 6) != 0) - continue; - - ffStrbufAppendC(baseDir, '/'); - ffStrbufAppendS(baseDir, entry->d_name); - result = getNumStrings(baseDir->chars, "installed"); - break; - } - - closedir(dir); - return result; -} - -#endif // !__ANDROID__ - -#else // !__APPLE__ - -static uint32_t countBrewPackages(FFstrbuf* baseDir) -{ - uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; - - ffStrbufAppendS(baseDir, "/Caskroom"); - result += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - ffStrbufAppendS(baseDir, "/Cellar"); - result += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - return result; -} - -static uint32_t getBrewPackages(FFstrbuf* baseDir) -{ - uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; - - const char* prefix = getenv("HOMEBREW_PREFIX"); - bool prefixSet = ffStrSet(prefix); - - if(prefixSet) - { - ffStrbufAppendS(baseDir, prefix); - result += countBrewPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - } - - ffStrbufAppendS(baseDir, "/opt/homebrew"); - if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) - result += countBrewPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - ffStrbufAppendS(baseDir, "/usr/local"); - if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) - result += countBrewPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - return result; -} - -static uint32_t countMacPortsPackages(FFstrbuf* baseDir) -{ - uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; - - ffStrbufAppendS(baseDir, "/var/macports/software"); - result += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - return result; -} - -static uint32_t getMacPortsPackages(FFstrbuf* baseDir) -{ - uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; - - const char* prefix = getenv("MACPORTS_PREFIX"); - bool prefixSet = ffStrSet(prefix); - - if(prefixSet) - { - ffStrbufAppendS(baseDir, prefix); - result += countMacPortsPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - } - - ffStrbufAppendS(baseDir, "/opt/local"); - if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) - result += countMacPortsPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - return result; -} - -#endif // __APPLE__ - -#ifdef FF_HAVE_RPM -#include "common/library.h" -#include -#include -#include -#include - -static uint32_t getRpmFromLibrpm(const FFinstance* instance) -{ - FF_LIBRARY_LOAD(rpm, &instance->config.librpm, 0, "librpm.so", 12) - FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0) - FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0) - FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0) - FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbGetIteratorCount, 0) - FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbFreeIterator, 0) - FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsFree, 0) - FF_LIBRARY_LOAD_SYMBOL(rpm, rpmlogSetMask, 0) - - // Don't print any error messages - ffrpmlogSetMask(RPMLOG_MASK(RPMLOG_EMERG)); - - if(ffrpmReadConfigFiles(NULL, NULL) != 0) - { - dlclose(rpm); - return 0; - } - - rpmts ts = ffrpmtsCreate(); - if(ts == NULL) - { - dlclose(rpm); - return 0; - } - - rpmdbMatchIterator mi = ffrpmtsInitIterator(ts, RPMDBI_LABEL, NULL, 0); - if(mi == NULL) - { - ffrpmtsFree(ts); - dlclose(rpm); - return 0; - } - - int count = ffrpmdbGetIteratorCount(mi); - - ffrpmdbFreeIterator(mi); - ffrpmtsFree(ts); - dlclose(rpm); - - return count > 0 ? (uint32_t) count : 0; -} - -#endif //FF_HAVE_RPM - -static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, PackageCounts* packageCounts) -{ - #if defined(__APPLE__) || defined(__ANDROID__) - FF_UNUSED(instance); - #endif - - #ifndef __APPLE__ //Linux desktop and Android - - uint32_t baseDirLength = baseDir->length; - - //pacman - ffStrbufAppendS(baseDir, "/var/lib/pacman/local"); - packageCounts->pacman += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //dpkg - ffStrbufAppendS(baseDir, "/var/lib/dpkg/status"); - packageCounts->dpkg += getNumStrings(baseDir->chars, "Status: "); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - #ifndef __ANDROID__ //Linux Desktop - - //rpm - ffStrbufAppendS(baseDir, "/var/lib/rpm/rmpdb.sqlite"); - packageCounts->rpm += (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, "SELECT count(blob) FROM Packages"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //emerge - ffStrbufAppendS(baseDir, "/var/db/pkg"); - packageCounts->emerge += countFilesRecursive(baseDir, "SIZE"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //xps - ffStrbufAppendS(baseDir, "/var/db/xbps"); - packageCounts->xbps += getXBPS(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //nix system - ffStrbufAppendS(baseDir, "/run/current-system"); - packageCounts->nixSystem += getNixPackages(baseDir->chars); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //nix default - ffStrbufAppendS(baseDir, "/nix/var/nix/profiles/default"); - packageCounts->nixDefault += getNixPackages(baseDir->chars); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //apk - ffStrbufAppendS(baseDir, "/lib/apk/db/installed"); - packageCounts->apk += getNumStrings(baseDir->chars, "C:Q"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //flatpak - ffStrbufAppendS(baseDir, "/var/lib/flatpak/app"); - packageCounts->flatpak += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //snap - ffStrbufAppendS(baseDir, "/snap"); - uint32_t snap = getNumElements(baseDir->chars, DT_DIR); - if(snap > 0) - packageCounts->snap += (snap - 1); //Accounting for the /snap/bin folder - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //pacman branch - ffStrbufAppendS(baseDir, "/etc/pacman-mirrors.conf"); - if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0) - ffStrbufAppendS(&packageCounts->pacmanBranch, "stable"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - #endif // !__ANDROID__ - - #else // !__APPLE__ - - //brew - packageCounts->brew += getBrewPackages(baseDir); - packageCounts->port += getMacPortsPackages(baseDir); - - #endif // __APPLE__ - - #ifdef __FreeBSD__ - - ffStrbufAppendS(baseDir, "/var/db/pkg/local.sqlite"); - packageCounts->pkg += (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, "SELECT count(id) FROM packages"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - #endif // __FreeBSD__ -} - -static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDir, PackageCounts* packageCounts) -{ - uint32_t baseDirLength = baseDir->length; - - ffStrbufAppendS(baseDir, "/bedrock/strata"); - - DIR* dir = opendir(baseDir->chars); - if(dir == NULL) - { - ffStrbufSubstrBefore(baseDir, baseDirLength); - getPackageCounts(instance, baseDir, packageCounts); - return; - } - - ffStrbufAppendC(baseDir, '/'); - baseDirLength = baseDir->length; - - struct dirent* entry; - while((entry = readdir(dir)) != NULL) - { - if(entry->d_type != DT_DIR) - continue; - - ffStrbufAppendS(baseDir, entry->d_name); - getPackageCounts(instance, baseDir, packageCounts); - ffStrbufSubstrBefore(baseDir, baseDirLength); - } - - closedir(dir); -} void ffPrintPackages(FFinstance* instance) { - PackageCounts counts = {0}; + FFPackageCounts counts = {0}; ffStrbufInit(&counts.pacmanBranch); + ffDetectPackages(instance, &counts); - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 512); - ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT); - - if(ffStrbufIgnCaseCompS(&ffDetectOS(instance)->id, "bedrock") == 0) - getPackageCountsBedrock(instance, &baseDir, &counts); - else - getPackageCounts(instance, &baseDir, &counts); - - // If SQL failed, we can still try with librpm. - // This is needed on openSUSE, which seems to use a proprietary database file - // This method doesn't work on bedrock, so we do it here. - #ifdef FF_HAVE_RPM - if(counts.rpm == 0) - counts.rpm = getRpmFromLibrpm(instance); - #endif - - #if !defined(__ANDROID__) && !defined(__APPLE__) - //nix user - ffStrbufSetS(&baseDir, instance->state.passwd->pw_dir); - ffStrbufAppendS(&baseDir, "/.nix-profile"); - uint32_t nixUser = getNixPackages(baseDir.chars); - #else - uint32_t nixUser = 0; - #endif - - ffStrbufDestroy(&baseDir); - - uint32_t all = counts.pacman + counts.dpkg + counts.rpm + counts.emerge + counts.xbps + counts.nixSystem + nixUser + counts.nixDefault + counts.apk + counts.pkg + counts.flatpak + counts.snap + counts.brew + counts.port; + uint32_t all = counts.pacman + counts.dpkg + counts.rpm + counts.emerge + counts.xbps + counts.nixSystem + counts.nixUser + counts.nixDefault + counts.apk + counts.pkg + counts.flatpak + counts.snap + counts.brew + counts.port + counts.scoop; if(all == 0) { ffPrintError(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages, "No packages from known package managers found"); @@ -507,10 +52,10 @@ void ffPrintPackages(FFinstance* instance) printf(", "); } - if(nixUser > 0) + if(counts.nixUser > 0) { - printf("%u (nix-user)", nixUser); - if((all = all - nixUser) > 0) + printf("%u (nix-user)", counts.nixUser); + if((all = all - counts.nixUser) > 0) printf(", "); } @@ -527,6 +72,7 @@ void ffPrintPackages(FFinstance* instance) FF_PRINT_PACKAGE(snap) FF_PRINT_PACKAGE(brew) FF_PRINT_PACKAGE(port) + FF_PRINT_PACKAGE(scoop) //Fix linter warning of unused value of all (void) all; @@ -546,14 +92,15 @@ void ffPrintPackages(FFinstance* instance) {FF_FORMAT_ARG_TYPE_UINT, &counts.emerge}, {FF_FORMAT_ARG_TYPE_UINT, &counts.xbps}, {FF_FORMAT_ARG_TYPE_UINT, &counts.nixSystem}, - {FF_FORMAT_ARG_TYPE_UINT, &nixUser}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.nixUser}, {FF_FORMAT_ARG_TYPE_UINT, &counts.nixDefault}, {FF_FORMAT_ARG_TYPE_UINT, &counts.apk}, {FF_FORMAT_ARG_TYPE_UINT, &counts.pkg}, {FF_FORMAT_ARG_TYPE_UINT, &counts.flatpak}, {FF_FORMAT_ARG_TYPE_UINT, &counts.snap}, {FF_FORMAT_ARG_TYPE_UINT, &counts.brew}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.port} + {FF_FORMAT_ARG_TYPE_UINT, &counts.port}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.scoop} }); } From 8387d8651ec8ac52f95fcc61e77bb134fd858f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 18:29:23 +0800 Subject: [PATCH 025/311] Kernel: add support for Windows --- CMakeLists.txt | 2 ++ src/detection/kernel/kernel.h | 18 +++++++++++++ src/detection/kernel/kernel_linux.c | 9 +++++++ src/detection/kernel/kernel_windows.cpp | 34 +++++++++++++++++++++++++ src/modules/kernel.c | 24 ++++++++++++++--- 5 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/detection/kernel/kernel.h create mode 100644 src/detection/kernel/kernel_linux.c create mode 100644 src/detection/kernel/kernel_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ee36893a1..88267a10b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,6 +269,7 @@ if(LINUX OR APPLE OR ANDROID OR BSD) src/detection/disk/disk.c src/detection/terminalShell/terminalShell_linux.c src/detection/packages/packages_linux.c + src/detection/kernel/kernel_linux.c ) endif() @@ -340,6 +341,7 @@ if(WIN_MSYS) src/detection/terminalShell/terminalShell_windows.cpp src/detection/packages/packages_linux.c src/detection/packages/packages_windows.c + src/detection/kernel/kernel_windows.cpp src/util/windows/wmi.cpp # Shared diff --git a/src/detection/kernel/kernel.h b/src/detection/kernel/kernel.h new file mode 100644 index 000000000..1b29350f3 --- /dev/null +++ b/src/detection/kernel/kernel.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_kernel_kernel +#define FF_INCLUDED_detection_kernel_kernel + +#include "fastfetch.h" + +typedef struct FFKernelResult +{ + FFstrbuf sysname; + FFstrbuf release; + FFstrbuf version; + FFstrbuf error; +} FFKernelResult; + +void ffDetectKernel(FFinstance* instance, FFKernelResult* result); + +#endif diff --git a/src/detection/kernel/kernel_linux.c b/src/detection/kernel/kernel_linux.c new file mode 100644 index 000000000..4ab70f027 --- /dev/null +++ b/src/detection/kernel/kernel_linux.c @@ -0,0 +1,9 @@ +#include "kernel.h" + +void ffDetectKernel(FFinstance* instance, FFKernelResult* result) +{ + ffStrbufInit(&result->error); + ffStrbufInitS(&result->sysname, instance->state.utsname.sysname); + ffStrbufInitS(&result->release, instance->state.utsname.release); + ffStrbufInitS(&result->version, instance->state.utsname.version); +} diff --git a/src/detection/kernel/kernel_windows.cpp b/src/detection/kernel/kernel_windows.cpp new file mode 100644 index 000000000..94a06d950 --- /dev/null +++ b/src/detection/kernel/kernel_windows.cpp @@ -0,0 +1,34 @@ +extern "C" { +#include "kernel.h" +} +#include "util/windows/wmi.hpp" + +extern "C" void ffDetectKernel(FFinstance* instance, FFKernelResult* kernel) +{ + FF_UNUSED(instance); + + ffStrbufInit(&kernel->error); + + ffStrbufInitS(&kernel->sysname, "Windows_NT"); + ffStrbufInit(&kernel->release); + ffStrbufInit(&kernel->version); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Version FROM Win32_OperatingSystem", &kernel->error); + if(!pEnumerator) + return; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + ffStrbufInitS(&kernel->error, "No WMI result returned"); + pEnumerator->Release(); + return; + } + + ffGetWmiObjString(pclsObj, L"Version", &kernel->release); + + pclsObj->Release(); + pEnumerator->Release(); +} diff --git a/src/modules/kernel.c b/src/modules/kernel.c index 062b04f42..02cece513 100644 --- a/src/modules/kernel.c +++ b/src/modules/kernel.c @@ -1,22 +1,38 @@ #include "fastfetch.h" #include "common/printing.h" +#include "detection/kernel/kernel.h" #define FF_KERNEL_MODULE_NAME "Kernel" #define FF_KERNEL_NUM_FORMAT_ARGS 3 void ffPrintKernel(FFinstance* instance) { + FFKernelResult result; + ffDetectKernel(instance, &result); + + if(result.error.length > 0) + { + ffPrintError(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, "%*s", result.error.length, result.error.chars); + goto exit; + } + if(instance->config.kernel.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel.key); - puts(instance->state.utsname.release); + ffStrbufPutTo(&result.release, stdout); } else { ffPrintFormat(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, - {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.release}, - {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.version} + {FF_FORMAT_ARG_TYPE_STRBUF, &result.sysname}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.release}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version} }); } + +exit: + ffStrbufDestroy(&result.error); + ffStrbufDestroy(&result.sysname); + ffStrbufDestroy(&result.release); + ffStrbufDestroy(&result.version); } From f7ba00746b7e6d736248aeeba38014d057231625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 18:35:56 +0800 Subject: [PATCH 026/311] Fix compiling on Linux --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88267a10b..90f071fca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -267,7 +267,7 @@ if(LINUX OR APPLE OR ANDROID OR BSD) src/detection/users/users_linux.c src/common/processing_linux.c src/detection/disk/disk.c - src/detection/terminalShell/terminalShell_linux.c + src/detection/terminalshell/terminalshell_linux.c src/detection/packages/packages_linux.c src/detection/kernel/kernel_linux.c ) @@ -337,8 +337,8 @@ if(WIN_MSYS) src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp src/detection/font/font_windows.cpp - src/detection/terminalShell/terminalShell_linux.c - src/detection/terminalShell/terminalShell_windows.cpp + src/detection/terminalshell/terminalshell_linux.c + src/detection/terminalshell/terminalshell_windows.cpp src/detection/packages/packages_linux.c src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp From 959371d1eabe4af18d405ffd03cc95ad375562a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 19:07:02 +0800 Subject: [PATCH 027/311] CpuUsage: Disable no wait detection by default because the result does need some time to generate --- src/detection/cpuUsage/cpuUsage.c | 22 +++++++++++----------- src/detection/cpuUsage/cpuUsage.h | 3 ++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuUsage/cpuUsage.c index 61aaaf817..7470236dc 100644 --- a/src/detection/cpuUsage/cpuUsage.c +++ b/src/detection/cpuUsage/cpuUsage.c @@ -1,7 +1,17 @@ #include "fastfetch.h" #include "cpuUsage.h" -#ifndef FF_DETECTION_CPUUSAGE_NOWAIT +#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" @@ -45,14 +55,4 @@ const char* ffGetCpuUsageResult(double* result) return NULL; } -#else //FF_DETECTION_CPUUSAGE_NOWAIT - -const char* ffGetCpuUsageResultNoWait(double* result); - -void ffPrepareCPUUsage() {} - -const char* ffGetCpuUsageResult(double* result) { - return ffGetCpuUsageResultNoWait(result); -} - #endif //FF_DETECTION_CPUUSAGE_NOWAIT diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index 0c76275c0..4ac03c222 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -4,7 +4,8 @@ #define FF_INCLUDED_detection_cpu_cpuUsage #if defined(_WIN32) || defined(__MSYS__) - #define FF_DETECTION_CPUUSAGE_NOWAIT 1 + // Disabled by default because the result does need some time to generate + #define FF_DETECTION_CPUUSAGE_NOWAIT 0 #endif const char* ffGetCpuUsageResult(double* result); From 511405172598246d96ff6add0876769da6df780c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 22:16:45 +0800 Subject: [PATCH 028/311] TerminalShell: fix nested shells detection, add more error checks --- .../terminalshell/terminalshell_linux.c | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 2897a7c8e..5d9a392f6 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -13,6 +13,7 @@ static void setExeName(FFstrbuf* exe, const char** exeName) { + assert(exe->length > 0); uint32_t lastSlashIndex = ffStrbufLastIndexC(exe, '/'); if(lastSlashIndex < exe->length) *exeName = exe->chars + lastSlashIndex + 1; @@ -20,15 +21,20 @@ static void setExeName(FFstrbuf* exe, const char** exeName) static void getProcessInformation(const char* pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName) { + assert(processName->length > 0); + FFstrbuf cmdlineFilePath; ffStrbufInit(&cmdlineFilePath); ffStrbufAppendS(&cmdlineFilePath, "/proc/"); ffStrbufAppendS(&cmdlineFilePath, pid); ffStrbufAppendS(&cmdlineFilePath, "/cmdline"); - ffReadFileBuffer(cmdlineFilePath.chars, exe); - ffStrbufSubstrBeforeFirstC(exe, '\0'); //Trim the arguments - ffStrbufTrimLeft(exe, '-'); //Happens in TTY + ffStrbufClear(exe); + if(ffAppendFileBuffer(cmdlineFilePath.chars, exe)) + { + ffStrbufSubstrBeforeFirstC(exe, '\0'); //Trim the arguments + ffStrbufTrimLeft(exe, '-'); //Happens in TTY + } if(exe->length == 0) ffStrbufSet(exe, processName); @@ -97,14 +103,14 @@ static void getTerminalShell(FFTerminalShellResult* result, const char* pid) strcasecmp(name, "pwsh") == 0 || strcasecmp(name, "git-shell") == 0 ) { - ffStrbufAppendS(&result->shellProcessName, name); + ffStrbufSetS(&result->shellProcessName, name); // prevent from `fishbash` getProcessInformation(pid, &result->shellProcessName, &result->shellExe, &result->shellExeName); getTerminalShell(result, ppid); return; } - ffStrbufAppendS(&result->terminalProcessName, name); + ffStrbufSetS(&result->terminalProcessName, name); getProcessInformation(pid, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName); } @@ -172,14 +178,19 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) if(!ffStrSet(term) || strcasecmp(term, "linux") == 0) term = ttyname(STDIN_FILENO); - ffStrbufSetS(&result->terminalProcessName, term); - ffStrbufSetS(&result->terminalExe, term); - setExeName(&result->terminalExe, &result->terminalExeName); + if(ffStrSet(term)) + { + ffStrbufSetS(&result->terminalProcessName, term); + ffStrbufSetS(&result->terminalExe, term); + setExeName(&result->terminalExe, &result->terminalExeName); + } } static void getUserShellFromEnv(FFTerminalShellResult* result) { ffStrbufAppendS(&result->userShellExe, getenv("SHELL")); + if(result->userShellExe.length == 0) + return; setExeName(&result->userShellExe, &result->userShellExeName); //If shell detection via processes failed @@ -253,6 +264,7 @@ static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) { + ffStrbufClear(version); if(strcasecmp(exeName, "bash") == 0) getShellVersionBash(exe, version); else if(strcasecmp(exeName, "zsh") == 0) From 2c512523960c401a49e1ecc5227db9bc13e69b16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 22:48:13 +0800 Subject: [PATCH 029/311] LocalIP: add support for Windows --- CMakeLists.txt | 3 + src/detection/localip/localip.h | 17 ++++ src/detection/localip/localip_linux.c | 66 +++++++++++++ src/detection/localip/localip_windows.c | 89 +++++++++++++++++ src/modules/localip.c | 124 ++++++++++-------------- 5 files changed, 225 insertions(+), 74 deletions(-) create mode 100644 src/detection/localip/localip.h create mode 100644 src/detection/localip/localip_linux.c create mode 100644 src/detection/localip/localip_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 90f071fca..96712e4c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,6 +270,7 @@ if(LINUX OR APPLE OR ANDROID OR BSD) src/detection/terminalshell/terminalshell_linux.c src/detection/packages/packages_linux.c src/detection/kernel/kernel_linux.c + src/detection/localip/localip_linux.c ) endif() @@ -342,6 +343,7 @@ if(WIN_MSYS) src/detection/packages/packages_linux.c src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp + src/detection/localip/localip_windows.c src/util/windows/wmi.cpp # Shared @@ -483,6 +485,7 @@ elseif(WIN_MSYS) PRIVATE "-ldwmapi" PRIVATE "-lopengl32" PRIVATE "-lgdi32" + PRIVATE "-liphlpapi" ) endif() diff --git a/src/detection/localip/localip.h b/src/detection/localip/localip.h new file mode 100644 index 000000000..ef16da50f --- /dev/null +++ b/src/detection/localip/localip.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_localip_localip +#define FF_INCLUDED_detection_localip_localip + +#include "fastfetch.h" + +typedef struct FFLocalIpResult +{ + FFstrbuf name; + FFstrbuf addr; + bool ipv6; +} FFLocalIpResult; + +const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results); + +#endif diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c new file mode 100644 index 000000000..b38958b19 --- /dev/null +++ b/src/detection/localip/localip_linux.c @@ -0,0 +1,66 @@ +#include "localip.h" + +#include +#include +#include +#include +#include +#include + +#ifdef __FreeBSD__ + #include // FreeBSD needs this for AF_INET +#endif + +static void addNewIp(FFlist* list, const char* name, const char* addr, bool ipv6) +{ + FFLocalIpResult* ip = (FFLocalIpResult*) ffListAdd(list); + ffStrbufInitS(&ip->name, name); + ffStrbufInitS(&ip->addr, addr); + ip->ipv6 = ipv6; +} + +const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) +{ + struct ifaddrs* ifAddrStruct = NULL; + if(getifaddrs(&ifAddrStruct) < 0) + return "getifaddrs(&ifAddrStruct) failed"; + + for (struct ifaddrs* ifa = ifAddrStruct; ifa; ifa = ifa->ifa_next) + { + if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING)) + continue; + + // loop back + if (strncmp(ifa->ifa_name, "lo", 2) == 0 && (ifa->ifa_name[2] == '\0' || isdigit(ifa->ifa_name[2])) && !instance->config.localIpShowLoop) + continue; + + if (instance->config.localIpNamePrefix.length && strncmp(ifa->ifa_name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0) + continue; + + if (ifa->ifa_addr->sa_family == AF_INET) + { + // IPv4 + if (!instance->config.localIpShowIpV4) + continue; + + struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr; + char addressBuffer[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN); + addNewIp(results, ifa->ifa_name, addressBuffer, false); + } + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + // IPv6 + if (!instance->config.localIpShowIpV6) + continue; + + struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr; + char addressBuffer[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN); + addNewIp(results, ifa->ifa_name, addressBuffer, true); + } + } + + if (ifAddrStruct) freeifaddrs(ifAddrStruct); + return NULL; +} diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c new file mode 100644 index 000000000..881dd2d6e --- /dev/null +++ b/src/detection/localip/localip_windows.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +#include "localip.h" + +static void addNewIp(FFlist* list, const wchar_t* name, const char* addr, bool ipv6) +{ + FFLocalIpResult* ip = (FFLocalIpResult*) ffListAdd(list); + + int len = (int)wcslen(name); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, name, len, NULL, 0, NULL, NULL); + ffStrbufInitA(&ip->name, (uint32_t)size_needed + 1); + WideCharToMultiByte(CP_UTF8, 0, name, len, ip->name.chars, size_needed, NULL, NULL); + ip->name.length = (uint32_t)size_needed; + ip->name.chars[size_needed] = '\0'; + + ffStrbufInitS(&ip->addr, addr); + ip->ipv6 = ipv6; +} + +const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) +{ + IP_ADAPTER_ADDRESSES* adapter_addresses = NULL; + + // Start with a 16 KB buffer and resize if needed - + // multiple attempts in case interfaces change while + // we are in the middle of querying them. + DWORD adapter_addresses_buffer_size = 16 * 1024; + for (int attempts = 0; attempts != 3; ++attempts) + { + adapter_addresses = (IP_ADAPTER_ADDRESSES*)realloc(adapter_addresses, adapter_addresses_buffer_size); + assert(adapter_addresses); + + DWORD error = GetAdaptersAddresses( + AF_UNSPEC, + GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | + GAA_FLAG_SKIP_FRIENDLY_NAME, + NULL, + adapter_addresses, + &adapter_addresses_buffer_size); + + if (error == ERROR_SUCCESS) + break; + else if (ERROR_BUFFER_OVERFLOW == error) + continue; + else + return "GetAdaptersAddresses() failed"; + } + + // Iterate through all of the adapters + for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next) + { + if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK && !instance->config.localIpShowLoop) + continue; + + for (IP_ADAPTER_UNICAST_ADDRESS* ifa = adapter->FirstUnicastAddress; ifa; ifa = ifa->Next) + { + if (ifa->Address.lpSockaddr->sa_family == AF_INET) + { + // IPv4 + if (!instance->config.localIpShowIpV4) + continue; + + SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr; + char addressBuffer[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN); + addNewIp(results, adapter->FriendlyName, addressBuffer, false); + } + else if (ifa->Address.lpSockaddr->sa_family == AF_INET6) + { + // IPv6 + if (!instance->config.localIpShowIpV6) + continue; + + SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr; + char addressBuffer[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN); + addNewIp(results, adapter->FriendlyName, addressBuffer, false); + } + } + } + + free(adapter_addresses); + return NULL; +} diff --git a/src/modules/localip.c b/src/modules/localip.c index 9308d246a..07508f3bd 100644 --- a/src/modules/localip.c +++ b/src/modules/localip.c @@ -1,90 +1,66 @@ #include "fastfetch.h" #include "common/printing.h" +#include "detection/localip/localip.h" #define FF_LOCALIP_MODULE_NAME "Local IP" -#define FF_LOCALIP_NUM_FORMAT_ARGS 1 - -#include -#include -#include -#include -#include - -#ifdef __FreeBSD__ - #include // FreeBSD needs this for AF_INET -#endif - -static void printValue(FFinstance* instance, const char* ifaName, const char* addressBuffer) -{ - FFstrbuf key; - ffStrbufInit(&key); - - if (instance->config.localIP.key.length == 0) - { - ffStrbufAppendF(&key, FF_LOCALIP_MODULE_NAME " (%s)", ifaName); - } - else - { - ffParseFormatString(&key, &instance->config.localIP.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, ifaName} - }); - } - - if (instance->config.localIP.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - puts(addressBuffer); - } - else - { - ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.localIP.outputFormat, FF_LOCALIP_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, addressBuffer} - }); - } - - ffStrbufDestroy(&key); -} +#define FF_LOCALIP_NUM_FORMAT_ARGS 2 void ffPrintLocalIp(FFinstance* instance) { - struct ifaddrs* ifAddrStruct = NULL; - int ret = getifaddrs(&ifAddrStruct); - if (ret < 0) { - ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP, "getifaddrs(&ifAddrStruct) < 0 (%i)", ret); - return; + FFlist results; + ffListInit(&results, sizeof(FFLocalIpResult)); + + const char* error = ffDetectLocalIps(instance, &results); + + if(error) + { + ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP, "%s", error); + goto exit; } - for (struct ifaddrs* ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; + if(results.length == 0) + { + ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP, "Failed to detect any IPs"); + goto exit; + } - // loop back - if (strncmp(ifa->ifa_name, "lo", 2) == 0 && (ifa->ifa_name[2] == '\0' || isdigit(ifa->ifa_name[2])) && !instance->config.localIpShowLoop) - continue; + FFstrbuf key; + ffStrbufInit(&key); - if (instance->config.localIpNamePrefix.length && strncmp(ifa->ifa_name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0) - continue; + for(uint32_t i = 0; i < results.length; ++i) + { + FFLocalIpResult* ip = (FFLocalIpResult*) ffListGet(&results, i); - if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4 - // is a valid IP4 Address - if (!instance->config.localIpShowIpV4) - continue; - - void* tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; - char addressBuffer[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); - printValue(instance, ifa->ifa_name, addressBuffer); - } else if (ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6 - // is a valid IP6 Address - if (!instance->config.localIpShowIpV6) - continue; - - void* tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; - char addressBuffer[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN); - printValue(instance, ifa->ifa_name, addressBuffer); + if(instance->config.localIP.key.length == 0) + { + ffStrbufSetF(&key, FF_LOCALIP_MODULE_NAME " (%*s)", ip->name.length, ip->name.chars); } + else + { + ffParseFormatString(&key, &instance->config.localIP.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name} + }); + } + + if(instance->config.localIP.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, key.chars, 0, NULL); + ffStrbufPutTo(&ip->addr, stdout); + } + else + { + ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.localIP.outputFormat, FF_LOCALIP_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->addr}, + {FF_FORMAT_ARG_TYPE_STRING, ip->ipv6 ? "IPv6" : "IPv4"} + }); + } + + ffStrbufDestroy(&ip->name); + ffStrbufDestroy(&ip->addr); } - if (ifAddrStruct) freeifaddrs(ifAddrStruct); + ffStrbufDestroy(&key); + +exit: + ffListDestroy(&results); } From 7080449a8c521276f5f84596278e59927fca1db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 23:40:57 +0800 Subject: [PATCH 030/311] DE: add support for Windows --- src/detection/displayserver/displayserver_windows.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index a990e2e82..354961094 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -1,4 +1,5 @@ #include "displayserver.h" +#include "detection/os/os.h" #include #include @@ -35,4 +36,13 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffdsAppendResolution(ds, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmDisplayFrequency); } + + //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067 + const FFOSResult* os = ffDetectOS(instance); + if(ffStrbufCompS(&os->version, "11") == 0 || ffStrbufCompS(&os->version, "10") == 0) + ffStrbufSetS(&ds->dePrettyName, "Fluent"); + else if(ffStrbufCompS(&os->version, "8") == 0 || ffStrbufStartsWithS(&os->version, "8.")) + ffStrbufSetS(&ds->dePrettyName, "Metro"); + else + ffStrbufSetS(&ds->dePrettyName, "Aero"); } From da797ecb338bbfb6c87e2b38aa75874322a6f023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Oct 2022 23:42:43 +0800 Subject: [PATCH 031/311] Cursor / Icons / Theme / GTK / Qt: don't compile on Windows / macOS / Android --- CMakeLists.txt | 4 ++-- src/modules/cursor.c | 4 ++-- src/modules/icons.c | 2 +- src/modules/theme.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96712e4c8..27d787e92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,8 +201,6 @@ set(LIBFASTFETCH_SRC src/logo/image/image.c src/logo/image/im7.c src/logo/image/im6.c - src/detection/qt.c - src/detection/gtk.c src/detection/vulkan.c src/detection/datetime.c src/detection/title.c @@ -315,6 +313,8 @@ if(LINUX OR BSD) src/detection/media/media_linux.c src/detection/wmtheme/wmtheme_linux.c src/detection/font/font_linux.c + src/detection/qt.c + src/detection/gtk.c ) endif() diff --git a/src/modules/cursor.c b/src/modules/cursor.c index c0f572823..e6d50d333 100644 --- a/src/modules/cursor.c +++ b/src/modules/cursor.c @@ -11,7 +11,7 @@ #define FF_CURSOR_MODULE_NAME "Cursor" #define FF_CURSOR_NUM_FORMAT_ARGS 2 -#if !(defined(__ANDROID__) || defined(__APPLE__)) +#if !(defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__)) static void printCursor(FFinstance* instance, FFstrbuf* cursorTheme, const FFstrbuf* cursorSize) { @@ -196,7 +196,7 @@ static bool printCursorFromEnv(FFinstance* instance) void ffPrintCursor(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) FF_UNUSED(instance); ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Cursor detection is not supported"); diff --git a/src/modules/icons.c b/src/modules/icons.c index 38d0823fb..c489b9a86 100644 --- a/src/modules/icons.c +++ b/src/modules/icons.c @@ -10,7 +10,7 @@ void ffPrintIcons(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) FF_UNUSED(instance); ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons, "Icons detection is not supported"); diff --git a/src/modules/theme.c b/src/modules/theme.c index 612bb6b96..5d294c196 100644 --- a/src/modules/theme.c +++ b/src/modules/theme.c @@ -10,7 +10,7 @@ void ffPrintTheme(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) FF_UNUSED(instance); ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme, "Theme detection is not supported"); From 510d57e7dd8a65baff4b60157e4dbe9239f3c718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 00:50:46 +0800 Subject: [PATCH 032/311] Fix huge compiler warnings when compiling C++ code C++ requires a white space between two string literals --- src/data/config_user.txt | 4 ++-- src/fastfetch_config.h.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 26b90679f..1e68fe85b 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -5,7 +5,7 @@ # Whitespaces are trimmed at the beginning and the end. # Empty lines or lines starting with # are ignored. -# This file was shipped with $"FASTFETCH_PROJECT_VERSION$". +# This file was shipped with $" FASTFETCH_PROJECT_VERSION $". # Use fastfetch --print-config-user > ~/.config/fastfetch/config.conf to overwrite this file with the current defaults # Below some often usefull options are listed. Uncomment and modify them so they take affect. @@ -25,7 +25,7 @@ # Must be a list of module names, separated by colons. # List available modules with "fastfetch --list-modules". # Get the default structure with "fastfetch --print-structure". -#--structure $"FASTFETCH_DATATEXT_STRUCTURE$" +#--structure $" FASTFETCH_DATATEXT_STRUCTURE $" # Multithreading option: # Sets if fastfetch should use multiple threads to detect the values. diff --git a/src/fastfetch_config.h.in b/src/fastfetch_config.h.in index 982a5a313..8a79969eb 100644 --- a/src/fastfetch_config.h.in +++ b/src/fastfetch_config.h.in @@ -14,7 +14,7 @@ #define FASTFETCH_TARGET_DIR_ETC "@TARGET_DIR_ETC@" #define FASTFETCH_DATATEXT_STRUCTURE "@DATATEXT_STRUCTURE@" -#define FASTFETCH_DATATEXT_CONFIG_SYSTEM "@DATATEXT_CONFIG_SYSTEM@" //Requires FASTFETCH_PROJECT_VERSION to be set +#define FASTFETCH_DATATEXT_CONFIG_SYSTEM "@DATATEXT_CONFIG_SYSTEM@" #define FASTFETCH_DATATEXT_CONFIG_USER "@DATATEXT_CONFIG_USER@" //Requires FASTFETCH_PROJECT_VERSION and FASTFETCH_DATATEXT_STRUCTURE to be set #define FASTFETCH_DATATEXT_MODULES "@DATATEXT_MODULES@" #define FASTFETCH_DATATEXT_HELP "@DATATEXT_HELP@" From 7c98450acc05e5ad1697dbb47a810dc7ea28e187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 02:04:41 +0800 Subject: [PATCH 033/311] OpenCL / Vulkan: enable support for Windows --- CMakeLists.txt | 4 ++-- src/common/library.c | 11 +++++++++++ src/common/library.h | 4 +++- src/detection/terminalfont/terminalfont_linux.c | 2 +- src/detection/vulkan.c | 2 +- src/modules/opencl.c | 2 +- 6 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27d787e92..f438ed07d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ project(fastfetch if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel -elseif("${CMAKE_SYSTEM_NAME}" MATCHES "MSYS") +elseif("${CMAKE_SYSTEM_NAME}" MATCHES "MSYS|Windows") set(WIN_MSYS TRUE CACHE BOOL "..." FORCE) # Windows on msys2 elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) @@ -47,7 +47,7 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD" OFF) +cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN_MSYS" OFF) cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN_MSYS" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) diff --git a/src/common/library.c b/src/common/library.c index 441b9f611..c131a3862 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -19,6 +19,14 @@ static void* libraryLoad(const char* path, int maxVersion) { void* result = dlopen(path, FF_DLOPEN_FLAGS); + + #if defined(_WIN32) || defined(__MSYS__) + + // libX.dll.1 never exists on Windows, while libX-1.dll may exist + FF_UNUSED(maxVersion) + + #else + if(result != NULL || maxVersion < 0) return result; @@ -40,6 +48,9 @@ static void* libraryLoad(const char* path, int maxVersion) } ffStrbufDestroy(&pathbuf); + + #endif + return result; } diff --git a/src/common/library.h b/src/common/library.h index 25a323119..885cd32dc 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -5,7 +5,9 @@ #include -#ifdef __APPLE__ +#if defined(_WIN32) || defined(__MSYS__) + #define FF_LIBRARY_EXTENSION ".dll" +#elif defined(__APPLE__) #define FF_LIBRARY_EXTENSION ".dylib" #else #define FF_LIBRARY_EXTENSION ".so" diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 74392b55e..f7f4de454 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -189,7 +189,7 @@ static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* conten { CJSONData cjsonData; - FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson failed", "libcjson"FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson"FF_LIBRARY_EXTENSION" failed", "libcjson"FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Parse) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsObject) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive) diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index a04ab11d2..1ff96e2c9 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -35,7 +35,7 @@ static void applyDriverName(VkPhysicalDeviceDriverProperties* properties, FFstrb static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* result) { - FF_LIBRARY_LOAD(vulkan, &instance->config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed", "libvulkan"FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD(vulkan, &instance->config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed", "libvulkan"FF_LIBRARY_EXTENSION, 2, "vulkan-1"FF_LIBRARY_EXTENSION, -1) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(vulkan, vkGetInstanceProcAddr) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(vulkan, vkCreateInstance) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(vulkan, vkDestroyInstance) diff --git a/src/modules/opencl.c b/src/modules/opencl.c index 7f2ce1acb..debfcd45e 100644 --- a/src/modules/opencl.c +++ b/src/modules/opencl.c @@ -83,7 +83,7 @@ static const char* printOpenCL(FFinstance* instance) { OpenCLData data; - FF_LIBRARY_LOAD(opencl, &instance->config.libOpenCL, "dlopen libOpenCL.so failed", "libOpenCL.so", 1); + FF_LIBRARY_LOAD(opencl, &instance->config.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed", "libOpenCL"FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetPlatformIDs); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceIDs); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceInfo); From 034f444fca184443bc41274263bcc1b85ce98130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 16:51:53 +0800 Subject: [PATCH 034/311] Terminal / Shell: fix name printing --- src/detection/terminalshell/terminalshell.h | 2 ++ .../terminalshell/terminalshell_linux.c | 8 +++++ .../terminalshell/terminalshell_windows.cpp | 29 ++++++++++++------- src/modules/shell.c | 2 +- src/modules/terminal.c | 2 +- 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/detection/terminalshell/terminalshell.h b/src/detection/terminalshell/terminalshell.h index 2791856ac..8783e3410 100644 --- a/src/detection/terminalshell/terminalshell.h +++ b/src/detection/terminalshell/terminalshell.h @@ -10,10 +10,12 @@ typedef struct FFTerminalShellResult FFstrbuf shellProcessName; FFstrbuf shellExe; const char* shellExeName; //pointer to a char in shellExe + FFstrbuf shellPrettyName; FFstrbuf shellVersion; FFstrbuf terminalProcessName; FFstrbuf terminalExe; + FFstrbuf terminalPrettyName; const char* terminalExeName; //pointer to a char in terminalExe FFstrbuf userShellExe; diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 5d9a392f6..3adca984f 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -322,6 +322,14 @@ const FFTerminalShellResult* else ffStrbufSet(&result.userShellVersion, &result.shellVersion); + // https://github.com/LinusDierheimer/fastfetch/discussions/280#discussioncomment-3831734 + ffStrbufInitS(&result.shellPrettyName, result.shellExeName); + + 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 + ffStrbufInitCopy(&result.terminalPrettyName, &result.terminalProcessName); + pthread_mutex_unlock(&mutex); return &result; } diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 9ef0d9c6b..d4deea9b3 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -66,15 +66,16 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) return 0; result->shellExeName = result->shellExe.chars + ffStrbufLastIndexC(&result->shellExe, '\\') + 1; - if(ffStrbufEndsWithIgnCaseS(&result->shellProcessName, ".exe")) - ffStrbufSubstrBefore(&result->shellProcessName, result->shellProcessName.length - 4); + ffStrbufSet(&result->shellPrettyName, &result->shellProcessName); + if(ffStrbufEndsWithIgnCaseS(&result->shellPrettyName, ".exe")) + ffStrbufSubstrBefore(&result->shellPrettyName, result->shellPrettyName.length - 4); - if(ffStrbufIgnCaseCompS(&result->shellProcessName, "pwsh") == 0) + if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "pwsh") == 0) { - ffStrbufSetS(&result->shellProcessName, "PowerShell"); + ffStrbufSetS(&result->shellPrettyName, "PowerShell"); getShellVersion(&result->shellExe, &result->shellVersion); } - else if(ffStrbufIgnCaseCompS(&result->shellProcessName, "powershell") == 0) + else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell") == 0) ffStrbufSetS(&result->shellProcessName, "Windows PowerShell"); return ppid; @@ -88,13 +89,14 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) return 0; result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\'); - if(ffStrbufEndsWithIgnCaseS(&result->terminalProcessName, ".exe")) + ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName); + if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe")) result->terminalProcessName.length -= 4; - if(ffStrbufIgnCaseCompS(&result->terminalProcessName, "WindowsTerminal")) - ffStrbufSetS(&result->terminalProcessName, "Windows Terminal"); - else if(ffStrbufIgnCaseCompS(&result->terminalProcessName, "conhost")) - ffStrbufSetS(&result->terminalProcessName, "Console Window Host"); + if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "WindowsTerminal")) + ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal"); + else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost")) + ffStrbufSetS(&result->terminalPrettyName, "Console Window Host"); return ppid; } @@ -108,7 +110,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { #ifdef __MSYS__ // This is hacky. - // When running inside MSYS2, the real Windows parent process doesn't exist and we must find it in Linux way ( /proc/self/xxx ) + // When running inside of MSYS2, the real Windows parent process doesn't exist and we must find it in Linux way ( /proc/self/xxx ) // When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way if(getenv("MSYSTEM")) return ffDetectTerminalShellPosix(instance); @@ -123,11 +125,13 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) ffStrbufInit(&result.shellProcessName); ffStrbufInitA(&result.shellExe, 128); result.shellExeName = result.shellExe.chars; + ffStrbufInit(&result.shellPrettyName); ffStrbufInit(&result.shellVersion); ffStrbufInit(&result.terminalProcessName); ffStrbufInitA(&result.terminalExe, 128); result.terminalExeName = result.terminalExe.chars; + ffStrbufInit(&result.terminalPrettyName); ffStrbufInit(&result.userShellExe); result.userShellExeName = result.userShellExe.chars; @@ -141,6 +145,9 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) if(ppid == 0) return &result; + // TODO: handle nested shells + // TODO: handle running without shells ( dblclick exe in Windows Explorer ) + ppid = getTerminalInfo(&result, ppid); if(ppid == 0) return &result; diff --git a/src/modules/shell.c b/src/modules/shell.c index b9486bc2c..607f5ec69 100644 --- a/src/modules/shell.c +++ b/src/modules/shell.c @@ -18,7 +18,7 @@ void ffPrintShell(FFinstance* instance) if(instance->config.shell.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell.key); - ffStrbufWriteTo(&result->shellProcessName, stdout); + ffStrbufWriteTo(&result->shellPrettyName, stdout); if(result->shellVersion.length > 0) { diff --git a/src/modules/terminal.c b/src/modules/terminal.c index c89afbb78..469ece23b 100644 --- a/src/modules/terminal.c +++ b/src/modules/terminal.c @@ -20,7 +20,7 @@ void ffPrintTerminal(FFinstance* instance) if(instance->config.terminal.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal.key); - ffStrbufPutTo(&result->terminalProcessName, stdout); + ffStrbufPutTo(&result->terminalPrettyName, stdout); } else { From 6e190c6f7c79dd664296cd73826c61abaffec11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 17:47:30 +0800 Subject: [PATCH 035/311] Fix some mistakes --- src/detection/font/font.h | 2 +- src/detection/terminalfont/terminalfont_linux.c | 3 ++- src/detection/terminalshell/terminalshell_windows.cpp | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/detection/font/font.h b/src/detection/font/font.h index e28446e66..63d19e2ee 100644 --- a/src/detection/font/font.h +++ b/src/detection/font/font.h @@ -14,7 +14,7 @@ typedef struct FFFontResult /** * Linux / BSD: QT, GTK2, GTK3, GTK4 * MacOS: System, User, Monospace, Application - * Windows: Desktop, User, Unset, Unset + * Windows: Desktop, Unset, Unset, Unset * Other: Unset, Unset, Unset, Unset */ FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS]; diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index f7f4de454..ee381744e 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -352,7 +352,8 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "gnome-terminal-") == 0) detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", terminalFont); - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0) + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || + ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) detectFromWindowsTeriminal(instance, terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0) detectMintty(instance, terminalFont); diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index d4deea9b3..bdb604a95 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -91,11 +91,11 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName); if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe")) - result->terminalProcessName.length -= 4; + ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4); - if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "WindowsTerminal")) + if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "WindowsTerminal") == 0) ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal"); - else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost")) + else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost") == 0) ffStrbufSetS(&result->terminalPrettyName, "Console Window Host"); return ppid; From 00f5b84660449e8361249bcea8a1daceba5c804f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 19:47:13 +0800 Subject: [PATCH 036/311] Disk: improve performance; support `--disk-folders` option --- CMakeLists.txt | 2 +- src/data/help.txt | 2 +- src/detection/disk/disk_windows.c | 66 +++++++++++++++++++++++++++++ src/detection/disk/disk_windows.cpp | 55 ------------------------ 4 files changed, 68 insertions(+), 57 deletions(-) create mode 100644 src/detection/disk/disk_windows.c delete mode 100644 src/detection/disk/disk_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c23855bf5..de7d36a6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,7 +342,7 @@ if(WIN_MSYS) src/detection/users/users_windows.cpp src/detection/os/os_windows.cpp src/detection/processes/processes_windows.cpp - src/detection/disk/disk_windows.cpp + src/detection/disk/disk_windows.c src/detection/cpuUsage/cpuUsage_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp diff --git a/src/data/help.txt b/src/data/help.txt index f24242ec4..181f24671 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -90,7 +90,7 @@ Module specific options: --title-fqdn : Sets if the title should use fully qualified domain name. Default is false. --separator-string : Set the string printed by the separator module --os-file : Set the path to the file containing OS informations - --disk-folders : A colon separated list of folder paths for the disk output. Default is "/:/home" + --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) --disk-removable : Sets if removable volume should be printed. Default is false --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ --cpu-temp : Detect and display CPU temperature if supported. Default is false diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c new file mode 100644 index 000000000..27117a017 --- /dev/null +++ b/src/detection/disk/disk_windows.c @@ -0,0 +1,66 @@ +#include "disk.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +static void detectDrive(const char* folderPath, uint32_t pathLen, FFDiskResult* result) +{ + ffStrbufInitNS(&result->path, pathLen, folderPath); + result->removable = false; //To be set at other place + result->files = 0; //Unsupported + + //According to https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa + //GetDiskFreeSpaceExA does not have to specify the root directory on a disk. The function accepts any directory on a disk. + uint64_t freeBytes; + if(GetDiskFreeSpaceExA(folderPath, NULL, (PULARGE_INTEGER)&result->total, (PULARGE_INTEGER)&freeBytes)) { + result->used = result->total - freeBytes; + ffStrbufInit(&result->error); + } + else + ffStrbufInitS(&result->error, "GetDiskFreeSpaceExA() failed"); +} + +const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) +{ + FF_UNUSED(instance); + + char buf[128]; // "C:\\\0D:\\\0" + uint32_t length = GetLogicalDriveStringsA(sizeof(buf) / sizeof(*buf), buf); + + for(size_t i = 0; i < length;) + { + const char* drive = buf + i; + uint32_t driveLen = (uint32_t) strlen(drive); + i += driveLen + 1; + + bool removable = GetDriveTypeA(drive) == DRIVE_REMOVABLE; + if(removable && !instance->config.diskRemovable) + continue; + + FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); + detectDrive(drive, driveLen, folder); + folder->removable = removable; + } + + return NULL; +} + +bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders) +{ + ffStrbufTrim(&instance->config.diskFolders, ';'); + if(instance->config.diskFolders.length == 0) + return false; + + uint32_t startIndex = 0; + while(startIndex < instance->config.diskFolders.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ';'); + instance->config.diskFolders.chars[colonIndex] = '\0'; + + detectDrive(instance->config.diskFolders.chars + startIndex, colonIndex - startIndex, (FFDiskResult*)ffListAdd(folders)); + + startIndex = colonIndex + 1; + } + + return true; +} diff --git a/src/detection/disk/disk_windows.cpp b/src/detection/disk/disk_windows.cpp deleted file mode 100644 index dce2f92eb..000000000 --- a/src/detection/disk/disk_windows.cpp +++ /dev/null @@ -1,55 +0,0 @@ -extern "C" { -#include "disk.h" -} -#include "util/windows/wmi.hpp" - -const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) -{ - FF_UNUSED(instance); - - const wchar_t* query = instance->config.diskRemovable - ? L"SELECT Name, DriveType, FreeSpace, Size FROM Win32_LogicalDisk" - : L"SELECT Name, FreeSpace, Size FROM Win32_LogicalDisk WHERE DriveType != 2"; - IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr); - - if(!pEnumerator) - return "Query WMI service failed"; - - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) - { - FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); - - ffStrbufInit(&folder->path); - ffGetWmiObjString(pclsObj, L"Name", &folder->path); - - uint64_t free; - ffGetWmiObjUnsigned(pclsObj, L"Size", &folder->total); - ffGetWmiObjUnsigned(pclsObj, L"FreeSpace", &free); - folder->used = folder->total - free; - - if(instance->config.diskRemovable) - { - uint64_t driveType; - ffGetWmiObjUnsigned(pclsObj, L"DriveType", &driveType); - folder->removable = driveType == 2; - } - else - folder->removable = false; - - folder->files = 0; //Unsupported - - ffStrbufInit(&folder->error); - } - - pclsObj->Release(); - pEnumerator->Release(); - return nullptr; -} - -bool ffDiskDetectDiskFolders(FFinstance*, FFlist*) -{ - return false; // Unsupported -} From 553f90a7c4a9adac9e685ffd0ec4c358c922eec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 20:45:35 +0800 Subject: [PATCH 037/311] Logo: add support for Windows --- src/detection/os/os_windows.cpp | 8 +-- src/logo/builtin.c | 99 +++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 7a0c54665..b1c595dd4 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -51,12 +51,10 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufClear(&os->variant); } - #ifdef __MSYS__ + if(getenv("MSYSTEM")) ffStrbufAppendS(&os->id, "MSYS2"); - #else - // Enable this after we have Windows logo support - ffStrbufAppendF(&os->id, "Windows %*s", &os->version.length, &os->version.chars); - #endif + else + ffStrbufAppendF(&os->id, "Windows %*s", os->version.length, os->version.chars); ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 991115c0b..285cfb8c7 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1277,6 +1277,102 @@ static const FFlogo* getLogoMsys2() FF_LOGO_RETURN } +static const FFlogo* getLogoWindows11() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("Windows 11") + FF_LOGO_LINES( + "$1\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################\n" + "################ ################" + ) + FF_LOGO_COLORS( + "34" //blue + ) + FF_LOGO_COLOR_KEYS("34"); //blue + FF_LOGO_COLOR_TITLE("36"); //cyan + FF_LOGO_RETURN +} + +static const FFlogo* getLogoWindows8() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("Windows 8", "Windows 8.1", "Windows 10") + FF_LOGO_LINES( + "$1 ..,\n" + " ....,,:;+ccllll\n" + " ...,,+:; cllllllllllllllllll\n" + ",cclllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "llllllllllllll lllllllllllllllllll\n" + "`'ccllllllllll lllllllllllllllllll\n" + " `' \\*:: :ccllllllllllllllll\n" + " ````''*::cll\n" + " ``" + ) + FF_LOGO_COLORS( + "36" //cyan + ) + FF_LOGO_COLOR_KEYS("36"); //cyan + FF_LOGO_COLOR_TITLE("37"); //white + FF_LOGO_RETURN +} + +static const FFlogo* getLogoWindows() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("Windows") + FF_LOGO_LINES( + "$1 ,.=:!!t3Z3z.,\n" + " :tt:::tt333EE3\n" + "$1 Et:::ztt33EEEL$2 @Ee., ..,\n" + "$1 ;tt:::tt333EE7$2 ;EEEEEEttttt33#\n" + "$1 :Et:::zt333EEQ.$2 $EEEEEttttt33QL\n" + "$1 it::::tt333EEF$2 @EEEEEEttttt33F\n" + "$1 ;3=*^```\"*4EEV$2 :EEEEEEttttt33@.\n" + "$3 ,.=::::!t=., $1`$2 @EEEEEEtttz33QF\n" + "$3 ;::::::::zt33)$2 \"4EEEtttji3P*\n" + "$3 :t::::::::tt33.$4:Z3z..$2 ``$4 ,..g.\n" + "$3 i::::::::zt33F$4 AEEEtttt::::ztF\n" + "$3 ;:::::::::t33V$4 ;EEEttttt::::t3\n" + "$3 E::::::::zt33L$4 @EEEtttt::::z3F\n" + "$3{3=*^```\"*4E3)$4 ;EEEtttt:::::tZ`\n" + "$3 `$4 :EEEEtttt::::z7\n" + " \"VEzjt:;;z>*`" + ) + FF_LOGO_COLORS( + "31", //red + "32", //green + "34", //blue + "33" //yellow + ) + FF_LOGO_COLOR_KEYS("34"); //blue + FF_LOGO_COLOR_TITLE("32"); //green + FF_LOGO_RETURN +} + static const FFlogo* getLogoNixOS() { FF_LOGO_INIT @@ -2016,6 +2112,9 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoMintSmall, getLogoMintOld, getLogoMsys2, + getLogoWindows11, + getLogoWindows8, + getLogoWindows, getLogoNixOS, getLogoNixOsOld, getLogoNixOsSmall, From 983669019e2cc75c29491864f51f1e90666f6135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 21:02:33 +0800 Subject: [PATCH 038/311] README: clearify Windows support --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8f834a886..f100921bb 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ The following libraries are used if present at runtime: * [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font. * [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count. * [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE. -* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( WSL ). +* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( Windows, WSL ). * [`freetype`](https://www.freetype.org/): Needed for Termux font detection ( Android ). ## Support status @@ -52,12 +52,12 @@ All categories not listed here should work without needing a specific implementa ##### Available Modules ``` -Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom +Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom ``` ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. @@ -67,12 +67,12 @@ AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal ##### Package managers ``` -Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts +Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop ``` ##### WM themes ``` -KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS) +KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS), DWM (Windows) ``` ##### DE versions @@ -97,6 +97,12 @@ cmake --build . --target fastfetch --target flashfetch If pkg-config fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available. +### Building on Windows + +Currently [MSYS2](https://www.msys2.org/) is required to build fastfetch. Running fastfetch requires msys2 runtime library (`msys-2.0.dll`) but not full MSYS2 environment. + +Full native Windows executable is planned. + ## Packaging ### Repositories From 6a9fd7a84d20dd195ac71b085f038ffb887f0b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 21:12:27 +0800 Subject: [PATCH 039/311] TerminalShell: silence compiler warnings --- src/detection/terminalshell/terminalshell_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index bdb604a95..c463e8bcb 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -52,7 +52,7 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb static void getShellVersion(FFstrbuf* exe, FFstrbuf* version) { - char* const argv[] = { exe->chars, "--version", NULL }; + char* const argv[] = { exe->chars, (char*)"--version", NULL }; ffProcessAppendStdOut(version, argv); ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); From 0381d88e2d0356c14cb3c1d50107443a6b5fc4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 21:33:54 +0800 Subject: [PATCH 040/311] TerminalShell: detect `cmd` ( Windows ) --- src/detection/terminalshell/terminalshell_windows.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index c463e8bcb..7496fd6be 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -76,7 +76,9 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) getShellVersion(&result->shellExe, &result->shellVersion); } else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell") == 0) - ffStrbufSetS(&result->shellProcessName, "Windows PowerShell"); + ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell"); + else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "cmd") == 0) + ffStrbufSetS(&result->shellPrettyName, "Command Prompt"); return ppid; } From 643aa7c156a2e906658f7bc4ba8f5ebfaa38b4b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 22:24:12 +0800 Subject: [PATCH 041/311] TerminalFont: add conhost detection --- .../terminalfont/terminalfont_linux.c | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index ee381744e..06a71da50 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -317,6 +317,9 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFon #endif +#if defined(_WIN32) || defined(__MSYS__) +// TODO: move to a separate file + static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { FFstrbuf fontName; @@ -340,6 +343,56 @@ static void detectMintty(const FFinstance* instance, FFTerminalFontResult* termi ffStrbufDestroy(&fontSize); } +#define WIN32_LEAN_AND_MEAN 1 +#include + +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 hKey; + if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS) + { + ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed"); + return; + } + + DWORD bufSize; + + wchar_t fontNameW[64]; + bufSize = sizeof(fontNameW); + if(RegQueryValueExW(hKey, L"FaceName", NULL, NULL, (LPBYTE)fontNameW, &bufSize) != ERROR_SUCCESS) + { + ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(FaceName) failed"); + goto exit; + } + 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) + { + ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(fontSize) failed"); + goto exit; + } + + char fontSize[16]; + snprintf(fontSize, sizeof(fontSize), "%u", (fontSizeNum >> 16)); + + ffFontInitValues(&terminalFont->font, fontNameA, fontSize); + +exit: + RegCloseKey(hKey); +} + +#endif //defined(_WIN32) || defined(__MSYS__) + void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0) @@ -355,6 +408,11 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) detectFromWindowsTeriminal(instance, terminalFont); + + #if defined(_WIN32) || defined(__MSYS__) else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0) detectMintty(instance, terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0) + detectConhost(instance, terminalFont); + #endif } From f2540f00a5d0774aa2e71dcf976c3bf82201d6f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Oct 2022 23:23:46 +0800 Subject: [PATCH 042/311] Address some feedbacks --- CMakeLists.txt | 71 ++++++++++--------- ...{battery_android.c => battery_nosupport.c} | 2 +- src/detection/bios/bios_apple.c | 11 --- .../bios/{bios_android.c => bios_nosupport.c} | 2 +- src/detection/board/board_android.c | 10 --- .../{board_apple.c => board_nosupport.c} | 2 +- ...er_android.c => displayserver_nosupport.c} | 0 .../font/{font_android.c => font_nosupport.c} | 2 +- .../gpu/{gpu_android.c => gpu_nosupport.c} | 2 +- .../{media_android.c => media_nosupport.c} | 2 +- ...apter_linux.c => poweradapter_nosupport.c} | 2 +- ...{wmtheme_android.c => wmtheme_nosupport.c} | 2 +- 12 files changed, 45 insertions(+), 63 deletions(-) rename src/detection/battery/{battery_android.c => battery_nosupport.c} (77%) delete mode 100644 src/detection/bios/bios_apple.c rename src/detection/bios/{bios_android.c => bios_nosupport.c} (75%) delete mode 100644 src/detection/board/board_android.c rename src/detection/board/{board_apple.c => board_nosupport.c} (72%) rename src/detection/displayserver/{displayserver_android.c => displayserver_nosupport.c} (100%) rename src/detection/font/{font_android.c => font_nosupport.c} (66%) rename src/detection/gpu/{gpu_android.c => gpu_nosupport.c} (73%) rename src/detection/media/{media_android.c => media_nosupport.c} (63%) rename src/detection/poweradapter/{poweradapter_linux.c => poweradapter_nosupport.c} (75%) rename src/detection/wmtheme/{wmtheme_android.c => wmtheme_nosupport.c} (71%) diff --git a/CMakeLists.txt b/CMakeLists.txt index de7d36a6f..54871bab5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs project(fastfetch VERSION 1.7.2 - LANGUAGES C CXX # Windows part requires C++ compiler + LANGUAGES C DESCRIPTION "Fast system information tool" HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch" ) @@ -13,14 +13,16 @@ project(fastfetch if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel -elseif("${CMAKE_SYSTEM_NAME}" MATCHES "MSYS|Windows") - set(WIN_MSYS TRUE CACHE BOOL "..." FORCE) # Windows on msys2 elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) -elseif(NOT APPLE AND NOT ANDROID) +elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() +if(MSYS) + enable_language(CXX) +endif() + ##################### # Configure options # ##################### @@ -28,7 +30,7 @@ endif() include(CMakeDependentOption) cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN_MSYS" OFF) +cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF) @@ -47,8 +49,8 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN_MSYS" OFF) -cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN_MSYS" OFF) +cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS" OFF) +cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) option(BUILD_TESTS "Build tests" OFF) # Also create test executables @@ -78,7 +80,7 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") -if(WIN_MSYS) +if(MSYS) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti") endif() @@ -90,7 +92,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) endif() set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer") -if(NOT WIN_MSYS) +if(NOT MSYS) set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") @@ -298,10 +300,11 @@ if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c - src/detection/poweradapter/poweradapter_linux.c src/detection/temps/temps_linux.c src/detection/opengl/opengl_linux.c src/detection/processes/processes_linux.c + + src/detection/poweradapter/poweradapter_nosupport.c ) endif() @@ -327,7 +330,7 @@ if(LINUX OR BSD) ) endif() -if(WIN_MSYS) +if(MSYS) list(APPEND LIBFASTFETCH_SRC src/common/processing_linux.c src/detection/host/host_windows.cpp @@ -349,17 +352,15 @@ if(WIN_MSYS) src/detection/font/font_windows.cpp src/detection/terminalshell/terminalshell_linux.c src/detection/terminalshell/terminalshell_windows.cpp + src/detection/terminalfont/terminalfont_linux.c src/detection/packages/packages_linux.c src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp src/detection/localip/localip_windows.c src/util/windows/wmi.cpp - # Shared - src/detection/terminalfont/terminalfont_linux.c - src/detection/poweradapter/poweradapter_linux.c - src/detection/media/media_linux.c - src/detection/temps/temps_linux.c + src/detection/poweradapter/poweradapter_nosupport.c + src/detection/media/media_nosupport.c ) endif() @@ -369,8 +370,6 @@ if(APPLE) src/util/apple/cf_helpers.c src/util/apple/osascript.m src/detection/host/host_apple.c - src/detection/bios/bios_apple.c - src/detection/board/board_apple.c src/detection/os/os_apple.m src/detection/cpu/cpu_apple.c src/detection/gpu/gpu_apple.c @@ -386,6 +385,9 @@ if(APPLE) src/detection/font/font_apple.m src/detection/opengl/opengl_apple.c src/detection/processes/processes_apple.c + + src/detection/bios/bios_nosupport.c + src/detection/board/board_nosupport.c ) endif() @@ -399,16 +401,17 @@ endif() if(ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/host/host_android.c - src/detection/bios/bios_android.c - src/detection/board/board_android.c src/detection/os/os_android.c - src/detection/gpu/gpu_android.c - src/detection/battery/battery_android.c - src/detection/displayserver/displayserver_android.c src/detection/terminalfont/terminalfont_android.c - src/detection/media/media_android.c - src/detection/wmtheme/wmtheme_android.c - src/detection/font/font_android.c + + src/detection/bios/bios_nosupport.c + src/detection/board/board_nosupport.c + src/detection/displayserver/displayserver_nosupport.c + src/detection/battery/battery_nosupport.c + src/detection/gpu/gpu_nosupport.c + src/detection/font/font_nosupport.c + src/detection/media/media_nosupport.c + src/detection/wmtheme/wmtheme_nosupport.c ) endif() @@ -486,15 +489,15 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" ) -elseif(WIN_MSYS) +elseif(MSYS) target_link_libraries(libfastfetch - PRIVATE "-lwbemuuid" - PRIVATE "-lole32" - PRIVATE "-loleaut32" - PRIVATE "-ldwmapi" - PRIVATE "-lopengl32" - PRIVATE "-lgdi32" - PRIVATE "-liphlpapi" + PRIVATE "wbemuuid" + PRIVATE "ole32" + PRIVATE "oleaut32" + PRIVATE "dwmapi" + PRIVATE "opengl32" + PRIVATE "gdi32" + PRIVATE "iphlpapi" ) endif() diff --git a/src/detection/battery/battery_android.c b/src/detection/battery/battery_nosupport.c similarity index 77% rename from src/detection/battery/battery_android.c rename to src/detection/battery/battery_nosupport.c index 6a59625d7..40ca05241 100644 --- a/src/detection/battery/battery_android.c +++ b/src/detection/battery/battery_nosupport.c @@ -4,5 +4,5 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { FF_UNUSED(instance, results) - return "Unimplemented"; + return "Not supported on this platform"; } diff --git a/src/detection/bios/bios_apple.c b/src/detection/bios/bios_apple.c deleted file mode 100644 index f22dca253..000000000 --- a/src/detection/bios/bios_apple.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "bios.h" - -void ffDetectBios(FFBiosResult* bios) -{ - ffStrbufInitS(&bios->error, "Not supported on macOS"); - - ffStrbufInit(&bios->biosDate); - ffStrbufInit(&bios->biosRelease); - ffStrbufInit(&bios->biosVendor); - ffStrbufInit(&bios->biosVersion); -} diff --git a/src/detection/bios/bios_android.c b/src/detection/bios/bios_nosupport.c similarity index 75% rename from src/detection/bios/bios_android.c rename to src/detection/bios/bios_nosupport.c index c767f3616..f8d886182 100644 --- a/src/detection/bios/bios_android.c +++ b/src/detection/bios/bios_nosupport.c @@ -2,7 +2,7 @@ void ffDetectBios(FFBiosResult* bios) { - ffStrbufInitS(&bios->error, "Not supported on Android"); + ffStrbufInitS(&bios->error, "Not supported on this platform"); ffStrbufInit(&bios->biosDate); ffStrbufInit(&bios->biosRelease); diff --git a/src/detection/board/board_android.c b/src/detection/board/board_android.c deleted file mode 100644 index d55dfe453..000000000 --- a/src/detection/board/board_android.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "board.h" - -void ffDetectBoard(FFBoardResult* board) -{ - ffStrbufInitS(&board->error, "Not supported on Android"); - - ffStrbufInit(&board->boardName); - ffStrbufInit(&board->boardVendor); - ffStrbufInit(&board->boardVersion); -} diff --git a/src/detection/board/board_apple.c b/src/detection/board/board_nosupport.c similarity index 72% rename from src/detection/board/board_apple.c rename to src/detection/board/board_nosupport.c index 76704dbd7..0b182ba3e 100644 --- a/src/detection/board/board_apple.c +++ b/src/detection/board/board_nosupport.c @@ -2,7 +2,7 @@ void ffDetectBoard(FFBoardResult* board) { - ffStrbufInitS(&board->error, "Not supported on macOS"); + ffStrbufInitS(&board->error, "Not supported on this platform"); ffStrbufInit(&board->boardName); ffStrbufInit(&board->boardVendor); diff --git a/src/detection/displayserver/displayserver_android.c b/src/detection/displayserver/displayserver_nosupport.c similarity index 100% rename from src/detection/displayserver/displayserver_android.c rename to src/detection/displayserver/displayserver_nosupport.c diff --git a/src/detection/font/font_android.c b/src/detection/font/font_nosupport.c similarity index 66% rename from src/detection/font/font_android.c rename to src/detection/font/font_nosupport.c index f2331a302..f88ad8395 100644 --- a/src/detection/font/font_android.c +++ b/src/detection/font/font_nosupport.c @@ -4,5 +4,5 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) { FF_UNUSED(instance); - ffStrbufAppendS(&result->error, "Not implemented"); + ffStrbufAppendS(&result->error, "Not supported on this platform"); } diff --git a/src/detection/gpu/gpu_android.c b/src/detection/gpu/gpu_nosupport.c similarity index 73% rename from src/detection/gpu/gpu_android.c rename to src/detection/gpu/gpu_nosupport.c index 6e0afe389..ef2d54abd 100644 --- a/src/detection/gpu/gpu_android.c +++ b/src/detection/gpu/gpu_nosupport.c @@ -3,5 +3,5 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) { FF_UNUSED(gpus, instance); - return "Unimplemented"; + return "Not supported on this platform"; } diff --git a/src/detection/media/media_android.c b/src/detection/media/media_nosupport.c similarity index 63% rename from src/detection/media/media_android.c rename to src/detection/media/media_nosupport.c index 0cf6d53d1..e3d038186 100644 --- a/src/detection/media/media_android.c +++ b/src/detection/media/media_nosupport.c @@ -3,5 +3,5 @@ void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media) { FF_UNUSED(instance); - ffStrbufAppendS(&media->error, "Media not supported on Android"); + ffStrbufAppendS(&media->error, "Not supported on this platform"); } diff --git a/src/detection/poweradapter/poweradapter_linux.c b/src/detection/poweradapter/poweradapter_nosupport.c similarity index 75% rename from src/detection/poweradapter/poweradapter_linux.c rename to src/detection/poweradapter/poweradapter_nosupport.c index 4e5bebd80..cf6d1c841 100644 --- a/src/detection/poweradapter/poweradapter_linux.c +++ b/src/detection/poweradapter/poweradapter_nosupport.c @@ -3,5 +3,5 @@ const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results) { FF_UNUSED(instance, results); - return "Unimplemented"; + return "Not supported on this platform"; } diff --git a/src/detection/wmtheme/wmtheme_android.c b/src/detection/wmtheme/wmtheme_nosupport.c similarity index 71% rename from src/detection/wmtheme/wmtheme_android.c rename to src/detection/wmtheme/wmtheme_nosupport.c index 7d9da9a5d..5dc5691d3 100644 --- a/src/detection/wmtheme/wmtheme_android.c +++ b/src/detection/wmtheme/wmtheme_nosupport.c @@ -5,6 +5,6 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) { FF_UNUSED(instance); - ffStrbufAppendS(themeOrError, "WM theme detection is not supported on Android"); + ffStrbufAppendS(themeOrError, "Not supported on this platform"); return false; } From df986d36a2b44d17f720a05bdc1a3e2af86a2527 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 10 Oct 2022 10:16:43 +0200 Subject: [PATCH 043/311] Print the last element of the default structure #283 --- .editorconfig | 2 +- CHANGELOG.md | 4 ++++ CMakeLists.txt | 9 +++++---- src/fastfetch.c | 20 ++++++++------------ 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.editorconfig b/.editorconfig index b2ae4e980..c65cfad7b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,7 @@ trim_trailing_whitespace = true [*.{md,fflogo}] trim_trailing_whitespace = false -[*.{txt,fflogo}] +[*.{fflogo}] insert_final_newline = false [*.yml] diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c2403bb6..ffb90a097 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.7.4 + +The last element in the default structure (currently the color blocks) is now printed again (#283) + # 1.7.3 A lot of small improvements for MacOS & BSD platforms. diff --git a/CMakeLists.txt b/CMakeLists.txt index ec7e6c459..5337af873 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 1.7.3 + VERSION 1.7.4 LANGUAGES C DESCRIPTION "Fast system information tool" HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch" @@ -167,9 +167,10 @@ endif() function(fastfetch_load_text FILENAME OUTVAR) file(READ "${FILENAME}" TEMP) - string(REPLACE "\n" "\\n" TEMP "${TEMP}") - string(REPLACE "\"" "\\\"" TEMP "${TEMP}") - string(REPLACE "$\\" "" TEMP "${TEMP}") + string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline + string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n + string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \" + string(REPLACE "$\\" "" TEMP "${TEMP}") # Remove $\, so we can unescape some things set("${OUTVAR}" "${TEMP}" PARENT_SCOPE) endfunction(fastfetch_load_text) diff --git a/src/fastfetch.c b/src/fastfetch.c index fff00ea5b..1520a998c 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -780,12 +780,12 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con } else if(strcasecmp(key, "--print-config-system") == 0) { - fputs(FASTFETCH_DATATEXT_CONFIG_SYSTEM, stdout); + puts(FASTFETCH_DATATEXT_CONFIG_SYSTEM); exit(0); } else if(strcasecmp(key, "--print-config-user") == 0) { - fputs(FASTFETCH_DATATEXT_CONFIG_USER, stdout); + puts(FASTFETCH_DATATEXT_CONFIG_USER); exit(0); } else if(strcasecmp(key, "--print-structure") == 0) @@ -795,7 +795,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con } else if(strcasecmp(key, "--list-modules") == 0) { - fputs(FASTFETCH_DATATEXT_MODULES, stdout); + puts(FASTFETCH_DATATEXT_MODULES); exit(0); } else if(strcasecmp(key, "--list-presets") == 0) @@ -1485,18 +1485,14 @@ int main(int argc, const char** argv) if(data.structure.length == 0) ffStrbufAppendS(&data.structure, FASTFETCH_DATATEXT_STRUCTURE); - #define FF_CONTAINS_MODULE_NAME(moduleName)\ - ffStrbufContainIgnCaseS(&data.structure, ":" #moduleName ":") ||\ - ffStrbufStartsWithIgnCaseS(&data.structure, #moduleName ":") ||\ - ffStrbufEndsWithIgnCaseS(&data.structure, ":" #moduleName) - - if(FF_CONTAINS_MODULE_NAME(CPUUsage)) + if(ffStrbufContainIgnCaseS(&data.structure, "CPUUsage")) ffPrepareCPUUsage(); - if(FF_CONTAINS_MODULE_NAME(PublicIp)) + + if(ffStrbufContainIgnCaseS(&data.structure, "PublicIp")) ffPreparePublicIp(&instance); - if(FF_CONTAINS_MODULE_NAME(Weather)) + + if(ffStrbufContainIgnCaseS(&data.structure, "Weather")) ffPrepareWeather(&instance); - #undef FF_CONTAINS_MODULE_NAME ffStart(&instance); From d54f14a14cfd79db50ddbbc976a6a4795100ccfa Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Tue, 11 Oct 2022 12:37:54 +0200 Subject: [PATCH 044/311] ffStrbufLastIndexC: account for empty strings #285 --- src/detection/terminalshell/terminalshell_linux.c | 1 - src/util/FFstrbuf.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 3adca984f..48e5e2c38 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -224,7 +224,6 @@ static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version) "--version", NULL }); - ffStrbufTrimRight(version, '\n'); ffStrbufSubstrBeforeLastC(version, ' '); ffStrbufSubstrAfterFirstC(version, ' '); } diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index d6397c6dc..687969606 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -184,6 +184,9 @@ static inline FF_C_NODISCARD uint32_t ffStrbufFirstIndexS(const FFstrbuf* strbuf static inline FF_C_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, char c) { + if(strbuf->length == 0) + return strbuf->length; + return ffStrbufPreviousIndexC(strbuf, strbuf->length - 1, c); } From 9879a9557024dd752942d3f2fb44b8f3a7b1b742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 10 Oct 2022 15:48:48 +0800 Subject: [PATCH 045/311] Packages: fix scoop detection when it's not installed --- src/detection/packages/packages_windows.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 53d45d351..994a3e333 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -36,6 +36,10 @@ void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts) FFstrbuf scoopPath; ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); - counts->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY) - 3; // . .. scoop + counts->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); + if(counts->scoop >= 3) + counts->scoop -= 3; // . .. scoop + else + counts->scoop = 0; ffStrbufDestroy(&scoopPath); } From 2e42bbb1a27d3dd3cb85e81c1831147c617cc184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 11 Oct 2022 13:15:43 +0800 Subject: [PATCH 046/311] Don't enable LTO on Debug mode which breaks debuging on macOS --- CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5337af873..3527b5fb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,10 +98,12 @@ endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG} -rdynamic") -include(CheckIPOSupported) -check_ipo_supported(RESULT IPO_SUPPORTED) -if(IPO_SUPPORTED) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + include(CheckIPOSupported) + check_ipo_supported(RESULT IPO_SUPPORTED) + if(IPO_SUPPORTED) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + endif() endif() ####################### From 3d2497f9636f567687358a5a366a27e329c08f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 11 Oct 2022 13:17:32 +0800 Subject: [PATCH 047/311] macOS: fix compile warnings --- src/detection/memory/memory.c | 2 +- src/detection/processes/processes_apple.c | 2 +- src/detection/temps/temps_apple.c | 2 +- src/modules/disk.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/detection/memory/memory.c b/src/detection/memory/memory.c index f777554c3..62be6197e 100644 --- a/src/detection/memory/memory.c +++ b/src/detection/memory/memory.c @@ -11,7 +11,7 @@ static void calculatePercentage(FFMemoryStorage* storage) if(storage->bytesTotal == 0) storage->percentage = 0; else - storage->percentage = (uint8_t) ((storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); + storage->percentage = (uint8_t) (((long double) storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); } const FFMemoryResult* ffDetectMemory() diff --git a/src/detection/processes/processes_apple.c b/src/detection/processes/processes_apple.c index 32a251b1a..bbed0db2d 100644 --- a/src/detection/processes/processes_apple.c +++ b/src/detection/processes/processes_apple.c @@ -11,7 +11,7 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0) { - ffStrbufAppend(error, "sysctl() failed"); + ffStrbufAppendS(error, "sysctl() failed"); return 0; } return (uint32_t)(length / sizeof(struct kinfo_proc)); diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c index b952e720b..015546ecf 100644 --- a/src/detection/temps/temps_apple.c +++ b/src/detection/temps/temps_apple.c @@ -207,7 +207,7 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl uint64_t tmp = 0; for (uint32_t i = 0; i < val.dataSize; i++) tmp += (uint64_t)((uint8_t)(val.bytes[i]) * pow(256, val.dataSize - 1 - i)); - *value = tmp; + *value = (double)tmp; } else if (strcmp(val.dataType, kDataTypeFlt) == 0) { diff --git a/src/modules/disk.c b/src/modules/disk.c index 8f97f54ba..07903c496 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -24,7 +24,7 @@ static void printFolder(FFinstance* instance, FFDiskResult* folder) }); } - uint8_t percentage = (uint8_t) ((folder->used / (long double) folder->total) * 100.0); + uint8_t percentage = (uint8_t) (((long double) folder->used / (long double) folder->total) * 100.0); FFstrbuf usedPretty; ffStrbufInit(&usedPretty); From 424fbfc9c9a480965fe835ba806b0f724d750ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 11 Oct 2022 14:59:09 +0800 Subject: [PATCH 048/311] TerminalShell: actually support macOS --- .../terminalshell/terminalshell_linux.c | 108 ++++++++++++------ 1 file changed, 70 insertions(+), 38 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 48e5e2c38..b5f68c58f 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -11,6 +11,10 @@ #include #include +#ifdef __APPLE__ + #include +#endif + static void setExeName(FFstrbuf* exe, const char** exeName) { assert(exe->length > 0); @@ -19,64 +23,92 @@ static void setExeName(FFstrbuf* exe, const char** exeName) *exeName = exe->chars + lastSlashIndex + 1; } -static void getProcessInformation(const char* pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName) +static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName) { assert(processName->length > 0); - - FFstrbuf cmdlineFilePath; - ffStrbufInit(&cmdlineFilePath); - ffStrbufAppendS(&cmdlineFilePath, "/proc/"); - ffStrbufAppendS(&cmdlineFilePath, pid); - ffStrbufAppendS(&cmdlineFilePath, "/cmdline"); - ffStrbufClear(exe); - if(ffAppendFileBuffer(cmdlineFilePath.chars, exe)) + + #if defined(__linux__) || defined(__MSYS__) + + char cmdlineFilePath[64]; + snprintf(cmdlineFilePath, sizeof(cmdlineFilePath), "/proc/%d/cmdline", (int)pid); + + if(ffAppendFileBuffer(cmdlineFilePath, exe)) { ffStrbufSubstrBeforeFirstC(exe, '\0'); //Trim the arguments ffStrbufTrimLeft(exe, '-'); //Happens in TTY } + #elif defined(__APPLE__) + + int length = proc_pidpath((int)pid, exe->chars, exe->allocated); + if(length > 0) + exe->length = (uint32_t)length; + + #else + + //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) + + #endif + if(exe->length == 0) ffStrbufSet(exe, processName); setExeName(exe, exeName); - - ffStrbufDestroy(&cmdlineFilePath); } -static void getTerminalShell(FFTerminalShellResult* result, const char* pid) +static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid) { - FFstrbuf statFilePath; - ffStrbufInit(&statFilePath); - ffStrbufAppendS(&statFilePath, "/proc/"); - ffStrbufAppendS(&statFilePath, pid); - ffStrbufAppendS(&statFilePath, "/stat"); + const char* error = NULL; - FILE* stat = fopen(statFilePath.chars, "r"); - - ffStrbufDestroy(&statFilePath); + #if defined(__linux__) || defined(__MSYS__) + char statFilePath[64]; + snprintf(statFilePath, sizeof(statFilePath), "/proc/%d/stat", (int)pid); + FILE* stat = fopen(statFilePath, "r"); if(stat == NULL) - return; + return "fopen(statFilePath, \"r\") failed"; + *ppid = 0; + if( + fscanf(stat, "%*s (%255[^)]) %*c %d", name, ppid) != 2 || //stat (comm) state ppid + !ffStrSet(name) || + *ppid == 0 + ) + error = "fscanf(stat) failed"; + + fclose(stat); + + #elif defined(__APPLE__) + + struct proc_bsdshortinfo proc; + if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0) + error = "proc_pidinfo(pid) failed"; + else + { + *ppid = (pid_t)proc.pbsi_ppid; + strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars + } + + #else + + //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) + error = "unimplemented"; + + #endif + + return error; +} + +static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) +{ char name[256]; name[0] = '\0'; - char ppid[256]; - ppid[0] = '\0'; + pid_t ppid = 0; - if( - fscanf(stat, "%*s (%255[^)]) %*c %255s", name, ppid) != 2 || //stat (comm) state ppid - !ffStrSet(name) || - !ffStrSet(ppid) || - *ppid == '-' || - strcasecmp(ppid, "0") == 0 - ) { - fclose(stat); + if(getProcessNameAndPpid(pid, name, &ppid)) return; - } - - fclose(stat); //Common programs that are between terminal and own process, but are not the shell if( @@ -86,7 +118,9 @@ static void getTerminalShell(FFTerminalShellResult* result, const char* pid) strcasecmp(name, "strace") == 0 || strcasecmp(name, "sshd") == 0 || strcasecmp(name, "gdb") == 0 || - strcasecmp(name, "guake-wrapped") == 0 + strcasecmp(name, "lldb") == 0 || + strcasecmp(name, "guake-wrapped") == 0 || + strcasestr(name, "debug") != NULL ) { getTerminalShell(result, ppid); return; @@ -308,9 +342,7 @@ const FFTerminalShellResult* result.userShellExeName = result.userShellExe.chars; ffStrbufInit(&result.userShellVersion); - char ppid[32]; - snprintf(ppid, sizeof(ppid) - 1, "%i", getppid()); - getTerminalShell(&result, ppid); + getTerminalShell(&result, getppid()); getTerminalFromEnv(&result); getUserShellFromEnv(&result); From 9bc5c99fc89142329fac031a0a5de3b61c64724f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 11 Oct 2022 16:10:15 +0800 Subject: [PATCH 049/311] Font: fix memleak on Linux --- src/modules/font.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/font.c b/src/modules/font.c index 176243adf..4223eb799 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -23,6 +23,7 @@ static void printFont(const FFFontResult* font) } ffStrbufWriteTo(>k, stdout); + ffStrbufDestroy(>k); } #elif defined(__APPLE__) From 2cb7be67bd714b713ac62109a6e60ea16db6f7db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 10 Oct 2022 18:12:04 +0800 Subject: [PATCH 050/311] ci: add Windows --- .github/workflows/push.yml | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index ae492a408..6b532c563 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -123,6 +123,71 @@ jobs: name: fastfetch-bsd path: ./fastfetch-*.* + windows: + name: Windows + runs-on: windows-latest + permissions: + security-events: write + contents: read + outputs: + ffversion: ${{ steps.ffversion.outputs.ffversion }} + defaults: + run: + shell: msys2 {0} + steps: + - name: checkout repository + uses: actions/checkout@v3 + + - name: setup-msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: MSYS + update: true + install: git base-devel cmake gcc mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd + + - name: print msys version + run: uname -a + + # https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785 + - name: create OpenCL.pc + run: | + cat > /clang64/lib/pkgconfig/OpenCL.pc << EOF + prefix=/clang64 + exec_prefix=${prefix} + libdir=${exec_prefix}/lib + includedir=${prefix}/include + + Name: OpenCL + Description: Open Computing Language generic Installable Client Driver Loader + Version: 2022.09.30-1 + Libs: -L${libdir} -lOpenCL.dll + Cflags: -I${includedir} + EOF + + - name: configure project + run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . + + - name: build project + run: cmake --build . --target fastfetch --target flashfetch # Makes no sense to install exes to /usr/bin for Windows + + - name: copy necessary dlls + run: cp /usr/bin/msys-2.0.dll /clang64/bin/*.dll . + + # Crashes on start for some reason, but it provides binaries at least. Needs investigation. + # - name: run fastfetch + # run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + + # - name: run flashfetch + # run: ./flashfetch + + - name: upload artifacts + uses: actions/upload-artifact@v3 + with: + name: fastfetch-windows + path: | + ./*.dll + ./*.exe + release: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch' name: Release From 8e8d2839591858bd5c91634d1a711a7c9091d256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 11 Oct 2022 20:13:44 +0800 Subject: [PATCH 051/311] Windows: fix crashing --- src/util/windows/wmi.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 845a3dda4..cff1c9a97 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -142,6 +142,11 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { int len = (int)SysStringLen(bstr); + if(len <= 0) + { + ffStrbufClear(strbuf); + return; + } int size_needed = WideCharToMultiByte(CP_UTF8, 0, bstr, len, nullptr, 0, nullptr, nullptr); ffStrbufEnsureFree(strbuf, (uint32_t)size_needed); WideCharToMultiByte(CP_UTF8, 0, bstr, len, strbuf->chars, size_needed, nullptr, nullptr); From 779266e61e536f17b3d30a0bde077ebd28ae577d Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Tue, 11 Oct 2022 14:26:00 +0200 Subject: [PATCH 052/311] Release 1.7.5 --- CHANGELOG.md | 4 ++++ CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffb90a097..c91d6efa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.7.5 + +Fixes a crash on linux that could happen when getting zsh version (#285) + # 1.7.4 The last element in the default structure (currently the color blocks) is now printed again (#283) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5337af873..1684259d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 1.7.4 + VERSION 1.7.5 LANGUAGES C DESCRIPTION "Fast system information tool" HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch" From 5e3e2b6137d13cd64f3118e86af9a9fcb745fcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 11 Oct 2022 22:36:14 +0800 Subject: [PATCH 053/311] Windows: fix possible crashes --- src/detection/battery/battery_windows.cpp | 6 ++++-- src/detection/font/font_windows.cpp | 4 +--- src/detection/gpu/gpu_windows.cpp | 2 +- src/detection/host/host_windows.cpp | 4 +--- src/detection/localip/localip_windows.c | 17 ++++++++++++----- src/detection/users/users_windows.cpp | 2 +- src/util/windows/wmi.cpp | 7 ++++--- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp index 48084720a..fce0b5657 100644 --- a/src/detection/battery/battery_windows.cpp +++ b/src/detection/battery/battery_windows.cpp @@ -26,7 +26,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) ffStrbufInit(&battery->modelName); ffGetWmiObjString(pclsObj, L"Name", &battery->modelName); - uint64_t chemistry; + uint64_t chemistry = 0; ffGetWmiObjUnsigned(pclsObj, L"Chemistry", &chemistry); switch(chemistry) { @@ -38,6 +38,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) 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; } uint64_t capacity; @@ -59,12 +60,13 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) 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; } - pclsObj->Release(); + if(pclsObj) pclsObj->Release(); pEnumerator->Release(); return nullptr; } diff --git a/src/detection/font/font_windows.cpp b/src/detection/font/font_windows.cpp index 1d4196bde..0ade9812e 100644 --- a/src/detection/font/font_windows.cpp +++ b/src/detection/font/font_windows.cpp @@ -19,9 +19,7 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) IWbemClassObject *pclsObj = NULL; ULONG uReturn = 0; - pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); - - if(uReturn == 0) + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) { ffStrbufInitS(&result->error, "No WMI result returned"); pEnumerator->Release(); diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index 443ad422e..d99885633 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -38,7 +38,7 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; } - pclsObj->Release(); + if(pclsObj) pclsObj->Release(); pEnumerator->Release(); return nullptr; } diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp index 34141cf72..60f3fcedf 100644 --- a/src/detection/host/host_windows.cpp +++ b/src/detection/host/host_windows.cpp @@ -23,9 +23,7 @@ extern "C" void ffDetectHostImpl(FFHostResult* host) IWbemClassObject *pclsObj = NULL; ULONG uReturn = 0; - pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); - - if(uReturn == 0) + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) { ffStrbufInitS(&host->error, "No Wmi result returned"); pEnumerator->Release(); diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c index 881dd2d6e..275987f10 100644 --- a/src/detection/localip/localip_windows.c +++ b/src/detection/localip/localip_windows.c @@ -10,11 +10,18 @@ static void addNewIp(FFlist* list, const wchar_t* name, const char* addr, bool i FFLocalIpResult* ip = (FFLocalIpResult*) ffListAdd(list); int len = (int)wcslen(name); - int size_needed = WideCharToMultiByte(CP_UTF8, 0, name, len, NULL, 0, NULL, NULL); - ffStrbufInitA(&ip->name, (uint32_t)size_needed + 1); - WideCharToMultiByte(CP_UTF8, 0, name, len, ip->name.chars, size_needed, NULL, NULL); - ip->name.length = (uint32_t)size_needed; - ip->name.chars[size_needed] = '\0'; + if(len > 0) + { + int size_needed = WideCharToMultiByte(CP_UTF8, 0, name, len, NULL, 0, NULL, NULL); + ffStrbufInitA(&ip->name, (uint32_t)size_needed + 1); + WideCharToMultiByte(CP_UTF8, 0, name, len, ip->name.chars, size_needed, NULL, NULL); + ip->name.length = (uint32_t)size_needed; + ip->name.chars[size_needed] = '\0'; + } + else + { + ffStrbufInitS(&ip->name, "*"); + } ffStrbufInitS(&ip->addr, addr); ip->ipv6 = ipv6; diff --git a/src/detection/users/users_windows.cpp b/src/detection/users/users_windows.cpp index 43a6fb3d2..41dd9674b 100644 --- a/src/detection/users/users_windows.cpp +++ b/src/detection/users/users_windows.cpp @@ -37,6 +37,6 @@ next: if(users->length == 0) ffStrbufAppendS(error, "Unable to detect users"); - pclsObj->Release(); + if(pclsObj) pclsObj->Release(); pEnumerator->Release(); } diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index cff1c9a97..925d428ee 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -2,6 +2,7 @@ #include #include +#include //https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer //https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes @@ -232,7 +233,7 @@ bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integ case VT_UI4: *integer = (int64_t)vtProp.uintVal; break; case VT_UI8: *integer = (int64_t)vtProp.ullVal; break; case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break; - default: result = false; + default: *integer = 0; result = false; } } VariantClear(&vtProp); @@ -266,7 +267,7 @@ bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* in case VT_UI4: *integer = vtProp.uintVal; break; case VT_UI8: *integer = vtProp.ullVal; break; case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break; - default: result = false; + default: *integer = 0; result = false; } } VariantClear(&vtProp); @@ -302,7 +303,7 @@ bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real) case VT_R4: *real = vtProp.fltVal; break; case VT_R8: *real = vtProp.dblVal; break; case VT_BOOL: *real = vtProp.boolVal != VARIANT_FALSE; break; - default: result = false; + default: *real = NAN; result = false; } } VariantClear(&vtProp); From 8c127a175cd8f0c354917d6e7f077d252b69c61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 00:13:49 +0800 Subject: [PATCH 054/311] TerminalShell: try detecting more shells --- src/detection/terminalshell/terminalshell_windows.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 7496fd6be..8c1466974 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -77,8 +77,15 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) } else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell") == 0) ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell"); + else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell_ise") == 0) + ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell ISE"); else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "cmd") == 0) ffStrbufSetS(&result->shellPrettyName, "Command Prompt"); + else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0) + { + ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); // Started without shell + return 0; + } return ppid; } @@ -99,6 +106,8 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal"); else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost") == 0) ffStrbufSetS(&result->terminalPrettyName, "Console Window Host"); + else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0) + ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); return ppid; } @@ -148,7 +157,6 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) return &result; // TODO: handle nested shells - // TODO: handle running without shells ( dblclick exe in Windows Explorer ) ppid = getTerminalInfo(&result, ppid); if(ppid == 0) From 34cd81b4d9ead7fd78fd38f59dce268810b712ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 00:17:09 +0800 Subject: [PATCH 055/311] ci: run fastfetch on Windows --- .github/workflows/push.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 6b532c563..76fd9ede9 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -171,14 +171,13 @@ jobs: run: cmake --build . --target fastfetch --target flashfetch # Makes no sense to install exes to /usr/bin for Windows - name: copy necessary dlls - run: cp /usr/bin/msys-2.0.dll /clang64/bin/*.dll . + run: cp /usr/bin/msys-2.0.dll /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - # Crashes on start for some reason, but it provides binaries at least. Needs investigation. - # - name: run fastfetch - # run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + - name: run fastfetch + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - # - name: run flashfetch - # run: ./flashfetch + - name: run flashfetch + run: ./flashfetch - name: upload artifacts uses: actions/upload-artifact@v3 From 4bae08c159cba3d0a319561b4ab97a8658a1b57e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 00:36:01 +0800 Subject: [PATCH 056/311] OS: detect Windows Server --- src/detection/os/os_windows.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index b1c595dd4..4df85791f 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -33,13 +33,21 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) return; } - ffGetWmiObjString(pclsObj, L"Caption", &os->variant); // Microsoft Windows 11 家庭中文版 + ffGetWmiObjString(pclsObj, L"Caption", &os->variant); if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows ")) { ffStrbufAppendS(&os->name, "Microsoft Windows"); ffStrbufAppendS(&os->prettyName, "Windows"); - ffStrbufSubstrAfter(&os->variant, strlen("Microsoft Windows ") - 1); // 11 家庭中文版 + 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); From bc72f3cd64de6fbd4c9eed1d89b94da7a5511132 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Tue, 11 Oct 2022 19:41:37 +0200 Subject: [PATCH 057/311] Don't build dmg --- CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 639f25dad..018d3375e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -603,12 +603,6 @@ if(LINUX) set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") set(CPACK_RPM_PACKAGE_LICENSE "MIT") -elseif(APPLE) - set(CPACK_GENERATOR "${CPACK_GENERATOR};DragNDrop") - - set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK TRUE) -elseif(BSD) - set(CPACK_GENERATOR "${CPACK_GENERATOR};FreeBSD") endif() set(CPACK_SET_DESTDIR ON) From d0f589bb3e758fc44268c35f8938ea8650c6683f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 14:03:03 +0800 Subject: [PATCH 058/311] Disk: silence warning on macOS --- src/detection/disk/disk_apple.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index b79d03e86..8341ef74e 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -1,5 +1,6 @@ #include "disk.h" +#include #import void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result); From 1b594d9ed18229524135d1aa7a5022a61f303caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 14:13:20 +0800 Subject: [PATCH 059/311] Thread: add common thread abstraction layer, and make threading optional --- CMakeLists.txt | 38 +++++--- README.md | 3 +- src/common/init.c | 90 +++++-------------- src/common/settings.c | 16 ++-- src/common/thread.h | 43 +++++++++ src/detection/datetime.c | 10 +-- src/detection/displayserver/linux/wayland.c | 8 +- src/detection/gtk.c | 19 ++-- src/detection/internal.h | 10 +-- src/detection/media/media_linux.c | 2 +- src/detection/qt.c | 10 +-- src/detection/temps/temps_linux.c | 14 +-- .../terminalshell/terminalshell_linux.c | 10 +-- src/detection/title.c | 10 +-- src/detection/vulkan.c | 11 ++- 15 files changed, 151 insertions(+), 143 deletions(-) create mode 100644 src/common/thread.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 018d3375e..41aaabaaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,17 @@ if(MSYS) enable_language(CXX) endif() +############################# +# Compile time dependencies # +############################# + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads) + +find_package(PkgConfig REQUIRED) + +include(CheckIncludeFile) + ##################### # Configure options # ##################### @@ -52,21 +63,11 @@ cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS" OFF) cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS" 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) 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 -############################# -# Compile time dependencies # -############################# - -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) - -find_package(PkgConfig REQUIRED) - -include(CheckIncludeFile) - #################### # Compiler options # #################### @@ -76,6 +77,15 @@ if(NOT CMAKE_BUILD_TYPE) endif() message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +if(ENABLE_THREADS) + if(CMAKE_USE_PTHREADS_INIT) + message(STATUS "Threads type: pthread") + else() + message(STATUS "Threads type: Win32 thread") + endif() +else() + message(STATUS "Threads type: disabled") +endif() set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") @@ -482,6 +492,11 @@ ff_lib_enable(OPENCL OpenCL) ff_lib_enable(LIBCJSON libcjson) ff_lib_enable(FREETYPE freetype2) +if(ENABLE_THREADS) + target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS) + target_link_libraries(libfastfetch PRIVATE Threads::Threads) +endif() + if(APPLE) target_link_libraries(libfastfetch PRIVATE "-framework CoreFoundation" @@ -511,7 +526,6 @@ target_include_directories(libfastfetch target_link_libraries(libfastfetch PRIVATE ${CMAKE_DL_LIBS} - PRIVATE Threads::Threads ) ###################### diff --git a/README.md b/README.md index f100921bb..b5282ea46 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,10 @@ There are some premade config files in [`presets`](presets), including the ones ## Dependencies -Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and `libpthread`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it. +Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it. The following libraries are used if present at runtime: +* [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html): For multithreading support, which may improve performance * [`libpci`](https://github.com/pciutils/pciutils): GPU output. * [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output. * [`libxcb-randr`](https://xcb.freedesktop.org/), diff --git a/src/common/init.c b/src/common/init.c index be5dd73c1..f9001f12f 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/caching.h" #include "common/parsing.h" +#include "common/thread.h" #include "detection/qt.h" #include "detection/gtk.h" #include "detection/displayserver/displayserver.h" @@ -9,7 +10,6 @@ #include #include #include -#include static bool strbufEqualsAdapter(const void* first, const void* second) { @@ -259,87 +259,39 @@ void ffInitInstance(FFinstance* instance) defaultConfig(instance); } -#if !defined(__ANDROID__) && !defined(_WIN32) && !defined(__MSYS__) +#ifdef FF_HAVE_THREADS -static void* connectDisplayServerThreadMain(void* instance) -{ - ffConnectDisplayServer((FFinstance*)instance); - return NULL; -} +FF_THREAD_ENTRY_DECL_WRAPPER(ffConnectDisplayServer, FFinstance*) -#if !defined(__APPLE__) +#if !(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32)) -static void* detectPlasmaThreadMain(void* instance) -{ - ffDetectQt((FFinstance*)instance); - return NULL; -} +#define FF_DETECT_QT_GTK 1 -static void* detectGTK2ThreadMain(void* instance) -{ - ffDetectGTK2((FFinstance*)instance); - return NULL; -} +FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectQt, FFinstance*) +FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK2, FFinstance*) +FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK3, FFinstance*) +FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK4, FFinstance*) -static void* detectGTK3ThreadMain(void* instance) -{ - ffDetectGTK3((FFinstance*)instance); - return NULL; -} +#endif //!(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32)) -static void* detectGTK4ThreadMain(void* instance) -{ - ffDetectGTK4((FFinstance*)instance); - return NULL; -} - -static void* startThreadsThreadMain(void* instance) -{ - pthread_t dsThread; - pthread_create(&dsThread, NULL, connectDisplayServerThreadMain, instance); - pthread_detach(dsThread); - - pthread_t gtk2Thread; - pthread_create(>k2Thread, NULL, detectGTK2ThreadMain, instance); - pthread_detach(gtk2Thread); - - pthread_t gtk3Thread; - pthread_create(>k3Thread, NULL, detectGTK3ThreadMain, instance); - pthread_detach(gtk3Thread); - - pthread_t gtk4Thread; - pthread_create(>k4Thread, NULL, detectGTK4ThreadMain, instance); - pthread_detach(gtk4Thread); - - pthread_t plasmaThread; - pthread_create(&plasmaThread, NULL, detectPlasmaThreadMain, instance); - pthread_detach(plasmaThread); - - return NULL; -} +#endif //FF_HAVE_THREADS void startDetectionThreads(FFinstance* instance) { - pthread_t startThreadsThread; - pthread_create(&startThreadsThread, NULL, startThreadsThreadMain, instance); - pthread_detach(startThreadsThread); -} + #ifdef FF_HAVE_THREADS + ffThreadCreateAndDetach(ffConnectDisplayServerThreadMain, instance); -#else // !__APPLE__ -void startDetectionThreads(FFinstance* instance) -{ - pthread_t startThreadsThread; - pthread_create(&startThreadsThread, NULL, connectDisplayServerThreadMain, instance); - pthread_detach(startThreadsThread); -} -#endif // __APPLE__ + #ifdef FF_DETECT_QT_GTK + ffThreadCreateAndDetach(ffDetectQtThreadMain, instance); + ffThreadCreateAndDetach(ffDetectGTK2ThreadMain, instance); + ffThreadCreateAndDetach(ffDetectGTK3ThreadMain, instance); + ffThreadCreateAndDetach(ffDetectGTK4ThreadMain, instance); + #endif -#else // !__ANDROID__ -void startDetectionThreads(FFinstance* instance) -{ + #else FF_UNUSED(instance); + #endif } -#endif // __ANDROID__ static volatile bool ffDisableLinewrap = true; static volatile bool ffHideCursor = true; diff --git a/src/common/settings.c b/src/common/settings.c index 1b8a08c5d..6f5a5cfcb 100644 --- a/src/common/settings.c +++ b/src/common/settings.c @@ -2,8 +2,8 @@ #include "common/settings.h" #include "common/library.h" #include "common/io.h" +#include "common/thread.h" -#include #include typedef enum FFInitState @@ -15,18 +15,18 @@ typedef enum FFInitState #define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \ static dataObject data; \ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \ + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \ static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \ - pthread_mutex_lock(&mutex); \ + ffThreadMutexLock(&mutex); \ if(initState != FF_INITSTATE_UNINITIALIZED) {\ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \ } \ initState = FF_INITSTATE_SUCCESSFUL; \ void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \ if(libraryHandle == NULL) { \ initState = FF_INITSTATE_FAILED; \ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return NULL; \ } \ @@ -35,20 +35,20 @@ typedef enum FFInitState if(data.ff ## symbolName == NULL) { \ dlclose(libraryHandle); \ initState = FF_INITSTATE_FAILED; \ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return NULL; \ } #define FF_LIBRARY_DATA_LOAD_RETURN \ initState = FF_INITSTATE_SUCCESSFUL; \ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return &data; #define FF_LIBRARY_DATA_LOAD_ERROR \ { \ dlclose(libraryHandle); \ initState = FF_INITSTATE_FAILED; \ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return NULL; \ } diff --git a/src/common/thread.h b/src/common/thread.h new file mode 100644 index 000000000..3c80f84fd --- /dev/null +++ b/src/common/thread.h @@ -0,0 +1,43 @@ +#pragma once + +#ifndef FF_INCLUDED_common_thread +#define FF_INCLUDED_common_thread + +#include "fastfetch.h" + +#ifdef FF_HAVE_THREADS + #if defined(_WIN32) + #include + #include + #include // Win32 isn't available on MSYS2 + #define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT + typedef SRWLOCK FFThreadMutex; + static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); } + static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); } + static inline void ffThreadCreateAndDetach(__stdcall unsigned (* func)(void*), void* data) { + uintptr_t newThread = _beginthreadex(func, 0, data, NULL, 0, NULL); + if(newThread != 0) + CloseHandle((HANDLE)newThread); + } + #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; } + #else + #include + #define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + typedef pthread_mutex_t FFThreadMutex; + static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); } + static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); } + static inline void ffThreadCreateAndDetach(void* (* func)(void*), void* data) { + pthread_t newThread; + if(pthread_create(&newThread, NULL, func, data) == 0) + pthread_detach(newThread); + } + #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; } + #endif +#else //FF_HAVE_THREADS + #define FF_THREAD_MUTEX_INITIALIZER 0 + typedef char FFThreadMutex; + static inline void ffThreadMutexLock(FFThreadMutex* mutex) { FF_UNUSED(mutex) } + static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) } +#endif //FF_HAVE_THREADS + +#endif diff --git a/src/detection/datetime.c b/src/detection/datetime.c index 9c5ebf414..20b8ec367 100644 --- a/src/detection/datetime.c +++ b/src/detection/datetime.c @@ -1,21 +1,21 @@ #include "fastfetch.h" #include "detection/datetime.h" +#include "common/thread.h" #include -#include const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance) { FF_UNUSED(instance); //We may need it later for additional configuration static FFDateTimeResult result; - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static bool init = false; - pthread_mutex_lock(&mutex); + ffThreadMutexLock(&mutex); if (init) { - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } init = true; @@ -68,6 +68,6 @@ const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance) ffStrbufInitA(&result.secondPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC); result.secondPretty.length = (uint32_t) strftime(result.secondPretty.chars, ffStrbufGetFree(&result.secondPretty), "%S", tm); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } diff --git a/src/detection/displayserver/linux/wayland.c b/src/detection/displayserver/linux/wayland.c index 39743282c..166ec25b2 100644 --- a/src/detection/displayserver/linux/wayland.c +++ b/src/detection/displayserver/linux/wayland.c @@ -6,7 +6,7 @@ #ifdef FF_HAVE_WAYLAND #include "common/library.h" #include "common/io.h" -#include +#include "common/thread.h" #include #include @@ -56,12 +56,12 @@ static void waylandOutputModeListener(void* data, struct wl_output* output, uint if(!(flags & WL_OUTPUT_MODE_CURRENT) || width <= 0 || height <= 0) return; - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock(&mutex); + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; + ffThreadMutexLock(&mutex); FFResolutionResult* result = ffListAdd(wldata->results); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); result->width = (uint32_t) width; result->height = (uint32_t) height; diff --git a/src/detection/gtk.c b/src/detection/gtk.c index 3855f7990..ad24c9c4e 100644 --- a/src/detection/gtk.c +++ b/src/detection/gtk.c @@ -1,11 +1,10 @@ #include "fastfetch.h" #include "detection/gtk.h" #include "common/properties.h" +#include "common/thread.h" #include "common/settings.h" #include "detection/displayserver/displayserver.h" -#include - static inline bool allPropertiesSet(FFGTKResult* result) { return @@ -34,7 +33,7 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName, static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* result) { - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static const char* themeName = NULL; static const char* iconsName = NULL; @@ -44,11 +43,11 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul static bool init = false; - pthread_mutex_lock(&mutex); + ffThreadMutexLock(&mutex); if(init) { - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize); return; } @@ -90,7 +89,7 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul cursorSize = ffSettingsGet(instance, "/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue; } - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize); } @@ -168,12 +167,12 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu } #define FF_DETECT_GTK_IMPL(version) \ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \ + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \ static FFGTKResult result; \ static bool init = false; \ - pthread_mutex_lock(&mutex); \ + ffThreadMutexLock(&mutex); \ if(init){ \ - pthread_mutex_unlock(&mutex);\ + ffThreadMutexUnlock(&mutex);\ return &result; \ } \ init = true; \ @@ -183,7 +182,7 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu ffStrbufInit(&result.cursor); \ ffStrbufInit(&result.cursorSize); \ detectGTK(instance, #version, &result); \ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return &result; const FFGTKResult* ffDetectGTK2(const FFinstance* instance) diff --git a/src/detection/internal.h b/src/detection/internal.h index f4dc67cbb..11b081f7e 100644 --- a/src/detection/internal.h +++ b/src/detection/internal.h @@ -3,21 +3,21 @@ #ifndef FF_INCLUDED_detection_internal #define FF_INCLUDED_detection_internal -#include "pthread.h" +#include "common/thread.h" #define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \ + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \ static ResultType result; \ static bool init = false; \ - pthread_mutex_lock(&mutex); \ + ffThreadMutexLock(&mutex); \ if(init) \ { \ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return &result; \ } \ init = true; \ __VA_ARGS__; \ - pthread_mutex_unlock(&mutex); \ + ffThreadMutexUnlock(&mutex); \ return &result; \ #endif diff --git a/src/detection/media/media_linux.c b/src/detection/media/media_linux.c index 77ecbc3a9..60b407b99 100644 --- a/src/detection/media/media_linux.c +++ b/src/detection/media/media_linux.c @@ -1,8 +1,8 @@ #include "fastfetch.h" #include "detection/media/media.h" +#include "common/thread.h" #include -#include #define FF_DBUS_MPRIS_PREFIX "org.mpris.MediaPlayer2." #define FF_DBUS_TIMEOUT_MILLISECONDS 35 diff --git a/src/detection/qt.c b/src/detection/qt.c index 5bd9b2403..6a7794c8e 100644 --- a/src/detection/qt.c +++ b/src/detection/qt.c @@ -1,11 +1,11 @@ #include "fastfetch.h" #include "detection/qt.h" #include "common/properties.h" +#include "common/thread.h" #include "detection/displayserver/displayserver.h" #include #include -#include static inline bool allValuesSet(const FFQtResult* result) { @@ -135,12 +135,12 @@ const FFQtResult* ffDetectQt(const FFinstance* instance) { static FFQtResult result; - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static bool init = false; - pthread_mutex_lock(&mutex); + ffThreadMutexLock(&mutex); if(init) { - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } init = true; @@ -157,6 +157,6 @@ const FFQtResult* ffDetectQt(const FFinstance* instance) else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "LXQt") == 0) detectLXQt(instance, &result); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } diff --git a/src/detection/temps/temps_linux.c b/src/detection/temps/temps_linux.c index 5fad783d5..cb342a9f8 100644 --- a/src/detection/temps/temps_linux.c +++ b/src/detection/temps/temps_linux.c @@ -1,9 +1,9 @@ #include "fastfetch.h" #include "common/io.h" +#include "common/thread.h" #include "temps_linux.h" #include -#include #include static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value) @@ -38,13 +38,13 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value) const FFTempsResult* ffDetectTemps(const FFinstance* instance) { static FFTempsResult result; - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static bool init = false; - pthread_mutex_lock(&mutex); + ffThreadMutexLock(&mutex); if(init) { - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } init = true; @@ -52,7 +52,7 @@ const FFTempsResult* ffDetectTemps(const FFinstance* instance) if(!instance->config.allowSlowOperations) { ffListInitA(&result.values, sizeof(FFTempValue), 0); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } @@ -68,7 +68,7 @@ const FFTempsResult* ffDetectTemps(const FFinstance* instance) if(dirp == NULL) { ffStrbufDestroy(&baseDir); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } @@ -97,6 +97,6 @@ const FFTempsResult* ffDetectTemps(const FFinstance* instance) closedir(dirp); ffStrbufDestroy(&baseDir); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index b5f68c58f..534c343c7 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -3,13 +3,13 @@ #include "common/io.h" #include "common/parsing.h" #include "common/processing.h" +#include "common/thread.h" #include "terminalshell.h" #include #include #include #include -#include #ifdef __APPLE__ #include @@ -318,13 +318,13 @@ const FFTerminalShellResult* { FF_UNUSED(instance); - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static FFTerminalShellResult result; static bool init = false; - pthread_mutex_lock(&mutex); + ffThreadMutexLock(&mutex); if(init) { - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } init = true; @@ -361,6 +361,6 @@ const FFTerminalShellResult* else ffStrbufInitCopy(&result.terminalPrettyName, &result.terminalProcessName); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } diff --git a/src/detection/title.c b/src/detection/title.c index b4394be15..50482977f 100644 --- a/src/detection/title.c +++ b/src/detection/title.c @@ -1,9 +1,9 @@ #include "fastfetch.h" #include "detection/title.h" +#include "common/thread.h" #include #include -#include #include #ifndef HOST_NAME_MAX @@ -37,12 +37,12 @@ const FFTitleResult* ffDetectTitle(const FFinstance* instance) { static FFTitleResult result; - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static bool init = false; - pthread_mutex_lock(&mutex); + ffThreadMutexLock(&mutex); if(init) { - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } init = true; @@ -60,6 +60,6 @@ const FFTitleResult* ffDetectTitle(const FFinstance* instance) if(result.fqdn.length == 0) ffStrbufAppend(&result.fqdn, &result.hostname); - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 1ff96e2c9..9c348b74b 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -1,9 +1,8 @@ #include "fastfetch.h" +#include "common/thread.h" #include "detection/vulkan.h" #include "detection/gpu/gpu.h" -#include - #ifdef FF_HAVE_VULKAN #include "common/library.h" #include "common/io.h" @@ -217,13 +216,13 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu const FFVulkanResult* ffDetectVulkan(const FFinstance* instance) { static FFVulkanResult result; - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static bool init = false; - pthread_mutex_lock(&mutex); + ffThreadMutexLock(&mutex); if(init) { - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } init = true; @@ -240,6 +239,6 @@ const FFVulkanResult* ffDetectVulkan(const FFinstance* instance) result.error = "fastfetch was compiled without vulkan support"; #endif - pthread_mutex_unlock(&mutex); + ffThreadMutexUnlock(&mutex); return &result; } From dfed3812ceeeadf728ed9ae9ec3fb59377dd2300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 17:53:11 +0800 Subject: [PATCH 060/311] Title: don't include unnecessary headers --- src/detection/title.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/detection/title.c b/src/detection/title.c index 50482977f..df9367ba0 100644 --- a/src/detection/title.c +++ b/src/detection/title.c @@ -4,13 +4,14 @@ #include #include -#include #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 64 #endif #ifdef __linux__ +#include + static void detectFQDN(FFTitleResult* title) { struct addrinfo hints = {0}; @@ -54,7 +55,7 @@ const FFTitleResult* ffDetectTitle(const FFinstance* instance) ffStrbufAppendS(&result.hostname, instance->state.utsname.nodename); ffStrbufInitA(&result.fqdn, HOST_NAME_MAX); - #ifdef __linux + #ifdef __linux__ detectFQDN(&result); #endif if(result.fqdn.length == 0) From b64a234f8a4cd1d8a3b4ab81c26050529b513f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 19:35:23 +0800 Subject: [PATCH 061/311] Networking: support Windows --- CMakeLists.txt | 1 + src/common/networking.c | 66 ++++++++++++++++++++++++++++++----------- src/common/networking.h | 14 +++++++-- src/modules/publicip.c | 4 +-- src/modules/weather.c | 4 +-- 5 files changed, 65 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41aaabaaf..ea760f60c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -516,6 +516,7 @@ elseif(MSYS) PRIVATE "opengl32" PRIVATE "gdi32" PRIVATE "iphlpapi" + PRIVATE "ws2_32" ) endif() diff --git a/src/common/networking.c b/src/common/networking.c index 4558f7f8e..d3685a543 100644 --- a/src/common/networking.c +++ b/src/common/networking.c @@ -1,13 +1,43 @@ +#if defined(_WIN32) || defined(__MSYS__) + #include + #include + #include + + static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context) + { + (void)once; + (void)param; + static WSADATA wsaData; + *context = &wsaData; + return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0; + } + + //Types of winsock2 are full of mess. Disable warnings for them and keep clean for posix + #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" + #pragma GCC diagnostic ignored "-Wconversion" + #pragma GCC diagnostic ignored "-Wsign-conversion" +#else + #include + #include + #include + #include + + #define closesocket close +#endif + +//Must be included after #include "fastfetch.h" #include "common/networking.h" -#include -#include -#include -#include - -int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout) +FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout) { + #if defined(_WIN32) || defined(__MSYS__) + static INIT_ONCE once = INIT_ONCE_STATIC_INIT; + WSADATA* pData; + if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData)) + return INVALID_SOCKET; + #endif + struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, @@ -16,13 +46,13 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* struct addrinfo* addr; if(getaddrinfo(host, "80", &hints, &addr) != 0) - return -1; + return INVALID_SOCKET; - int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if(sockfd == -1) + FFSockType sockfd = (FFSockType)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if(sockfd == INVALID_SOCKET) { freeaddrinfo(addr); - return -1; + return INVALID_SOCKET; } if(timeout > 0) @@ -35,9 +65,9 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1) { - close(sockfd); + closesocket(sockfd); freeaddrinfo(addr); - return -1; + return INVALID_SOCKET; } freeaddrinfo(addr); @@ -55,14 +85,14 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* if(send(sockfd, command.chars, command.length, 0) == -1) { ffStrbufDestroy(&command); - close(sockfd); - return -1; + closesocket(sockfd); + return INVALID_SOCKET; } ffStrbufDestroy(&command); return sockfd; } -bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer) +bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer) { ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0); @@ -72,14 +102,14 @@ bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer) buffer->chars[buffer->length] = '\0'; } - close(sockfd); + closesocket(sockfd); return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n"); } bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer) { - int sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout); - if(sockfd > 0) + FFSockType sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout); + if(sockfd != INVALID_SOCKET) return ffNetworkingRecvHttpResponse(sockfd, buffer); return false; } diff --git a/src/common/networking.h b/src/common/networking.h index 145493ce7..f64288066 100644 --- a/src/common/networking.h +++ b/src/common/networking.h @@ -5,8 +5,18 @@ #include "util/FFstrbuf.h" -int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout); -bool ffNetworkingRecvHttpResponse(int sock, FFstrbuf* buffer); +#if defined(_WIN32) || defined(__MSYS__) + typedef uintptr_t FFSockType; //SOCKET, unsigned + #ifndef INVALID_SOCKET //Don't conflict with + #define INVALID_SOCKET ((uintptr_t)~0) + #endif +#else + typedef int FFSockType; // signed + #define INVALID_SOCKET (-1) +#endif + +FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout); +bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer); bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer); #endif diff --git a/src/modules/publicip.c b/src/modules/publicip.c index fe77e30f6..019f13dfb 100644 --- a/src/modules/publicip.c +++ b/src/modules/publicip.c @@ -5,7 +5,7 @@ #define FF_PUBLICIP_MODULE_NAME "Public IP" #define FF_PUBLICIP_NUM_FORMAT_ARGS 1 -static int sockfd; +static FFSockType sockfd; void ffPreparePublicIp(FFinstance* instance) { @@ -39,7 +39,7 @@ void ffPrintPublicIp(FFinstance* instance) if(sockfd == 0) ffPreparePublicIp(instance); - if(sockfd < 0) + if(sockfd == INVALID_SOCKET) { ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to connect to an IP detection server"); return; diff --git a/src/modules/weather.c b/src/modules/weather.c index 43c1d56fd..11dc9748e 100644 --- a/src/modules/weather.c +++ b/src/modules/weather.c @@ -5,7 +5,7 @@ #define FF_WEATHER_MODULE_NAME "Weather" #define FF_WEATHER_NUM_FORMAT_ARGS 1 -static int sockfd; +static FFSockType sockfd; void ffPrepareWeather(FFinstance* instance) { @@ -21,7 +21,7 @@ void ffPrintWeather(FFinstance* instance) if(sockfd == 0) ffPrepareWeather(instance); - if(sockfd < 0) + if(sockfd == INVALID_SOCKET) { ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to connect to 'wttr.in'"); return; From 06262c078dad07e2640bd7217ad6995f02e35a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Oct 2022 20:40:38 +0800 Subject: [PATCH 062/311] TerminaFont: move windows specific code into its own file --- CMakeLists.txt | 2 +- src/common/properties.h | 2 +- src/detection/terminalfont/terminalfont.c | 187 +++++++++++++ .../terminalfont/terminalfont_linux.c | 263 ------------------ .../terminalfont/terminalfont_windows.c | 82 ++++++ 5 files changed, 271 insertions(+), 265 deletions(-) create mode 100644 src/detection/terminalfont/terminalfont_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ea760f60c..1eac66074 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -365,8 +365,8 @@ if(MSYS) src/detection/font/font_windows.cpp src/detection/terminalshell/terminalshell_linux.c src/detection/terminalshell/terminalshell_windows.cpp - src/detection/terminalfont/terminalfont_linux.c src/detection/packages/packages_linux.c + src/detection/terminalfont/terminalfont_windows.c src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp src/detection/localip/localip_windows.c diff --git a/src/common/properties.h b/src/common/properties.h index 38d79c2ec..dfdcad96e 100644 --- a/src/common/properties.h +++ b/src/common/properties.h @@ -3,7 +3,7 @@ #ifndef FF_INCLUDED_common_properties #define FF_INCLUDED_common_properties -#include "util/FFstrbuf.h" +#include "fastfetch.h" typedef struct FFpropquery { diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 297301f2f..c79ed7827 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -64,6 +64,185 @@ static void detectTTY(FFTerminalFontResult* terminalFont) ffStrbufDestroy(&fontName); } +#if defined(_WIN32) || defined(__MSYS__) || defined(__linux__) +#ifdef FF_HAVE_LIBCJSON + +#include "common/library.h" +#include "common/processing.h" + +#include +#include + +typedef struct CJSONData +{ + FF_LIBRARY_SYMBOL(cJSON_Parse) + FF_LIBRARY_SYMBOL(cJSON_IsObject) + FF_LIBRARY_SYMBOL(cJSON_GetObjectItemCaseSensitive) + FF_LIBRARY_SYMBOL(cJSON_IsString) + FF_LIBRARY_SYMBOL(cJSON_GetStringValue) + FF_LIBRARY_SYMBOL(cJSON_IsNumber) + FF_LIBRARY_SYMBOL(cJSON_GetNumberValue) + FF_LIBRARY_SYMBOL(cJSON_IsArray) + FF_LIBRARY_SYMBOL(cJSON_Delete) +} CJSONData; + +static const char* detectWTProfile(CJSONData* cjsonData, cJSON* profile, FFstrbuf* name, int* size) +{ + if(!cjsonData->ffcJSON_IsObject(profile)) + return "cJSON_IsObject(profile) returns false"; + + cJSON* font = cjsonData->ffcJSON_GetObjectItemCaseSensitive(profile, "font"); + if(!cjsonData->ffcJSON_IsObject(font)) + return "cJSON_IsObject(font) returns false"; + + if(name->length == 0) + { + cJSON* pface = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "face"); + if(cjsonData->ffcJSON_IsString(pface)) + ffStrbufAppendS(name, cjsonData->ffcJSON_GetStringValue(pface)); + } + if(*size < 0) + { + cJSON* psize = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "size"); + if(cjsonData->ffcJSON_IsNumber(psize)) + *size = (int)cjsonData->ffcJSON_GetNumberValue(psize); + } + return NULL; +} + +static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* content, FFstrbuf* name, int* size) +{ + CJSONData cjsonData; + + FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson"FF_LIBRARY_EXTENSION" failed", "libcjson"FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Parse) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsObject) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsString) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetStringValue) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsNumber) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetNumberValue) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsArray) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Delete) + + const char* error = NULL; + + cJSON* root = cjsonData.ffcJSON_Parse(content->chars); + if(!cjsonData.ffcJSON_IsObject(root)) + { + error = "cJSON_Parse() failed"; + goto exit; + } + + cJSON* profiles = cjsonData.ffcJSON_GetObjectItemCaseSensitive(root, "profiles"); + if(!cjsonData.ffcJSON_IsObject(profiles)) + { + error = "cJSON_GetObjectItemCaseSensitive(root, \"profiles\") failed"; + goto exit; + } + + FFstrbuf wtProfileId; + ffStrbufInitS(&wtProfileId, getenv("WT_PROFILE_ID")); + ffStrbufTrim(&wtProfileId, '\''); + if(wtProfileId.length > 0) + { + cJSON* list = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "list"); + if(cjsonData.ffcJSON_IsArray(list)) + { + cJSON* profile; + cJSON_ArrayForEach(profile, list) + { + if(!cjsonData.ffcJSON_IsObject(profile)) + continue; + cJSON* guid = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profile, "guid"); + if(!cjsonData.ffcJSON_IsString(guid)) + continue; + if(ffStrbufCompS(&wtProfileId, cjsonData.ffcJSON_GetStringValue(guid)) == 0) + { + detectWTProfile(&cjsonData, profile, name, size); + break; + } + } + } + } + ffStrbufDestroy(&wtProfileId); + + cJSON* defaults = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "defaults"); + detectWTProfile(&cjsonData, defaults, name, size); + + if(name->length == 0) + ffStrbufSetS(name, "Cascadia Mono"); + if(*size < 0) + *size = 12; + +exit: + cjsonData.ffcJSON_Delete(root); + dlclose(libcjson); + return error; +} + +static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + //https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file + FFstrbuf json; + ffStrbufInit(&json); + const char* error; + error = ffProcessAppendStdOut(&json, (char* const[]) { + "cmd.exe", + "/c", + //print the file content directly, so we don't need to handle the difference of Windows and POSIX path + "if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json " + "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json ) " + "else if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json " + "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json ) " + "else if exist \"%LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json\" " + "( type %LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json ) " + "else ( call )", + NULL + }); + if(error) + { + ffStrbufAppendS(&terminalFont->error, error); + ffStrbufDestroy(&json); + return; + } + ffStrbufTrimRight(&json, '\n'); + if(json.length == 0) + { + ffStrbufAppendS(&terminalFont->error, "Cannot find file \"settings.json\""); + ffStrbufDestroy(&json); + return; + } + + FFstrbuf name; + ffStrbufInit(&name); + int size = -1; + error = detectFromWTImpl(instance, &json, &name, &size); + ffStrbufDestroy(&json); + + if(error) + ffStrbufAppendS(&terminalFont->error, error); + else + { + char sizeStr[16]; + snprintf(sizeStr, sizeof(sizeStr), "%d", size); + ffFontInitValues(&terminalFont->font, name.chars, sizeStr); + } + + ffStrbufDestroy(&name); +} + +#else + +static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + FF_UNUSED(instance, terminalFont); + ffStrbufAppendS(&terminalFont->error, "fastfetch is built without libcjson support"); +} + +#endif +#endif //defined(_WIN32) || defined(__MSYS__) || defined(__linux__) + void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) @@ -79,6 +258,14 @@ const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) detectAlacritty(instance, &result); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) detectTTY(&result); + + #if defined(_WIN32) || defined(__MSYS__) || defined(__linux__) + //Used by both Linux (WSL) and Windows + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || + ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) + detectFromWindowsTeriminal(instance, &result); + #endif + else ffDetectTerminalFontPlatform(instance, terminalShell, &result); diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 06a71da50..e63ccd815 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -140,259 +140,6 @@ static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* ffStrbufDestroy(&useSysFont); } -#ifdef FF_HAVE_LIBCJSON - -#include "common/library.h" -#include "common/processing.h" - -#include -#include - -typedef struct CJSONData -{ - FF_LIBRARY_SYMBOL(cJSON_Parse) - FF_LIBRARY_SYMBOL(cJSON_IsObject) - FF_LIBRARY_SYMBOL(cJSON_GetObjectItemCaseSensitive) - FF_LIBRARY_SYMBOL(cJSON_IsString) - FF_LIBRARY_SYMBOL(cJSON_GetStringValue) - FF_LIBRARY_SYMBOL(cJSON_IsNumber) - FF_LIBRARY_SYMBOL(cJSON_GetNumberValue) - FF_LIBRARY_SYMBOL(cJSON_IsArray) - FF_LIBRARY_SYMBOL(cJSON_Delete) -} CJSONData; - -static const char* detectWTProfile(CJSONData* cjsonData, cJSON* profile, FFstrbuf* name, int* size) -{ - if(!cjsonData->ffcJSON_IsObject(profile)) - return "cJSON_IsObject(profile) returns false"; - - cJSON* font = cjsonData->ffcJSON_GetObjectItemCaseSensitive(profile, "font"); - if(!cjsonData->ffcJSON_IsObject(font)) - return "cJSON_IsObject(font) returns false"; - - if(name->length == 0) - { - cJSON* pface = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "face"); - if(cjsonData->ffcJSON_IsString(pface)) - ffStrbufAppendS(name, cjsonData->ffcJSON_GetStringValue(pface)); - } - if(*size < 0) - { - cJSON* psize = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "size"); - if(cjsonData->ffcJSON_IsNumber(psize)) - *size = (int)cjsonData->ffcJSON_GetNumberValue(psize); - } - return NULL; -} - -static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* content, FFstrbuf* name, int* size) -{ - CJSONData cjsonData; - - FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson"FF_LIBRARY_EXTENSION" failed", "libcjson"FF_LIBRARY_EXTENSION, 1) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Parse) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsObject) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsString) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetStringValue) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsNumber) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetNumberValue) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsArray) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Delete) - - const char* error = NULL; - - cJSON* root = cjsonData.ffcJSON_Parse(content->chars); - if(!cjsonData.ffcJSON_IsObject(root)) - { - error = "cJSON_Parse() failed"; - goto exit; - } - - cJSON* profiles = cjsonData.ffcJSON_GetObjectItemCaseSensitive(root, "profiles"); - if(!cjsonData.ffcJSON_IsObject(profiles)) - { - error = "cJSON_GetObjectItemCaseSensitive(root, \"profiles\") failed"; - goto exit; - } - - FFstrbuf wtProfileId; - ffStrbufInitS(&wtProfileId, getenv("WT_PROFILE_ID")); - ffStrbufTrim(&wtProfileId, '\''); - if(wtProfileId.length > 0) - { - cJSON* list = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "list"); - if(cjsonData.ffcJSON_IsArray(list)) - { - cJSON* profile; - cJSON_ArrayForEach(profile, list) - { - if(!cjsonData.ffcJSON_IsObject(profile)) - continue; - cJSON* guid = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profile, "guid"); - if(!cjsonData.ffcJSON_IsString(guid)) - continue; - if(ffStrbufCompS(&wtProfileId, cjsonData.ffcJSON_GetStringValue(guid)) == 0) - { - detectWTProfile(&cjsonData, profile, name, size); - break; - } - } - } - } - ffStrbufDestroy(&wtProfileId); - - cJSON* defaults = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "defaults"); - detectWTProfile(&cjsonData, defaults, name, size); - - if(name->length == 0) - ffStrbufSetS(name, "Cascadia Mono"); - if(*size < 0) - *size = 12; - -exit: - cjsonData.ffcJSON_Delete(root); - dlclose(libcjson); - return error; -} - -static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) -{ - //https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file - FFstrbuf json; - ffStrbufInit(&json); - const char* error; - error = ffProcessAppendStdOut(&json, (char* const[]) { - "cmd.exe", - "/c", - //print the file content directly, so we don't need to handle the difference of Windows and POSIX path - "if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json " - "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json ) " - "else if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json " - "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json ) " - "else if exist \"%LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json\" " - "( type %LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json ) " - "else ( call )", - NULL - }); - if(error) - { - ffStrbufAppendS(&terminalFont->error, error); - ffStrbufDestroy(&json); - return; - } - ffStrbufTrimRight(&json, '\n'); - if(json.length == 0) - { - ffStrbufAppendS(&terminalFont->error, "Cannot find file \"settings.json\""); - ffStrbufDestroy(&json); - return; - } - - FFstrbuf name; - ffStrbufInit(&name); - int size = -1; - error = detectFromWTImpl(instance, &json, &name, &size); - ffStrbufDestroy(&json); - - if(error) - ffStrbufAppendS(&terminalFont->error, error); - else - { - char sizeStr[16]; - snprintf(sizeStr, sizeof(sizeStr), "%d", size); - ffFontInitValues(&terminalFont->font, name.chars, sizeStr); - } - - ffStrbufDestroy(&name); -} - -#else - -static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) -{ - FF_UNUSED(instance, terminalFont); - ffStrbufAppendS(&terminalFont->error, "fastfetch is built without libcjson support"); -} - -#endif - -#if defined(_WIN32) || defined(__MSYS__) -// TODO: move to a separate file - -static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) -{ - FFstrbuf fontName; - ffStrbufInit(&fontName); - - FFstrbuf fontSize; - ffStrbufInit(&fontSize); - - ffParsePropFileHomeValues(instance, ".minttyrc", 2, (FFpropquery[]) { - {"Font=", &fontName}, - {"FontHeight=", &fontSize} - }); - if(fontName.length == 0) - ffStrbufAppendS(&fontName, "Lucida Console"); - if(fontSize.length == 0) - ffStrbufAppendC(&fontSize, '9'); - - ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); -} - -#define WIN32_LEAN_AND_MEAN 1 -#include - -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 hKey; - if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS) - { - ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed"); - return; - } - - DWORD bufSize; - - wchar_t fontNameW[64]; - bufSize = sizeof(fontNameW); - if(RegQueryValueExW(hKey, L"FaceName", NULL, NULL, (LPBYTE)fontNameW, &bufSize) != ERROR_SUCCESS) - { - ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(FaceName) failed"); - goto exit; - } - 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) - { - ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(fontSize) failed"); - goto exit; - } - - char fontSize[16]; - snprintf(fontSize, sizeof(fontSize), "%u", (fontSizeNum >> 16)); - - ffFontInitValues(&terminalFont->font, fontNameA, fontSize); - -exit: - RegCloseKey(hKey); -} - -#endif //defined(_WIN32) || defined(__MSYS__) - void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0) @@ -405,14 +152,4 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "gnome-terminal-") == 0) detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", terminalFont); - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || - ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) - detectFromWindowsTeriminal(instance, terminalFont); - - #if defined(_WIN32) || defined(__MSYS__) - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0) - detectMintty(instance, terminalFont); - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0) - detectConhost(instance, terminalFont); - #endif } diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c new file mode 100644 index 000000000..6a68bb6a5 --- /dev/null +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -0,0 +1,82 @@ +#include "common/properties.h" +#include "detection/terminalshell/terminalshell.h" +#include "terminalfont.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + FFstrbuf fontName; + ffStrbufInit(&fontName); + + FFstrbuf fontSize; + ffStrbufInit(&fontSize); + + ffParsePropFileHomeValues(instance, ".minttyrc", 2, (FFpropquery[]) { + {"Font=", &fontName}, + {"FontHeight=", &fontSize} + }); + if(fontName.length == 0) + ffStrbufAppendS(&fontName, "Lucida Console"); + if(fontSize.length == 0) + ffStrbufAppendC(&fontSize, '9'); + + ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&fontSize); +} + +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 hKey; + if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS) + { + ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed"); + return; + } + + DWORD bufSize; + + wchar_t fontNameW[64]; + bufSize = sizeof(fontNameW); + if(RegQueryValueExW(hKey, L"FaceName", NULL, NULL, (LPBYTE)fontNameW, &bufSize) != ERROR_SUCCESS) + { + ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(FaceName) failed"); + goto exit; + } + 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) + { + ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(fontSize) failed"); + goto exit; + } + + char fontSize[16]; + snprintf(fontSize, sizeof(fontSize), "%u", (fontSizeNum >> 16)); + + ffFontInitValues(&terminalFont->font, fontNameA, fontSize); + +exit: + RegCloseKey(hKey); +} + +void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +{ + if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0) + detectMintty(instance, terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0) + detectConhost(instance, terminalFont); +} From 2c82c9a6dcf4d9a3ba2f14d9f8b36a50f750b21b Mon Sep 17 00:00:00 2001 From: Edward Piper Date: Wed, 12 Oct 2022 10:26:38 -0700 Subject: [PATCH 063/311] Fixed Alpine, EndeavourOS, Rocky, and Rosa logos --- src/logo/builtin.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 285cfb8c7..86376c7fa 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -87,7 +87,7 @@ static const FFlogo* getLogoAlpine() " +dddddddddddddddddddddddddddddd+\n" " `sdddddddddddddddddddddddddddddddds`\n" " `ydddddddddddd++hdddddddddddddddddddy`\n" - ".hddddddddddd+` `+ddddh:-sdddddddddddh. \n" + ".hddddddddddd+` `+ddddh:-sdddddddddddh.\n" "hdddddddddd+` `+y: .sddddddddddh\n" "ddddddddh+` `//` `.` -sddddddddd\n" "ddddddh+` `/hddh/` `:s- -sddddddd\n" @@ -699,8 +699,8 @@ static const FFlogo* getLogoEndeavour() " $2`:////$1ssssssssssssssssssssssssssso$3+++.\n" "$2`-////+$1ssssssssssssssssssssssssssso$3++++-\n" " $2`..-+$1oosssssssssssssssssssssssso$3+++++/`\n" - "$3./++++++++++++++++++++++++++++++/:.\n" - "`:::::::::::::::::::::::::------``" + " $3./++++++++++++++++++++++++++++++/:.\n" + " `:::::::::::::::::::::::::------``" ) FF_LOGO_COLORS( "35", //magenta @@ -1779,7 +1779,7 @@ static const FFlogo* getLogoRockyLinux() "jliililiiilililiiili@` ~ililiiiiiL\n" "iiiliiiiliiiiiiili>` ~liililii\n" "liliiiliiilililii` -9liiiil\n" - "iiiiiliiliiiiii~ ''4lili\n" + "iiiiiliiliiiiii~ \"4lili\n" "4ililiiiiilil~| -w, )4lf\n" "-liiiiililiF' _liig, )'\n" " )iiiliii@` _QIililig,\n" @@ -1802,7 +1802,7 @@ static const FFlogo* getLogoRosaLinux() FF_LOGO_INIT FF_LOGO_NAMES("rosa", "rosa-linux", "rosalinux") FF_LOGO_LINES( - " ROSAROSAROSAROSAR\n" + " ROSAROSAROSAROSAR\n" " ROSA AROS\n" " ROS SAROSAROSAROSAR AROS\n" " RO ROSAROSAROSAROSAROSAR RO\n" From 2689a20889e3fb8c7c54aa79a8a5f5ef43953048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 10:39:11 +0800 Subject: [PATCH 064/311] Uptime: support Windows --- CMakeLists.txt | 3 +++ src/detection/uptime/uptime.h | 10 ++++++++++ src/detection/uptime/uptime_apple.c | 19 +++++++++++++++++++ src/detection/uptime/uptime_linux.c | 11 +++++++++++ src/detection/uptime/uptime_windows.c | 10 ++++++++++ src/modules/uptime.c | 25 ++----------------------- 6 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 src/detection/uptime/uptime.h create mode 100644 src/detection/uptime/uptime_apple.c create mode 100644 src/detection/uptime/uptime_linux.c create mode 100644 src/detection/uptime/uptime_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eac66074..2a3117707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -316,6 +316,7 @@ if(LINUX OR ANDROID OR BSD) src/detection/temps/temps_linux.c src/detection/opengl/opengl_linux.c src/detection/processes/processes_linux.c + src/detection/uptime/uptime_linux.c src/detection/poweradapter/poweradapter_nosupport.c ) @@ -370,6 +371,7 @@ if(MSYS) src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp src/detection/localip/localip_windows.c + src/detection/uptime/uptime_windows.c src/util/windows/wmi.cpp src/detection/poweradapter/poweradapter_nosupport.c @@ -398,6 +400,7 @@ if(APPLE) src/detection/font/font_apple.m src/detection/opengl/opengl_apple.c src/detection/processes/processes_apple.c + src/detection/uptime/uptime_apple.c src/detection/bios/bios_nosupport.c src/detection/board/board_nosupport.c diff --git a/src/detection/uptime/uptime.h b/src/detection/uptime/uptime.h new file mode 100644 index 000000000..a44d4cecc --- /dev/null +++ b/src/detection/uptime/uptime.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_uptime_uptime +#define FF_INCLUDED_detection_uptime_uptime + +#include "fastfetch.h" + +uint64_t ffDetectUptime(const FFinstance* instance); + +#endif diff --git a/src/detection/uptime/uptime_apple.c b/src/detection/uptime/uptime_apple.c new file mode 100644 index 000000000..c32496ef3 --- /dev/null +++ b/src/detection/uptime/uptime_apple.c @@ -0,0 +1,19 @@ +#include "uptime.h" + +#include +#include + +uint64_t ffDetectUptime(const FFinstance* instance) +{ + FF_UNUSED(instance) + struct timeval bootTime; + size_t bootTimeSize = sizeof(bootTime); + if(sysctl( + (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, + &bootTime, &bootTimeSize, + NULL, 0 + ) == 0) + return (uint64_t) difftime(time(NULL), bootTime.tv_sec); + + return 0; +} diff --git a/src/detection/uptime/uptime_linux.c b/src/detection/uptime/uptime_linux.c new file mode 100644 index 000000000..e58fa6505 --- /dev/null +++ b/src/detection/uptime/uptime_linux.c @@ -0,0 +1,11 @@ +#include "uptime.h" + +uint64_t ffDetectUptime(const FFinstance* instance) +{ + #if FF_HAVE_SYSINFO_H + return (uint64_t) instance->state.sysinfo.uptime; + #else + FF_UNUSED(instance) + return 0; + #endif +} diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c new file mode 100644 index 000000000..8909ad596 --- /dev/null +++ b/src/detection/uptime/uptime_windows.c @@ -0,0 +1,10 @@ +#include "uptime.h" + +#define WIN32_LEAN_AND_MEAN +#include + +uint64_t ffDetectUptime(const FFinstance* instance) +{ + FF_UNUSED(instance) + return GetTickCount64() / 1000; +} diff --git a/src/modules/uptime.c b/src/modules/uptime.c index 9cbd9f9f8..cf371778d 100644 --- a/src/modules/uptime.c +++ b/src/modules/uptime.c @@ -1,34 +1,13 @@ #include "fastfetch.h" #include "common/printing.h" - -#if __APPLE__ - #include "time.h" - #include "sys/sysctl.h" -#endif +#include "detection/uptime/uptime.h" #define FF_UPTIME_MODULE_NAME "Uptime" #define FF_UPTIME_NUM_FORMAT_ARGS 4 void ffPrintUptime(FFinstance* instance) { - uint64_t uptime; - - #if FF_HAVE_SYSINFO_H - uptime = (uint64_t) instance->state.sysinfo.uptime; - #elif __APPLE__ - struct timeval bootTime; - size_t bootTimeSize = sizeof(bootTime); - if(sysctl( - (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, - &bootTime, &bootTimeSize, - NULL, 0 - ) == 0) - uptime = (uint64_t) difftime(time(NULL), bootTime.tv_sec); - else - uptime = 0; - #else - uptime = 0; - #endif + uint64_t uptime = ffDetectUptime(instance); if(uptime == 0) { From b33e042cd43542d2f383c1686068760b8a66633d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 17:00:36 +0800 Subject: [PATCH 065/311] Library: support Windows --- src/common/library.c | 10 ++++++---- src/common/library.h | 13 ++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/common/library.c b/src/common/library.c index c131a3862..554cc9f39 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -10,10 +10,12 @@ #endif #endif -#ifdef __SANITIZE_ADDRESS__ - #define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE -#else - #define FF_DLOPEN_FLAGS RTLD_LAZY +#ifndef FF_DLOPEN_FLAGS + #ifdef __SANITIZE_ADDRESS__ + #define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE + #else + #define FF_DLOPEN_FLAGS RTLD_LAZY + #endif #endif static void* libraryLoad(const char* path, int maxVersion) diff --git a/src/common/library.h b/src/common/library.h index 885cd32dc..fd12c0b05 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -3,7 +3,18 @@ #ifndef FF_INCLUDED_common_library #define FF_INCLUDED_common_library -#include +#include "fastfetch.h" +#include "util/FFcheckmacros.h" + +#if defined(_WIN32) //We don't force MSYS using LoadLibrary because dlopen also searches $LD_LIBRARY_PATH + #include + #define FF_DLOPEN_FLAGS 0 + FF_C_NODISCARD static inline void* dlopen(const char* path, int mode) { FF_UNUSED(mode); return LoadLibraryA(path); } + FF_C_NODISCARD static inline void* dlsym(void* handle, const char* symbol) { return GetProcAddress((HMODULE)handle, symbol); } + static inline int dlclose(void* handle) { return !FreeLibrary((HMODULE)handle); } +#else + #include +#endif #if defined(_WIN32) || defined(__MSYS__) #define FF_LIBRARY_EXTENSION ".dll" From 13769e0e5297dfb3998b206dbe7e0642123d38af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 17:57:59 +0800 Subject: [PATCH 066/311] Disk: removes unnecessary `#include`s --- src/modules/disk.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/disk.c b/src/modules/disk.c index 07903c496..1a2c97be8 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -3,8 +3,6 @@ #include "common/parsing.h" #include "detection/disk/disk.h" -#include - #define FF_DISK_MODULE_NAME "Disk" #define FF_DISK_NUM_FORMAT_ARGS 4 From 457c2da67d25fd44f5c0fa3f21d307f2c8533e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 17:59:37 +0800 Subject: [PATCH 067/311] Packages: silence warnings --- src/detection/packages/packages_windows.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 994a3e333..b64374e0e 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -32,6 +32,8 @@ void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts) //We have pacman and maybe others in MSYS, but not package managers for Windows if(getenv("MSYSTEM")) return ffDetectPackagesPosix(instance, counts); + #else + FF_UNUSED(instance); #endif FFstrbuf scoopPath; From 3cc661161428598e925f1903a7b1775b9c31ca30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 18:12:54 +0800 Subject: [PATCH 068/311] Windows: support native Windows --- .gitignore | 1 + CMakeLists.txt | 50 ++++++++++------ src/common/format.c | 8 ++- src/common/init.c | 50 +++++++++++++--- src/common/io.c | 20 ++++++- src/common/properties.c | 3 + src/detection/os/os_windows.cpp | 6 +- .../terminalshell/terminalshell_windows.cpp | 2 + src/fastfetch.c | 8 +++ src/fastfetch.h | 9 ++- src/modules/locale.c | 3 + src/util/FFstrbuf.h | 5 ++ src/util/windows/getline.c | 58 ++++++++++++++++++ src/util/windows/getline.h | 11 ++++ src/util/windows/pwd.c | 17 ++++++ src/util/windows/pwd.h | 22 +++++++ src/util/windows/utsname.c | 59 +++++++++++++++++++ src/util/windows/utsname.h | 19 ++++++ src/util/windows/wmi.cpp | 13 ++-- 19 files changed, 319 insertions(+), 45 deletions(-) create mode 100644 src/util/windows/getline.c create mode 100644 src/util/windows/getline.h create mode 100644 src/util/windows/pwd.c create mode 100644 src/util/windows/pwd.h create mode 100644 src/util/windows/utsname.c create mode 100644 src/util/windows/utsname.h diff --git a/.gitignore b/.gitignore index f604d255a..94a0919c6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ **/.cache/ **/.kdev4/ **/.DS_Store +/.vs cscope.* tags fastfetch.kdev4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a3117707..2b4f41f36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,11 +15,11 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) -elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS) +elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS AND NOT WIN32) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() -if(MSYS) +if(MSYS OR WIN32) enable_language(CXX) endif() @@ -27,7 +27,7 @@ endif() # Compile time dependencies # ############################# -set(THREADS_PREFER_PTHREAD_FLAG ON) +set(THREADS_PREFER_PTHREAD_FLAG NOT WIN32) find_package(Threads) find_package(PkgConfig REQUIRED) @@ -41,7 +41,7 @@ include(CheckIncludeFile) include(CMakeDependentOption) cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS" OFF) +cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS OR WIN32" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF) @@ -60,8 +60,8 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS" OFF) -cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS" OFF) +cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS OR WIN32" OFF) +cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS 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) @@ -78,10 +78,10 @@ endif() message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") if(ENABLE_THREADS) - if(CMAKE_USE_PTHREADS_INIT) - message(STATUS "Threads type: pthread") - else() + if(CMAKE_USE_WIN32_THREADS_INIT) message(STATUS "Threads type: Win32 thread") + elseif(CMAKE_USE_PTHREADS_INIT) + message(STATUS "Threads type: pthread") endif() else() message(STATUS "Threads type: disabled") @@ -90,7 +90,7 @@ endif() set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") -if(MSYS) +if(MSYS OR WIN32) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti") endif() @@ -102,7 +102,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) endif() set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer") -if(NOT MSYS) +if(NOT MSYS AND NOT WIN32) set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") @@ -344,9 +344,8 @@ if(LINUX OR BSD) ) endif() -if(MSYS) +if(MSYS OR WIN32) list(APPEND LIBFASTFETCH_SRC - src/common/processing_linux.c src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp @@ -364,9 +363,7 @@ if(MSYS) src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp src/detection/font/font_windows.cpp - src/detection/terminalshell/terminalshell_linux.c src/detection/terminalshell/terminalshell_windows.cpp - src/detection/packages/packages_linux.c src/detection/terminalfont/terminalfont_windows.c src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp @@ -379,6 +376,23 @@ if(MSYS) ) endif() +if(MSYS) + list(APPEND LIBFASTFETCH_SRC + src/common/processing_linux.c + src/detection/terminalshell/terminalshell_linux.c + src/detection/packages/packages_linux.c + ) +endif() + +if(WIN32) + list(APPEND LIBFASTFETCH_SRC + src/common/processing_windows.c + src/util/windows/getline.c + src/util/windows/pwd.c + src/util/windows/utsname.c + ) +endif() + if(APPLE) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_apple.c @@ -497,7 +511,9 @@ ff_lib_enable(FREETYPE freetype2) if(ENABLE_THREADS) target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS) - target_link_libraries(libfastfetch PRIVATE Threads::Threads) + if(CMAKE_USE_PTHREADS_INIT) #Threads::Threads is not set for WIN32 + target_link_libraries(libfastfetch PRIVATE Threads::Threads) + endif() endif() if(APPLE) @@ -510,7 +526,7 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" ) -elseif(MSYS) +elseif(MSYS OR WIN32) target_link_libraries(libfastfetch PRIVATE "wbemuuid" PRIVATE "ole32" diff --git a/src/common/format.c b/src/common/format.c index 688ae3887..19d5d289d 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -2,16 +2,18 @@ #include "common/format.h" #include "common/parsing.h" +#include + void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) { if(formatarg->type == FF_FORMAT_ARG_TYPE_INT) ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT) - ffStrbufAppendF(buffer, "%u", *(uint32_t*)formatarg->value); + ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16) - ffStrbufAppendF(buffer, "%hu", *(uint16_t*)formatarg->value); + ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8) - ffStrbufAppendF(buffer, "%hhu", *(uint8_t*)formatarg->value); + ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRING) ffStrbufAppendS(buffer, (const char*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRBUF) diff --git a/src/common/init.c b/src/common/init.c index f9001f12f..00b3c687a 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -9,7 +9,12 @@ #include #include #include -#include +#ifdef _WIN32 + #include + #include +#else + #include +#endif static bool strbufEqualsAdapter(const void* first, const void* second) { @@ -101,18 +106,35 @@ static void initCacheDir(FFstate* state) else ffStrbufEnsureEndsWithC(&state->cacheDir, '/'); - mkdir(state->cacheDir.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder, but who knows + mkdir(state->cacheDir.chars + #ifndef WIN32 + , S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH + #endif + ); //I hope everybody has a cache folder, but who knows ffStrbufAppendS(&state->cacheDir, "fastfetch/"); - mkdir(state->cacheDir.chars, S_IRWXU | S_IRGRP | S_IROTH); + mkdir(state->cacheDir.chars + #ifndef WIN32 + , S_IRWXU | S_IRGRP | S_IROTH + #endif + ); } static void initState(FFstate* state) { + #ifdef WIN32 + //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support + setlocale(LC_ALL, ".UTF8"); + #endif + state->logoWidth = 0; state->logoHeight = 0; state->keysHeight = 0; - state->passwd = getpwuid(getuid()); + #ifndef WIN32 + state->passwd = getpwuid(getuid()); + #else + state->passwd = ffGetPasswd(); + #endif uname(&state->utsname); #if FF_HAVE_SYSINFO_H @@ -305,12 +327,24 @@ static void resetConsole() fputs("\033[?25h", stdout); } +#ifdef _WIN32 +BOOL WINAPI consoleHandler(DWORD signal) +{ + if(signal == CTRL_C_EVENT) + { + resetConsole(); + return TRUE; + } + return false; +} +#else static void exitSignalHandler(int signal) { FF_UNUSED(signal); resetConsole(); exit(0); } +#endif void ffStart(FFinstance* instance) { @@ -320,12 +354,14 @@ void ffStart(FFinstance* instance) ffDisableLinewrap = instance->config.disableLinewrap && !instance->config.pipe; ffHideCursor = instance->config.hideCursor && !instance->config.pipe; - struct sigaction action = {}; - action.sa_handler = exitSignalHandler; - + #ifdef _WIN32 + SetConsoleCtrlHandler(consoleHandler, TRUE); + #else + struct sigaction action = { .sa_handler = exitSignalHandler }; sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); sigaction(SIGQUIT, &action, NULL); + #endif //We do the cache validation here, so we can skip it if --recache is given if(!instance->config.recache) diff --git a/src/common/io.c b/src/common/io.c index 1b3ccddf9..0f59205fe 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -4,8 +4,11 @@ #include #include #include -#include -#include + +#ifndef WIN32 + #include + #include +#endif static void createSubfolders(const char* fileName) { @@ -16,7 +19,13 @@ static void createSubfolders(const char* fileName) { ffStrbufAppendC(&path, *fileName); if(*fileName == '/') - mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH); + { + mkdir(path.chars + #ifndef WIN32 + , S_IRWXU | S_IRGRP | S_IROTH + #endif + ); + } ++fileName; } @@ -151,6 +160,7 @@ bool ffFileExists(const char* fileName, mode_t mode) void ffGetTerminalResponse(const char* request, const char* format, ...) { + #ifndef WIN32 struct termios oldTerm, newTerm; if(tcgetattr(STDIN_FILENO, &oldTerm) == -1) return; @@ -189,4 +199,8 @@ void ffGetTerminalResponse(const char* request, const char* format, ...) va_start(args, format); vsscanf(buffer, format, args); va_end(args); + #else + //Unimplemented + FF_UNUSED(request, format); + #endif } diff --git a/src/common/properties.c b/src/common/properties.c index 8331c6b3f..064d620aa 100644 --- a/src/common/properties.c +++ b/src/common/properties.c @@ -2,6 +2,9 @@ #include "common/properties.h" #include +#ifdef _WIN32 + #include "util/windows/getline.h" +#endif static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer) { diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 4df85791f..ccf7da36e 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -67,11 +67,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); - #ifdef __MSYS__ - ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); - #else - ffStrbufSetS(&os->systemName, "Windows"); - #endif + ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); pclsObj->Release(); pEnumerator->Release(); diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 8c1466974..c2e5acf04 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -125,6 +125,8 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) // When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way if(getenv("MSYSTEM")) return ffDetectTerminalShellPosix(instance); + #else + FF_UNUSED(instance); #endif static FFTerminalShellResult result; diff --git a/src/fastfetch.c b/src/fastfetch.c index 1520a998c..d21913664 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -10,6 +10,10 @@ #include #include +#ifdef WIN32 + #include "util/windows/getline.h" +#endif + typedef struct CustomValue { bool printKey; @@ -414,6 +418,7 @@ static inline void printCommandHelp(const char* command) static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t indentation, const char* folderName) { + #ifndef _WIN32 DIR* dir = opendir(folder->chars); if(dir == NULL) return; @@ -447,6 +452,9 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde } closedir(dir); + #else + FF_UNUSED(folder, indentation, folderName); + #endif } static inline void listAvailablePresets(FFinstance* instance) diff --git a/src/fastfetch.h b/src/fastfetch.h index 372fb221b..afb697cbf 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -8,8 +8,13 @@ #include #include -#include -#include +#ifndef _WIN32 + #include + #include +#else + #include "util/windows/pwd.h" + #include "util/windows/utsname.h" +#endif #if FF_HAVE_SYSINFO_H #include diff --git a/src/modules/locale.c b/src/modules/locale.c index c5dd9e1a4..dc2b2b650 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -26,10 +26,13 @@ static void getLocaleFromEnv(FFstrbuf* locale) static void getLocaleFromCmd(FFstrbuf* locale) { ffStrbufAppendS(locale, setlocale(LC_ALL, NULL)); + + #ifdef LC_MESSAGES if(locale->length > 0) return; ffStrbufAppendS(locale, setlocale(LC_MESSAGES, NULL)); + #endif } void ffPrintLocale(FFinstance* instance) diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 687969606..8966b569e 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -13,6 +13,11 @@ #include #include +#ifdef _WIN32 + #include + #define strcasestr StrStrIA +#endif + #define FASTFETCH_STRBUF_DEFAULT_ALLOC 32 typedef struct FFstrbuf diff --git a/src/util/windows/getline.c b/src/util/windows/getline.c new file mode 100644 index 000000000..cb1760f78 --- /dev/null +++ b/src/util/windows/getline.c @@ -0,0 +1,58 @@ +#include "getline.h" + +#include +#include + +ssize_t getline(char **lineptr, size_t *n, FILE *stream) { + ssize_t pos = -1; + int c; + + if (lineptr == NULL || stream == NULL || n == NULL) { + errno = EINVAL; + return -1; + } + + _lock_file(stream); + + c = _getc_nolock(stream); + if (c == EOF) { + goto exit; + } + + if (*lineptr == NULL) { + *lineptr = malloc(128); + if (*lineptr == NULL) { + goto exit; + } + *n = 128; + } + + pos = 0; + while(c != EOF) { + if ((size_t)(pos + 1) >= *n) { + size_t new_size = *n + (*n >> 2); + if (new_size < 128) { + new_size = 128; + } + char *new_ptr = realloc(*lineptr, new_size); + if (new_ptr == NULL) { + pos = -1; + goto exit; + } + *n = new_size; + *lineptr = new_ptr; + } + + ((char *)(*lineptr))[pos ++] = (char)c; + if (c == '\n') { + break; + } + c = _getc_nolock(stream); + } + + (*lineptr)[pos] = '\0'; + +exit: + _unlock_file(stream); + return pos; +} diff --git a/src/util/windows/getline.h b/src/util/windows/getline.h new file mode 100644 index 000000000..e4f48a4cf --- /dev/null +++ b/src/util/windows/getline.h @@ -0,0 +1,11 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UTIL_GETLINE +#define FASTFETCH_INCLUDED_UTIL_GETLINE + +#include +#include + +ssize_t getline(char **lineptr, size_t *n, FILE *stream); + +#endif diff --git a/src/util/windows/pwd.c b/src/util/windows/pwd.c new file mode 100644 index 000000000..a52f2689a --- /dev/null +++ b/src/util/windows/pwd.c @@ -0,0 +1,17 @@ +#include "pwd.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +struct passwd* ffGetPasswd() +{ + static struct passwd res; + + DWORD len = sizeof(res.pw_name); + GetUserNameA(res.pw_name, &len); + + SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, res.pw_dir); + + return &res; +} diff --git a/src/util/windows/pwd.h b/src/util/windows/pwd.h new file mode 100644 index 000000000..29d4c883b --- /dev/null +++ b/src/util/windows/pwd.h @@ -0,0 +1,22 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UTIL_PWD +#define FASTFETCH_INCLUDED_UTIL_PWD + +#include +#include + +struct passwd +{ + char pw_name[UNLEN + 1]; /* username */ + // char *pw_passwd[1]; /* user password */ + // int pw_uid; /* user ID */ + // int pw_gid; /* group ID */ + // char *pw_gecos; /* user information */ + char pw_dir[MAX_PATH]; /* home directory */ + // char *pw_shell; /* shell program */ +}; + +struct passwd* ffGetPasswd(); + +#endif diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c new file mode 100644 index 000000000..403f5e6fd --- /dev/null +++ b/src/util/windows/utsname.c @@ -0,0 +1,59 @@ +// https://github.com/tniessen/iperf-windows/blob/master/win32-compat/sys/utsname.c + +#define WIN32_LEAN_AND_MEAN +#include + +#include + +#include "utsname.h" + +int uname(struct utsname *name) +{ + memset(name, 0, sizeof(*name)); + + // Get Windows version info + OSVERSIONINFOA versionInfo = { + .dwOSVersionInfoSize = sizeof(OSVERSIONINFO), + }; + GetVersionExA(&versionInfo); + + // Get hardware info + SYSTEM_INFO sysInfo = {0}; + GetSystemInfo(&sysInfo); + + // Set implementation name + strcpy(name->sysname, "Windows_NT"); + sprintf(name->release, "%u.%u.%u", (unsigned)versionInfo.dwMajorVersion, (unsigned)versionInfo.dwMinorVersion, (unsigned)versionInfo.dwBuildNumber); + name->version[0] = '\0'; + + // Set hostname + DWORD bufSize = UTSNAME_MAXLENGTH - 1; + if(GetComputerNameA(name->nodename, &bufSize)) + return 1; + name->nodename[bufSize] = '\0'; + + // Set processor architecture + switch (sysInfo.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64: + strcpy(name->machine, "x86_64"); + break; + case PROCESSOR_ARCHITECTURE_IA64: + strcpy(name->machine, "ia64"); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + strcpy(name->machine, "x86"); + break; + case PROCESSOR_ARCHITECTURE_ARM64: + strcpy(name->machine, "aarch64"); + break; + case PROCESSOR_ARCHITECTURE_ARM: + strcpy(name->machine, "arm"); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN: + default: + strcpy(name->machine, "unknown"); + } + + return 0; +} diff --git a/src/util/windows/utsname.h b/src/util/windows/utsname.h new file mode 100644 index 000000000..96bc53adc --- /dev/null +++ b/src/util/windows/utsname.h @@ -0,0 +1,19 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UTSNAME_H +#define FASTFETCH_INCLUDED_UTSNAME_H + +#define UTSNAME_MAXLENGTH 256 + +struct utsname +{ + char sysname[UTSNAME_MAXLENGTH]; // name of this implementation of the operating system + char nodename[UTSNAME_MAXLENGTH]; // name of this node within an implementation - dependent communications network + char release[UTSNAME_MAXLENGTH]; // current release level of this implementation + char version[UTSNAME_MAXLENGTH]; // current version level of this release + char machine[UTSNAME_MAXLENGTH]; // name of the hardware type on which the system is running +}; + +int uname(struct utsname *name); + +#endif diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 925d428ee..9b1a120d0 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -13,9 +13,6 @@ static void CoUninitializeWrap() static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) { - static char error[128]; - *((char**)lpContext) = error; - HRESULT hres; // Initialize COM @@ -37,7 +34,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) if (FAILED(hres)) { CoUninitialize(); - snprintf(error, sizeof(error), "Failed to initialize security. Error code = 0x%X", hres); + *((const char**)lpContext) = "Failed to initialize security"; return FALSE; } @@ -53,7 +50,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) if (FAILED(hres)) { CoUninitialize(); - snprintf(error, sizeof(error), "Failed to create IWbemLocator object. Error code = 0x%X", hres); + *((const char**)lpContext) = "Failed to create IWbemLocator object"; return FALSE; } @@ -79,7 +76,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) if (FAILED(hres)) { CoUninitialize(); - snprintf(error, sizeof(error), "Could not connect WMI server. Error code = 0x%X", hres); + *((const char**)lpContext) = "Could not connect WMI server"; return FALSE; } @@ -99,7 +96,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) { pSvc->Release(); CoUninitialize(); - snprintf(error, sizeof(error), "Could not set proxy blanket. Error code = 0x%X", hres); + *((const char**)lpContext) = "Could not set proxy blanket"; return FALSE; } @@ -134,7 +131,7 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) if (FAILED(hres)) { if(error) - ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%X", queryStr, hres); + ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%lX", queryStr, hres); return nullptr; } From 952cacf3ffe48d58de1fa28267e22226f9450568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 18:28:43 +0800 Subject: [PATCH 069/311] ci: build with Windows native --- .github/workflows/push.yml | 68 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 76fd9ede9..6dc59f29e 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -123,8 +123,8 @@ jobs: name: fastfetch-bsd path: ./fastfetch-*.* - windows: - name: Windows + msys: + name: MSYS runs-on: windows-latest permissions: security-events: write @@ -179,6 +179,70 @@ jobs: - name: run flashfetch run: ./flashfetch + - name: upload artifacts + uses: actions/upload-artifact@v3 + with: + name: fastfetch-msys + path: | + ./*.dll + ./*.exe + + windows: + name: Windows + runs-on: windows-latest + permissions: + security-events: write + contents: read + outputs: + ffversion: ${{ steps.ffversion.outputs.ffversion }} + defaults: + run: + shell: msys2 {0} + steps: + - name: checkout repository + uses: actions/checkout@v3 + + - name: setup-msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: CLANG64 + update: true + install: git mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd + + - name: print msys version + run: uname -a + + # https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785 + - name: create OpenCL.pc + run: | + cat > /clang64/lib/pkgconfig/OpenCL.pc << EOF + prefix=/clang64 + exec_prefix=${prefix} + libdir=${exec_prefix}/lib + includedir=${prefix}/include + + Name: OpenCL + Description: Open Computing Language generic Installable Client Driver Loader + Version: 2022.09.30-1 + Libs: -L${libdir} -lOpenCL.dll + Cflags: -I${includedir} + EOF + + - name: configure project + run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . + + - name: build project + run: cmake --build . --target fastfetch --target flashfetch + + - name: copy necessary dlls + run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . + + - name: run fastfetch + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + + - name: run flashfetch + run: ./flashfetch + - name: upload artifacts uses: actions/upload-artifact@v3 with: From 79cfa96616c63bf81ded22b59510cf67467f1e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 20:06:54 +0800 Subject: [PATCH 070/311] Processing: fix Windows impl --- src/common/processing_windows.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index f3bb64a2d..9ec6da811 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -28,12 +28,11 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) }; FFstrbuf cmdline; - ffStrbufInit(&cmdline); - for(char* const* parg = argv; *parg; ++parg) + ffStrbufInitS(&cmdline, argv[0]); + for(char* const* parg = &argv[1]; *parg; ++parg) { - if(cmdline.length > 0) - ffStrbufAppendC(&cmdline, ' '); - ffStrbufAppendF(&cmdline, "\"%s\"", * parg); + ffStrbufAppendC(&cmdline, ' '); + ffStrbufAppendS(&cmdline, *parg); } BOOL success = CreateProcessA( @@ -48,6 +47,8 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION + ffStrbufDestroy(&cmdline); + CloseHandle(hChildStdoutWrite); if(!success) { @@ -55,14 +56,10 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) return "CreateProcessA() failed"; } - char str[128]; + char str[1024]; DWORD nRead; while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0) - { ffStrbufAppendNS(buffer, nRead, str); - if(nRead < sizeof(str)) - break; - } CloseHandle(hChildStdoutRead); return NULL; From 6f66b8726228b69dcd71e091aef049333272ef5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 22:28:43 +0800 Subject: [PATCH 071/311] Windows: support --list-presets --- src/detection/packages/packages_windows.c | 2 +- src/fastfetch.c | 38 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index b64374e0e..d9712b6f7 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -15,7 +15,7 @@ static uint32_t getNumElements(const char* searchPath /* including `\*` suffix * { if(wfd.dwFileAttributes & type) counter++; - } while (FindNextFileA(hFind, &wfd) == TRUE); + } while (FindNextFileA(hFind, &wfd)); FindClose(hFind); } diff --git a/src/fastfetch.c b/src/fastfetch.c index d21913664..817dd5dba 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -7,11 +7,13 @@ #include #include #include -#include #include #ifdef WIN32 #include "util/windows/getline.h" + #include +#else + #include #endif typedef struct CustomValue @@ -434,7 +436,6 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde { if(entry->d_type == DT_DIR) { - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; @@ -453,7 +454,38 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde closedir(dir); #else - FF_UNUSED(folder, indentation, folderName); + uint32_t folderLength = folder->length; + + if(folderName != NULL) + printf("%s/\n", folderName); + + ffStrbufAppendC(folder, '*'); + WIN32_FIND_DATAA entry; + HANDLE hFind = FindFirstFileA(folder->chars, &entry); + if(hFind == INVALID_HANDLE_VALUE) + return; + + do + { + if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if(strcmp(entry.cFileName, ".") == 0 || strcmp(entry.cFileName, "..") == 0) + continue; + + ffStrbufSubstrBefore(folder, folderLength); + ffStrbufAppendS(folder, entry.cFileName); + ffStrbufAppendC(folder, '/'); + listAvailablePresetsFromFolder(folder, (uint8_t) (indentation + 1), entry.cFileName); + ffStrbufSubstrBefore(folder, folderLength); + continue; + } + + for(uint8_t i = 0; i < indentation; i++) + fputs(" | ", stdout); + + puts(entry.cFileName); + } while (FindNextFileA(hFind, &entry)); + FindClose(hFind); #endif } From cf048bc723782d29c0475df65406423c8d2fae8a Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 13 Oct 2022 21:43:31 +0200 Subject: [PATCH 072/311] Refactor package detection code --- CMakeLists.txt | 6 +- src/detection/packages/packages.c | 31 +++ src/detection/packages/packages.h | 31 +-- src/detection/packages/packages_apple.c | 83 +++++++ src/detection/packages/packages_linux.c | 275 +++++++--------------- src/detection/packages/packages_windows.c | 23 +- src/modules/packages.c | 93 +++----- 7 files changed, 263 insertions(+), 279 deletions(-) create mode 100644 src/detection/packages/packages.c create mode 100644 src/detection/packages/packages_apple.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b4f41f36..25074c595 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,6 +238,7 @@ set(LIBFASTFETCH_SRC src/detection/displayserver/displayserver.c src/detection/terminalfont/terminalfont.c src/detection/media/media.c + src/detection/packages/packages.c src/modules/break.c src/modules/custom.c src/modules/title.c @@ -290,7 +291,6 @@ if(LINUX OR APPLE OR ANDROID OR BSD) src/common/processing_linux.c src/detection/disk/disk.c src/detection/terminalshell/terminalshell_linux.c - src/detection/packages/packages_linux.c src/detection/kernel/kernel_linux.c src/detection/localip/localip_linux.c ) @@ -317,6 +317,7 @@ if(LINUX OR ANDROID OR BSD) src/detection/opengl/opengl_linux.c src/detection/processes/processes_linux.c src/detection/uptime/uptime_linux.c + src/detection/packages/packages_linux.c src/detection/poweradapter/poweradapter_nosupport.c ) @@ -365,7 +366,6 @@ if(MSYS OR WIN32) src/detection/font/font_windows.cpp src/detection/terminalshell/terminalshell_windows.cpp src/detection/terminalfont/terminalfont_windows.c - src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp src/detection/localip/localip_windows.c src/detection/uptime/uptime_windows.c @@ -387,6 +387,7 @@ endif() if(WIN32) list(APPEND LIBFASTFETCH_SRC src/common/processing_windows.c + src/detection/packages/packages_windows.c src/util/windows/getline.c src/util/windows/pwd.c src/util/windows/utsname.c @@ -415,6 +416,7 @@ if(APPLE) src/detection/opengl/opengl_apple.c src/detection/processes/processes_apple.c src/detection/uptime/uptime_apple.c + src/detection/packages/packages_apple.c src/detection/bios/bios_nosupport.c src/detection/board/board_nosupport.c diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c new file mode 100644 index 000000000..08d79e054 --- /dev/null +++ b/src/detection/packages/packages.c @@ -0,0 +1,31 @@ +#include "packages.h" +#include "detection/internal.h" + +void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result); + +const FFPackagesResult* ffDetectPackages(const FFinstance* instance) +{ + FF_DETECTION_INTERNAL_GUARD(FFPackagesResult, + memset(&result, 0, sizeof(FFPackagesResult)); + ffStrbufInit(&result.pacmanBranch); + + ffDetectPackagesImpl(instance, &result); + + result.all = 0 + + result.pacman + + result.dpkg + + result.rpm + + result.emerge + + result.xbps + + result.nixSystem + + result.nixUser + + result.nixDefault + + result.apk + + result.pkg + + result.flatpak + + result.snap + + result.brew + + result.port + + result.scoop; + ); +} diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index 9ecfdb7e9..92bd26d63 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -5,28 +5,29 @@ #include "fastfetch.h" -typedef struct FFPackageCounts +typedef struct FFPackagesResult { - uint32_t pacman; - uint32_t dpkg; - uint32_t rpm; - uint32_t emerge; - uint32_t xbps; - uint32_t nixSystem; - uint32_t nixDefault; + uint32_t all; + uint32_t apk; - uint32_t pkg; - uint32_t flatpak; - uint32_t snap; uint32_t brew; + uint32_t dpkg; + uint32_t emerge; + uint32_t flatpak; + uint32_t nixDefault; + uint32_t nixSystem; + uint32_t nixUser; + uint32_t pacman; + uint32_t pkg; uint32_t port; + uint32_t rpm; uint32_t scoop; + uint32_t snap; + uint32_t xbps; FFstrbuf pacmanBranch; +} FFPackagesResult; - uint32_t nixUser; -} FFPackageCounts; - -void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts); +const FFPackagesResult* ffDetectPackages(const FFinstance* instance); #endif diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c new file mode 100644 index 000000000..ecabe0771 --- /dev/null +++ b/src/detection/packages/packages_apple.c @@ -0,0 +1,83 @@ +#include "packages.h" + +static uint32_t getNumElements(const char* dirname, unsigned char type) +{ + DIR* dirp = opendir(dirname); + if(dirp == NULL) + return 0; + + uint32_t num_elements = 0; + + struct dirent *entry; + while((entry = readdir(dirp)) != NULL) { + if(entry->d_type == type) + ++num_elements; + } + + if(type == DT_DIR) + num_elements -= 2; // accounting for . and .. + + closedir(dirp); + + return num_elements; +} + +static uint32_t countBrewPackages(const char* dirname) +{ + FFstrbuf baseDir; + ffStrbufInitS(&baseDir, dirname); + + uint32_t result = 0; + uint32_t baseDirLength = baseDir->length; + + ffStrbufAppendS(baseDir, "/Caskroom"); + result += getNumElements(baseDir->chars, DT_DIR); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + ffStrbufAppendS(baseDir, "/Cellar"); + result += getNumElements(baseDir->chars, DT_DIR); + ffStrbufSubstrBefore(baseDir, baseDirLength); + + ffStrbufDestroy(baseDir); + return result; +} + +static uint32_t getBrewPackages() +{ + const char* prefix = getenv("HOMEBREW_PREFIX"); + if(ffStrSet(prefix)) + return countBrewPackages(prefix); + + uint32_t result = 0; + result += countBrewPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/homebrew"); + result += countBrewPackages(FASTFETCH_TARGET_DIR_ROOT"/usr/local"); + return result; +} + +static uint32_t countMacPortsPackages(const char* dirname) +{ + FFstrbuf baseDir; + ffStrbufInitS(&baseDir, dirname); + ffStrbufAppendS(baseDir, "/var/macports/software"); + + uint32_t result += getNumElements(baseDir->chars, DT_DIR); + + ffStrbufDestroy(baseDir); + return result; +} + +static uint32_t getMacPortsPackages() +{ + const char* prefix = getenv("MACPORTS_PREFIX"); + if(ffStrSet(prefix)) + return countMacPortsPackages(baseDir); + + return countMacPortsPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/local"); +} + +void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) +{ + FF_UNUSED(instance); + result->brew = getBrewPackages(); + result->port = getMacPortsPackages(); +} diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index d25df2970..4a2f6d88e 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -1,3 +1,4 @@ +#include "packages.h" #include "common/io.h" #include "common/properties.h" #include "common/settings.h" @@ -5,14 +6,12 @@ #include "common/parsing.h" #include "detection/os/os.h" -#include "packages.h" - #include #include #include #include -static uint32_t getNumElements(const char* dirname, unsigned char type) +static uint32_t getNumElementsImpl(const char* dirname, unsigned char type) { DIR* dirp = opendir(dirname); if(dirp == NULL) @@ -26,7 +25,7 @@ static uint32_t getNumElements(const char* dirname, unsigned char type) ++num_elements; } - if(type == DT_DIR) + if(type == DT_DIR && num_elements >= 2) num_elements -= 2; // accounting for . and .. closedir(dirp); @@ -34,9 +33,16 @@ static uint32_t getNumElements(const char* dirname, unsigned char type) return num_elements; } -#ifndef __APPLE__ +static uint32_t getNumElements(FFstrbuf* baseDir, const char* dirname, unsigned char type) +{ + uint32_t baseDirLength = baseDir->length; + ffStrbufAppendS(baseDir, dirname); + uint32_t num_elements = getNumElementsImpl(baseDir->chars, type); + ffStrbufSubstrBefore(baseDir, baseDirLength); + return num_elements; +} -static uint32_t getNumStrings(const char* filename, const char* needle) +static uint32_t getNumStringsImpl(const char* filename, const char* needle) { FILE* file = fopen(filename, "r"); if(file == NULL) @@ -61,9 +67,25 @@ static uint32_t getNumStrings(const char* filename, const char* needle) return count; } -#ifndef __ANDROID__ +static uint32_t getNumStrings(FFstrbuf* baseDir, const char* filename, const char* needle) +{ + uint32_t baseDirLength = baseDir->length; + ffStrbufAppendS(baseDir, filename); + uint32_t num_elements = getNumStringsImpl(baseDir->chars, needle); + ffStrbufSubstrBefore(baseDir, baseDirLength); + return num_elements; +} -static uint32_t countFilesRecursive(FFstrbuf* baseDirPath, const char* filename) +static uint32_t getSQLite3Int(const FFinstance* instance, FFstrbuf* baseDir, const char* dbPath, const char* query) +{ + uint32_t baseDirLength = baseDir->length; + ffStrbufAppendS(baseDir, dbPath); + uint32_t num_elements = (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, query); + ffStrbufSubstrBefore(baseDir, baseDirLength); + return num_elements; +} + +static uint32_t countFilesRecursiveImpl(FFstrbuf* baseDirPath, const char* filename) { uint32_t baseDirPathLength = baseDirPath->length; @@ -90,7 +112,7 @@ static uint32_t countFilesRecursive(FFstrbuf* baseDirPath, const char* filename) continue; ffStrbufAppendS(baseDirPath, entry->d_name); - sum += countFilesRecursive(baseDirPath, filename); + sum += countFilesRecursiveImpl(baseDirPath, filename); ffStrbufSubstrBefore(baseDirPath, baseDirPathLength); } @@ -98,7 +120,16 @@ static uint32_t countFilesRecursive(FFstrbuf* baseDirPath, const char* filename) return sum; } -static uint32_t getNixPackages(char* path) +static uint32_t countFilesRecursive(FFstrbuf* baseDir, const char* dirname, const char* filename) +{ + uint32_t baseDirLength = baseDir->length; + ffStrbufAppendS(baseDir, dirname); + uint32_t sum = countFilesRecursiveImpl(baseDir, filename); + ffStrbufSubstrBefore(baseDir, baseDirLength); + return sum; +} + +static uint32_t getNixPackagesImpl(char* path) { //Nix detection is kinda slow, so we only do it if the dir exists if(!ffFileExists(path, S_IFDIR)) @@ -130,7 +161,16 @@ static uint32_t getNixPackages(char* path) return result; } -static uint32_t getXBPS(FFstrbuf* baseDir) +static uint32_t getNixPackages(FFstrbuf* baseDir, const char* dirname) +{ + uint32_t baseDirLength = baseDir->length; + ffStrbufAppendS(baseDir, dirname); + uint32_t num_elements = getNixPackagesImpl(baseDir->chars); + ffStrbufSubstrBefore(baseDir, baseDirLength); + return num_elements; +} + +static uint32_t getXBPSImpl(FFstrbuf* baseDir) { DIR* dir = opendir(baseDir->chars); if(dir == NULL) @@ -146,7 +186,7 @@ static uint32_t getXBPS(FFstrbuf* baseDir) ffStrbufAppendC(baseDir, '/'); ffStrbufAppendS(baseDir, entry->d_name); - result = getNumStrings(baseDir->chars, "installed"); + result = getNumStringsImpl(baseDir->chars, "installed"); break; } @@ -154,91 +194,23 @@ static uint32_t getXBPS(FFstrbuf* baseDir) return result; } -#endif // !__ANDROID__ - -#else // !__APPLE__ - -static uint32_t countBrewPackages(FFstrbuf* baseDir) +static uint32_t getXBPS(FFstrbuf* baseDir, const char* dirname) { - uint32_t result = 0; uint32_t baseDirLength = baseDir->length; - - ffStrbufAppendS(baseDir, "/Caskroom"); - result += getNumElements(baseDir->chars, DT_DIR); + ffStrbufAppendS(baseDir, dirname); + uint32_t result = getXBPSImpl(baseDir); ffStrbufSubstrBefore(baseDir, baseDirLength); - - ffStrbufAppendS(baseDir, "/Cellar"); - result += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - return result; } -static uint32_t getBrewPackages(FFstrbuf* baseDir) +static uint32_t getSnap(FFstrbuf* baseDir) { - uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; + uint32_t result = getNumElements(baseDir, "/snap", DT_DIR); - const char* prefix = getenv("HOMEBREW_PREFIX"); - bool prefixSet = ffStrSet(prefix); - - if(prefixSet) - { - ffStrbufAppendS(baseDir, prefix); - result += countBrewPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - } - - ffStrbufAppendS(baseDir, "/opt/homebrew"); - if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) - result += countBrewPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - ffStrbufAppendS(baseDir, "/usr/local"); - if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) - result += countBrewPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - return result; + //Accounting for the /snap/bin folder + return result > 0 ? result - 1 : 0; } -static uint32_t countMacPortsPackages(FFstrbuf* baseDir) -{ - uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; - - ffStrbufAppendS(baseDir, "/var/macports/software"); - result += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - return result; -} - -static uint32_t getMacPortsPackages(FFstrbuf* baseDir) -{ - uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; - - const char* prefix = getenv("MACPORTS_PREFIX"); - bool prefixSet = ffStrSet(prefix); - - if(prefixSet) - { - ffStrbufAppendS(baseDir, prefix); - result += countMacPortsPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - } - - ffStrbufAppendS(baseDir, "/opt/local"); - if(!prefixSet || strcasecmp(baseDir->chars, prefix) != 0) - result += countMacPortsPackages(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - return result; -} - -#endif // __APPLE__ - #ifdef FF_HAVE_RPM #include "common/library.h" #include @@ -292,96 +264,33 @@ static uint32_t getRpmFromLibrpm(const FFinstance* instance) #endif //FF_HAVE_RPM -static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, FFPackageCounts* packageCounts) +static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, FFPackagesResult* packageCounts) { - #if defined(__APPLE__) || defined(__ANDROID__) - FF_UNUSED(instance); - #endif + packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q"); + packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: "); + packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE"); + packageCounts->flatpak += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR); + packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default"); + packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system"); + packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR); + packageCounts->pkg += getSQLite3Int(instance, baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages"); + packageCounts->rpm += getSQLite3Int(instance, baseDir, "/var/lib/rpm/rmpdb.sqlite", "SELECT count(blob) FROM Packages"); + packageCounts->snap += getSnap(baseDir); + packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps"); +} - #ifndef __APPLE__ //Linux desktop and Android +static void getPackageCountsRegular(const FFinstance* instance, FFstrbuf* baseDir, FFPackagesResult* packageCounts) +{ + getPackageCounts(instance, baseDir, packageCounts); uint32_t baseDirLength = baseDir->length; - - //pacman - ffStrbufAppendS(baseDir, "/var/lib/pacman/local"); - packageCounts->pacman += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //dpkg - ffStrbufAppendS(baseDir, "/var/lib/dpkg/status"); - packageCounts->dpkg += getNumStrings(baseDir->chars, "Status: "); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - #ifndef __ANDROID__ //Linux Desktop - - //rpm - ffStrbufAppendS(baseDir, "/var/lib/rpm/rmpdb.sqlite"); - packageCounts->rpm += (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, "SELECT count(blob) FROM Packages"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //emerge - ffStrbufAppendS(baseDir, "/var/db/pkg"); - packageCounts->emerge += countFilesRecursive(baseDir, "SIZE"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //xps - ffStrbufAppendS(baseDir, "/var/db/xbps"); - packageCounts->xbps += getXBPS(baseDir); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //nix system - ffStrbufAppendS(baseDir, "/run/current-system"); - packageCounts->nixSystem += getNixPackages(baseDir->chars); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //nix default - ffStrbufAppendS(baseDir, "/nix/var/nix/profiles/default"); - packageCounts->nixDefault += getNixPackages(baseDir->chars); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //apk - ffStrbufAppendS(baseDir, "/lib/apk/db/installed"); - packageCounts->apk += getNumStrings(baseDir->chars, "C:Q"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //flatpak - ffStrbufAppendS(baseDir, "/var/lib/flatpak/app"); - packageCounts->flatpak += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //snap - ffStrbufAppendS(baseDir, "/snap"); - uint32_t snap = getNumElements(baseDir->chars, DT_DIR); - if(snap > 0) - packageCounts->snap += (snap - 1); //Accounting for the /snap/bin folder - ffStrbufSubstrBefore(baseDir, baseDirLength); - - //pacman branch ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC"/pacman-mirrors.conf"); if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0) ffStrbufAppendS(&packageCounts->pacmanBranch, "stable"); ffStrbufSubstrBefore(baseDir, baseDirLength); - - #endif // !__ANDROID__ - - #else // !__APPLE__ - - //brew - packageCounts->brew += getBrewPackages(baseDir); - packageCounts->port += getMacPortsPackages(baseDir); - - #endif // __APPLE__ - - #ifdef __FreeBSD__ - - ffStrbufAppendS(baseDir, "/var/db/pkg/local.sqlite"); - packageCounts->pkg += (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, "SELECT count(id) FROM packages"); - ffStrbufSubstrBefore(baseDir, baseDirLength); - - #endif // __FreeBSD__ } -static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDir, FFPackageCounts* packageCounts) +static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDir, FFPackagesResult* packageCounts) { uint32_t baseDirLength = baseDir->length; @@ -391,12 +300,11 @@ static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDi if(dir == NULL) { ffStrbufSubstrBefore(baseDir, baseDirLength); - getPackageCounts(instance, baseDir, packageCounts); return; } ffStrbufAppendC(baseDir, '/'); - baseDirLength = baseDir->length; + uint32_t baseDirLength2 = baseDir->length; struct dirent* entry; while((entry = readdir(dir)) != NULL) @@ -406,43 +314,34 @@ static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDi ffStrbufAppendS(baseDir, entry->d_name); getPackageCounts(instance, baseDir, packageCounts); - ffStrbufSubstrBefore(baseDir, baseDirLength); + ffStrbufSubstrBefore(baseDir, baseDirLength2); } closedir(dir); + ffStrbufSubstrBefore(baseDir, baseDirLength); } -void -#ifdef __MSYS__ -ffDetectPackagesPosix -#else -ffDetectPackages -#endif -(FFinstance* instance, FFPackageCounts* counts) +void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) { FFstrbuf baseDir; ffStrbufInitA(&baseDir, 512); ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT); - if(ffStrbufIgnCaseCompS(&ffDetectOS(instance)->id, "bedrock") == 0) - getPackageCountsBedrock(instance, &baseDir, counts); + if(ffStrbufIgnCaseCompS(&(ffDetectOS(instance)->id), "bedrock") == 0) + getPackageCountsBedrock(instance, &baseDir, result); else - getPackageCounts(instance, &baseDir, counts); + getPackageCountsRegular(instance, &baseDir, result); // If SQL failed, we can still try with librpm. // This is needed on openSUSE, which seems to use a proprietary database file // This method doesn't work on bedrock, so we do it here. #ifdef FF_HAVE_RPM - if(counts->rpm == 0) - counts->rpm = getRpmFromLibrpm(instance); + if(result->rpm == 0) + result->rpm = getRpmFromLibrpm(instance); #endif - #if !defined(__ANDROID__) && !defined(__APPLE__) - //nix user - ffStrbufSetS(&baseDir, instance->state.passwd->pw_dir); - ffStrbufAppendS(&baseDir, "/.nix-profile"); - counts->nixUser = getNixPackages(baseDir.chars); - #endif + ffStrbufSetS(&baseDir, instance->state.passwd->pw_dir); + result->nixUser = getNixPackages(&baseDir, "/.nix-profile"); ffStrbufDestroy(&baseDir); } diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index d9712b6f7..9ad5be848 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -19,29 +19,20 @@ static uint32_t getNumElements(const char* searchPath /* including `\*` suffix * FindClose(hFind); } + if(type == FILE_ATTRIBUTE_DIRECTORY && counter >= 2) + counter -= 2; // accounting for . and .. + return counter; } -#ifdef __MSYS__ - void ffDetectPackagesPosix(const FFinstance* instance, FFPackageCounts* counts); -#endif - -void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts) +void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) { - #ifdef __MSYS__ - //We have pacman and maybe others in MSYS, but not package managers for Windows - if(getenv("MSYSTEM")) - return ffDetectPackagesPosix(instance, counts); - #else - FF_UNUSED(instance); - #endif + FF_UNUSED(instance); FFstrbuf scoopPath; ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); counts->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); - if(counts->scoop >= 3) - counts->scoop -= 3; // . .. scoop - else - counts->scoop = 0; + if(counts->scoop > 0) + counts->scoop-- // scoop ffStrbufDestroy(&scoopPath); } diff --git a/src/modules/packages.c b/src/modules/packages.c index 5e653bcd7..488334bb1 100644 --- a/src/modules/packages.c +++ b/src/modules/packages.c @@ -7,11 +7,9 @@ void ffPrintPackages(FFinstance* instance) { - FFPackageCounts counts = {0}; - ffStrbufInit(&counts.pacmanBranch); - ffDetectPackages(instance, &counts); + const FFPackagesResult* counts = ffDetectPackages(instance); + uint32_t all = counts->all; //Copy it, so we can substract from it in FF_PRINT_PACKAGE - uint32_t all = counts.pacman + counts.dpkg + counts.rpm + counts.emerge + counts.xbps + counts.nixSystem + counts.nixUser + counts.nixDefault + counts.apk + counts.pkg + counts.flatpak + counts.snap + counts.brew + counts.port + counts.scoop; if(all == 0) { ffPrintError(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages, "No packages from known package managers found"); @@ -22,20 +20,22 @@ void ffPrintPackages(FFinstance* instance) { ffPrintLogoAndKey(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages.key); - #define FF_PRINT_PACKAGE(name) \ - if(counts.name > 0) \ - { \ - printf("%u ("#name")", counts.name); \ - if((all = all - counts.name) > 0) \ - printf(", "); \ - }; + #define FF_PRINT_PACKAGE_NAME(var, name) \ + if(counts->var > 0) \ + { \ + printf("%u ("name")", counts->var); \ + if((all -= counts->var) > 0) \ + printf(", "); \ + }; - if(counts.pacman > 0) + #define FF_PRINT_PACKAGE(name) FF_PRINT_PACKAGE_NAME(name, #name) + + if(counts->pacman > 0) { - printf("%u (pacman)", counts.pacman); - if(counts.pacmanBranch.length > 0) - printf("[%s]", counts.pacmanBranch.chars); - if((all = all - counts.pacman) > 0) + printf("%u (pacman)", counts->pacman); + if(counts->pacmanBranch.length > 0) + printf("[%s]", counts->pacmanBranch.chars); + if((all -= counts->pacman) > 0) printf(", "); }; @@ -43,28 +43,9 @@ void ffPrintPackages(FFinstance* instance) FF_PRINT_PACKAGE(rpm) FF_PRINT_PACKAGE(emerge) FF_PRINT_PACKAGE(xbps) - - if(counts.nixSystem > 0) - { - printf("%u (nix-system)", counts.nixSystem); - if((all = all - counts.nixSystem) > 0) - printf(", "); - } - - if(counts.nixUser > 0) - { - printf("%u (nix-user)", counts.nixUser); - if((all = all - counts.nixUser) > 0) - printf(", "); - } - - if(counts.nixDefault > 0) - { - printf("%u (nix-default)", counts.nixDefault); - if((all = all - counts.nixDefault) > 0) - printf(", "); - } - + FF_PRINT_PACKAGE_NAME(nixSystem, "nix-system") + FF_PRINT_PACKAGE_NAME(nixUser, "nix-user") + FF_PRINT_PACKAGE_NAME(nixDefault, "nix-default") FF_PRINT_PACKAGE(apk) FF_PRINT_PACKAGE(pkg) FF_PRINT_PACKAGE(flatpak) @@ -76,32 +57,28 @@ void ffPrintPackages(FFinstance* instance) //Fix linter warning of unused value of all (void) all; - #undef FF_PRINT_PACKAGE - putchar('\n'); } else { ffPrintFormat(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages, FF_PACKAGES_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_UINT, &all}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.pacman}, - {FF_FORMAT_ARG_TYPE_STRBUF, &counts.pacmanBranch}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.dpkg}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.rpm}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.emerge}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.xbps}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.nixSystem}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.nixUser}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.nixDefault}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.apk}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.pkg}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.flatpak}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.snap}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.brew}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.port}, - {FF_FORMAT_ARG_TYPE_UINT, &counts.scoop} + {FF_FORMAT_ARG_TYPE_UINT, &counts->pacman}, + {FF_FORMAT_ARG_TYPE_STRBUF, &counts->pacmanBranch}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->dpkg}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->rpm}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->emerge}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->xbps}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->nixSystem}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->nixUser}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->nixDefault}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->apk}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->pkg}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->flatpak}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->snap}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->brew}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->port}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->scoop} }); } - - ffStrbufDestroy(&counts.pacmanBranch); } From e18980be9fdd06283406f73dc77c2e03446fc2cd Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 13 Oct 2022 21:47:28 +0200 Subject: [PATCH 073/311] Require sucessfull windows and msys build for release --- .github/workflows/push.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 6dc59f29e..34ca25a84 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -259,6 +259,8 @@ jobs: - linux - macos - bsd + - msys + - windows permissions: contents: write steps: From 693cc1e7307dae275b4bb7f10d8ae52c7ff33c8a Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 13 Oct 2022 22:02:58 +0200 Subject: [PATCH 074/311] Fix build errors --- src/common/io.c | 1 - src/common/io.h | 2 +- src/common/settings.c | 3 +-- src/detection/displayserver/linux/wmde.c | 1 - src/detection/packages/packages_apple.c | 19 +++++++++++-------- src/detection/packages/packages_linux.c | 7 ++----- src/detection/packages/packages_windows.c | 6 +++--- .../terminalfont/terminalfont_android.c | 2 -- src/fastfetch.c | 1 - 9 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/common/io.c b/src/common/io.c index 0f59205fe..be2cb6afb 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -1,7 +1,6 @@ #include "fastfetch.h" #include "common/io.h" -#include #include #include diff --git a/src/common/io.h b/src/common/io.h index a6ecbc5ac..2c4db8716 100644 --- a/src/common/io.h +++ b/src/common/io.h @@ -5,7 +5,7 @@ #include "fastfetch.h" -#include //mode_t +#include //mode_t bool ffWriteFDBuffer(int fd, const FFstrbuf* content); bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data); diff --git a/src/common/settings.c b/src/common/settings.c index 6f5a5cfcb..1222aa490 100644 --- a/src/common/settings.c +++ b/src/common/settings.c @@ -1,8 +1,8 @@ #include "fastfetch.h" #include "common/settings.h" #include "common/library.h" -#include "common/io.h" #include "common/thread.h" +#include "common/io.h" #include @@ -280,7 +280,6 @@ FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelNam #ifdef FF_HAVE_SQLITE3 #include -#include typedef struct SQLiteData { diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index da942bbd7..0cb7c7493 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -9,7 +9,6 @@ #include #include #include -#include static const char* parseEnv() { diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c index ecabe0771..70b736c12 100644 --- a/src/detection/packages/packages_apple.c +++ b/src/detection/packages/packages_apple.c @@ -1,4 +1,7 @@ #include "packages.h" +#include "common/parsing.h" + +#include static uint32_t getNumElements(const char* dirname, unsigned char type) { @@ -28,17 +31,17 @@ static uint32_t countBrewPackages(const char* dirname) ffStrbufInitS(&baseDir, dirname); uint32_t result = 0; - uint32_t baseDirLength = baseDir->length; + uint32_t baseDirLength = baseDir.length; - ffStrbufAppendS(baseDir, "/Caskroom"); - result += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); + ffStrbufAppendS(&baseDir, "/Caskroom"); + result += getNumElements(baseDir.chars, DT_DIR); + ffStrbufSubstrBefore(&baseDir, baseDirLength); - ffStrbufAppendS(baseDir, "/Cellar"); - result += getNumElements(baseDir->chars, DT_DIR); - ffStrbufSubstrBefore(baseDir, baseDirLength); + ffStrbufAppendS(&baseDir, "/Cellar"); + result += getNumElements(baseDir.chars, DT_DIR); + ffStrbufSubstrBefore(&baseDir, baseDirLength); - ffStrbufDestroy(baseDir); + ffStrbufDestroy(&baseDir); return result; } diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index 4a2f6d88e..e2cab221d 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -1,15 +1,12 @@ #include "packages.h" #include "common/io.h" +#include "common/parsing.h" +#include "common/processing.h" #include "common/properties.h" #include "common/settings.h" -#include "common/processing.h" -#include "common/parsing.h" #include "detection/os/os.h" -#include -#include #include -#include static uint32_t getNumElementsImpl(const char* dirname, unsigned char type) { diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 9ad5be848..8839fdb16 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -31,8 +31,8 @@ void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) FFstrbuf scoopPath; ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); - counts->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); - if(counts->scoop > 0) - counts->scoop-- // scoop + result->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); + if(result->scoop > 0) + result->scoop-- // scoop ffStrbufDestroy(&scoopPath); } diff --git a/src/detection/terminalfont/terminalfont_android.c b/src/detection/terminalfont/terminalfont_android.c index 24a9baacd..8dd1ff2fe 100644 --- a/src/detection/terminalfont/terminalfont_android.c +++ b/src/detection/terminalfont/terminalfont_android.c @@ -3,8 +3,6 @@ #include "detection/terminalshell/terminalshell.h" #include "common/io.h" -#include - #ifdef FF_HAVE_FREETYPE #include "common/library.h" #include diff --git a/src/fastfetch.c b/src/fastfetch.c index 817dd5dba..6d1a2b8d2 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -7,7 +7,6 @@ #include #include #include -#include #ifdef WIN32 #include "util/windows/getline.h" From 1513b8c0db60e2ce1c8b621b697577be9af9530b Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 13 Oct 2022 22:12:31 +0200 Subject: [PATCH 075/311] Fix more build errors --- src/detection/packages/packages_apple.c | 8 ++++---- src/detection/packages/packages_windows.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c index 70b736c12..3966240fd 100644 --- a/src/detection/packages/packages_apple.c +++ b/src/detection/packages/packages_apple.c @@ -61,11 +61,11 @@ static uint32_t countMacPortsPackages(const char* dirname) { FFstrbuf baseDir; ffStrbufInitS(&baseDir, dirname); - ffStrbufAppendS(baseDir, "/var/macports/software"); + ffStrbufAppendS(&baseDir, "/var/macports/software"); - uint32_t result += getNumElements(baseDir->chars, DT_DIR); + uint32_t result = getNumElements(baseDir.chars, DT_DIR); - ffStrbufDestroy(baseDir); + ffStrbufDestroy(&baseDir); return result; } @@ -73,7 +73,7 @@ static uint32_t getMacPortsPackages() { const char* prefix = getenv("MACPORTS_PREFIX"); if(ffStrSet(prefix)) - return countMacPortsPackages(baseDir); + return countMacPortsPackages(prefix); return countMacPortsPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/local"); } diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 8839fdb16..34611328f 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -33,6 +33,6 @@ void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); result->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); if(result->scoop > 0) - result->scoop-- // scoop + result->scoop--; // scoop ffStrbufDestroy(&scoopPath); } From 2dee7f59825d57cf0f68273d9ba41f06f3ee873e Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Fri, 14 Oct 2022 10:49:08 +0200 Subject: [PATCH 076/311] Update CI --- .github/workflows/push.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 34ca25a84..e84cb1497 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -45,7 +45,7 @@ jobs: - name: get fastfetch version id: ffversion - run: echo "::set-output name=ffversion::$(./fastfetch --version-raw)" + run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT - name: upload artifacts uses: actions/upload-artifact@v3 @@ -129,8 +129,6 @@ jobs: permissions: security-events: write contents: read - outputs: - ffversion: ${{ steps.ffversion.outputs.ffversion }} defaults: run: shell: msys2 {0} @@ -164,12 +162,20 @@ jobs: Cflags: -I${includedir} EOF + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: c, cpp + - name: configure project run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . - name: build project run: cmake --build . --target fastfetch --target flashfetch # Makes no sense to install exes to /usr/bin for Windows + - name: perform CodeQL analysis + uses: github/codeql-action/analyze@v2 + - name: copy necessary dlls run: cp /usr/bin/msys-2.0.dll /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . @@ -193,8 +199,6 @@ jobs: permissions: security-events: write contents: read - outputs: - ffversion: ${{ steps.ffversion.outputs.ffversion }} defaults: run: shell: msys2 {0} @@ -228,12 +232,20 @@ jobs: Cflags: -I${includedir} EOF + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: c, cpp + - name: configure project run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . - name: build project run: cmake --build . --target fastfetch --target flashfetch + - name: perform CodeQL analysis + uses: github/codeql-action/analyze@v2 + - name: copy necessary dlls run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . From 135ca1eeba86b074124cafe02e0d60f7e68632b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 14:59:12 +0800 Subject: [PATCH 077/311] Packages: don't rely on environment variables --- src/detection/packages/packages_windows.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 34611328f..1a9fe2ade 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -30,7 +30,8 @@ void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) FF_UNUSED(instance); FFstrbuf scoopPath; - ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); + ffStrbufInitS(&scoopPath, instance->state.passwd->pw_dir); + ffStrbufAppendS(&scoopPath, "/scoop/apps/*"); result->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); if(result->scoop > 0) result->scoop--; // scoop From 779a33349a7d93795fd2e74c19a537bdfc1c4741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 16:16:43 +0800 Subject: [PATCH 078/311] OS: don't print msys2 logo for native Windows --- src/detection/os/os_windows.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index ccf7da36e..1607e0555 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -59,10 +59,11 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufClear(&os->variant); } - if(getenv("MSYSTEM")) + #ifdef __MSYS__ ffStrbufAppendS(&os->id, "MSYS2"); - else + #else ffStrbufAppendF(&os->id, "Windows %*s", os->version.length, os->version.chars); + #endif ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); From 622f84c971a3bb1173a1bc920df87a2e3d8eb835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 16:23:37 +0800 Subject: [PATCH 079/311] Kernel: remove special handling for Windows Since we have an implementation for it --- CMakeLists.txt | 2 -- src/detection/kernel/kernel.h | 18 ------------- src/detection/kernel/kernel_linux.c | 9 ------- src/detection/kernel/kernel_windows.cpp | 34 ------------------------- src/modules/kernel.c | 24 +++-------------- 5 files changed, 4 insertions(+), 83 deletions(-) delete mode 100644 src/detection/kernel/kernel.h delete mode 100644 src/detection/kernel/kernel_linux.c delete mode 100644 src/detection/kernel/kernel_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 25074c595..0a568c6c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -291,7 +291,6 @@ if(LINUX OR APPLE OR ANDROID OR BSD) src/common/processing_linux.c src/detection/disk/disk.c src/detection/terminalshell/terminalshell_linux.c - src/detection/kernel/kernel_linux.c src/detection/localip/localip_linux.c ) endif() @@ -366,7 +365,6 @@ if(MSYS OR WIN32) src/detection/font/font_windows.cpp src/detection/terminalshell/terminalshell_windows.cpp src/detection/terminalfont/terminalfont_windows.c - src/detection/kernel/kernel_windows.cpp src/detection/localip/localip_windows.c src/detection/uptime/uptime_windows.c src/util/windows/wmi.cpp diff --git a/src/detection/kernel/kernel.h b/src/detection/kernel/kernel.h deleted file mode 100644 index 1b29350f3..000000000 --- a/src/detection/kernel/kernel.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#ifndef FF_INCLUDED_detection_kernel_kernel -#define FF_INCLUDED_detection_kernel_kernel - -#include "fastfetch.h" - -typedef struct FFKernelResult -{ - FFstrbuf sysname; - FFstrbuf release; - FFstrbuf version; - FFstrbuf error; -} FFKernelResult; - -void ffDetectKernel(FFinstance* instance, FFKernelResult* result); - -#endif diff --git a/src/detection/kernel/kernel_linux.c b/src/detection/kernel/kernel_linux.c deleted file mode 100644 index 4ab70f027..000000000 --- a/src/detection/kernel/kernel_linux.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "kernel.h" - -void ffDetectKernel(FFinstance* instance, FFKernelResult* result) -{ - ffStrbufInit(&result->error); - ffStrbufInitS(&result->sysname, instance->state.utsname.sysname); - ffStrbufInitS(&result->release, instance->state.utsname.release); - ffStrbufInitS(&result->version, instance->state.utsname.version); -} diff --git a/src/detection/kernel/kernel_windows.cpp b/src/detection/kernel/kernel_windows.cpp deleted file mode 100644 index 94a06d950..000000000 --- a/src/detection/kernel/kernel_windows.cpp +++ /dev/null @@ -1,34 +0,0 @@ -extern "C" { -#include "kernel.h" -} -#include "util/windows/wmi.hpp" - -extern "C" void ffDetectKernel(FFinstance* instance, FFKernelResult* kernel) -{ - FF_UNUSED(instance); - - ffStrbufInit(&kernel->error); - - ffStrbufInitS(&kernel->sysname, "Windows_NT"); - ffStrbufInit(&kernel->release); - ffStrbufInit(&kernel->version); - - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Version FROM Win32_OperatingSystem", &kernel->error); - if(!pEnumerator) - return; - - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) - { - ffStrbufInitS(&kernel->error, "No WMI result returned"); - pEnumerator->Release(); - return; - } - - ffGetWmiObjString(pclsObj, L"Version", &kernel->release); - - pclsObj->Release(); - pEnumerator->Release(); -} diff --git a/src/modules/kernel.c b/src/modules/kernel.c index 02cece513..062b04f42 100644 --- a/src/modules/kernel.c +++ b/src/modules/kernel.c @@ -1,38 +1,22 @@ #include "fastfetch.h" #include "common/printing.h" -#include "detection/kernel/kernel.h" #define FF_KERNEL_MODULE_NAME "Kernel" #define FF_KERNEL_NUM_FORMAT_ARGS 3 void ffPrintKernel(FFinstance* instance) { - FFKernelResult result; - ffDetectKernel(instance, &result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, "%*s", result.error.length, result.error.chars); - goto exit; - } - if(instance->config.kernel.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel.key); - ffStrbufPutTo(&result.release, stdout); + puts(instance->state.utsname.release); } else { ffPrintFormat(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result.sysname}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.release}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.version} + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.release}, + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.version} }); } - -exit: - ffStrbufDestroy(&result.error); - ffStrbufDestroy(&result.sysname); - ffStrbufDestroy(&result.release); - ffStrbufDestroy(&result.version); } From 11ad7a8a3d166a8503a5e52181d89079ba523e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 16:28:03 +0800 Subject: [PATCH 080/311] TerminalShell: unify shell version detection code --- CMakeLists.txt | 3 +- src/detection/terminalshell/terminalshell.c | 64 +++++++++++++++++++ .../terminalshell/terminalshell_linux.c | 56 ++-------------- .../terminalshell/terminalshell_windows.cpp | 29 ++------- 4 files changed, 75 insertions(+), 77 deletions(-) create mode 100644 src/detection/terminalshell/terminalshell.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a568c6c0..a675706b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,6 +237,7 @@ set(LIBFASTFETCH_SRC src/detection/font/font.c src/detection/displayserver/displayserver.c src/detection/terminalfont/terminalfont.c + src/detection/terminalshell/terminalshell.c src/detection/media/media.c src/detection/packages/packages.c src/modules/break.c @@ -363,7 +364,6 @@ if(MSYS OR WIN32) src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp src/detection/font/font_windows.cpp - src/detection/terminalshell/terminalshell_windows.cpp src/detection/terminalfont/terminalfont_windows.c src/detection/localip/localip_windows.c src/detection/uptime/uptime_windows.c @@ -386,6 +386,7 @@ if(WIN32) list(APPEND LIBFASTFETCH_SRC src/common/processing_windows.c src/detection/packages/packages_windows.c + src/detection/terminalshell/terminalshell_windows.cpp src/util/windows/getline.c src/util/windows/pwd.c src/util/windows/utsname.c diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c new file mode 100644 index 000000000..606d7ad7e --- /dev/null +++ b/src/detection/terminalshell/terminalshell.c @@ -0,0 +1,64 @@ +#include "fastfetch.h" +#include "common/processing.h" + +static void getShellVersionBash(FFstrbuf* exe, FFstrbuf* version) +{ + ffProcessAppendStdOut(version, (char* const[]) { + "env", + "-i", + exe->chars, + "--norc", + "--noprofile", + "-c", + "printf \"%s\" \"$BASH_VERSION\"", + NULL + }); + ffStrbufSubstrBeforeFirstC(version, '('); +} + +static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version) +{ + ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "--version", + NULL + }); + ffStrbufSubstrBeforeLastC(version, ' '); + ffStrbufSubstrAfterFirstC(version, ' '); +} + +static void getShellVersionFishPwsh(FFstrbuf* exe, FFstrbuf* version) +{ + ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "--version", + NULL + }); + ffStrbufTrimRight(version, '\n'); + ffStrbufSubstrAfterLastC(version, ' '); +} + +static void getShellVersionNu(FFstrbuf* exe, FFstrbuf* version) +{ + ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "--version", + NULL + }); +} + +bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) +{ + bool ok = true; + if(strcasecmp(exeName, "bash") == 0 || strcasecmp(exeName, "sh") == 0) + getShellVersionBash(exe, version); + else if(strcasecmp(exeName, "zsh") == 0) + getShellVersionZsh(exe, version); + else if(strcasecmp(exeName, "fish") == 0 || strcasecmp(exeName, "pwsh") == 0) + getShellVersionFishPwsh(exe, version); + else if(strcasecmp(exeName, "nu") == 0) + getShellVersionNu(exe, version); + else + ok = false; + return ok; +} diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 534c343c7..5615f97b3 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -135,6 +135,7 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) strcasecmp(name, "fish") == 0 || strcasecmp(name, "dash") == 0 || strcasecmp(name, "pwsh") == 0 || + strcasecmp(name, "nu") == 0 || strcasecmp(name, "git-shell") == 0 ) { ffStrbufSetS(&result->shellProcessName, name); // prevent from `fishbash` @@ -236,43 +237,6 @@ static void getUserShellFromEnv(FFTerminalShellResult* result) } } -static void getShellVersionBash(FFstrbuf* exe, FFstrbuf* version) -{ - ffProcessAppendStdOut(version, (char* const[]) { - "env", - "-i", - exe->chars, - "--norc", - "--noprofile", - "-c", - "printf \"%s\" \"$BASH_VERSION\"", - NULL - }); - ffStrbufSubstrBeforeFirstC(version, '('); -} - -static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version) -{ - ffProcessAppendStdOut(version, (char* const[]) { - exe->chars, - "--version", - NULL - }); - ffStrbufSubstrBeforeLastC(version, ' '); - ffStrbufSubstrAfterFirstC(version, ' '); -} - -static void getShellVersionFish(FFstrbuf* exe, FFstrbuf* version) -{ - ffProcessAppendStdOut(version, (char* const[]) { - exe->chars, - "--version", - NULL - }); - ffStrbufTrimRight(version, '\n'); - ffStrbufSubstrAfterLastC(version, ' '); -} - static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version) { FFstrbuf command; @@ -295,26 +259,16 @@ static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* ffStrbufDestroy(&command); } +bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version); + static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) { ffStrbufClear(version); - if(strcasecmp(exeName, "bash") == 0) - getShellVersionBash(exe, version); - else if(strcasecmp(exeName, "zsh") == 0) - getShellVersionZsh(exe, version); - else if(strcasecmp(exeName, "fish") == 0 || strcasecmp(exeName, "pwsh") == 0) - getShellVersionFish(exe, version); - else + if(!fftsGetShellVersion(exe, exeName, version)) getShellVersionGeneric(exe, exeName, version); } -const FFTerminalShellResult* -#if defined(__MSYS__) || defined(_WIN32) - ffDetectTerminalShellPosix -#else - ffDetectTerminalShell -#endif -(const FFinstance* instance) +const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { FF_UNUSED(instance); diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index c2e5acf04..ed19f9099 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -50,13 +50,7 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb return true; } -static void getShellVersion(FFstrbuf* exe, FFstrbuf* version) -{ - char* const argv[] = { exe->chars, (char*)"--version", NULL }; - ffProcessAppendStdOut(version, argv); - ffStrbufTrimRight(version, '\n'); - ffStrbufSubstrAfterLastC(version, ' '); -} +extern "C" bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version); static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) { @@ -70,11 +64,11 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) if(ffStrbufEndsWithIgnCaseS(&result->shellPrettyName, ".exe")) ffStrbufSubstrBefore(&result->shellPrettyName, result->shellPrettyName.length - 4); + ffStrbufClear(&result->shellVersion); + fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion); + if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "pwsh") == 0) - { ffStrbufSetS(&result->shellPrettyName, "PowerShell"); - getShellVersion(&result->shellExe, &result->shellVersion); - } else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell") == 0) ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell"); else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell_ise") == 0) @@ -112,23 +106,8 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) return ppid; } -#ifdef __MSYS__ - extern "C" - const FFTerminalShellResult* ffDetectTerminalShellPosix(const FFinstance* instance); -#endif - const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { - #ifdef __MSYS__ - // This is hacky. - // When running inside of MSYS2, the real Windows parent process doesn't exist and we must find it in Linux way ( /proc/self/xxx ) - // When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way - if(getenv("MSYSTEM")) - return ffDetectTerminalShellPosix(instance); - #else - FF_UNUSED(instance); - #endif - static FFTerminalShellResult result; static bool init = false; if(init) From 1b7a2c2ed5ad3ad979a99d006748db07feddb8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 16:39:48 +0800 Subject: [PATCH 081/311] MSYS2: remove support MSYS2 version was built for smooth transition from POSIX api to Win32 api. It has almost identical output as Windows native version, except requiring msys runtime dll and being a bit slower. --- .github/workflows/push.yml | 71 ------------------- CMakeLists.txt | 51 +++++-------- src/common/init.c | 4 +- src/common/library.c | 2 +- src/common/library.h | 2 +- src/common/networking.c | 4 +- src/common/networking.h | 2 +- src/common/time.h | 6 +- src/detection/cpuUsage/cpuUsage.h | 2 +- src/detection/os/os_windows.cpp | 6 +- src/detection/terminalfont/terminalfont.c | 6 +- .../terminalshell/terminalshell_linux.c | 4 +- src/modules/cursor.c | 4 +- src/modules/font.c | 2 +- src/modules/icons.c | 2 +- src/modules/theme.c | 2 +- 16 files changed, 41 insertions(+), 129 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index e84cb1497..f89ea0f11 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -123,76 +123,6 @@ jobs: name: fastfetch-bsd path: ./fastfetch-*.* - msys: - name: MSYS - runs-on: windows-latest - permissions: - security-events: write - contents: read - defaults: - run: - shell: msys2 {0} - steps: - - name: checkout repository - uses: actions/checkout@v3 - - - name: setup-msys2 - uses: msys2/setup-msys2@v2 - with: - msystem: MSYS - update: true - install: git base-devel cmake gcc mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd - - - name: print msys version - run: uname -a - - # https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785 - - name: create OpenCL.pc - run: | - cat > /clang64/lib/pkgconfig/OpenCL.pc << EOF - prefix=/clang64 - exec_prefix=${prefix} - libdir=${exec_prefix}/lib - includedir=${prefix}/include - - Name: OpenCL - Description: Open Computing Language generic Installable Client Driver Loader - Version: 2022.09.30-1 - Libs: -L${libdir} -lOpenCL.dll - Cflags: -I${includedir} - EOF - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: c, cpp - - - name: configure project - run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . - - - name: build project - run: cmake --build . --target fastfetch --target flashfetch # Makes no sense to install exes to /usr/bin for Windows - - - name: perform CodeQL analysis - uses: github/codeql-action/analyze@v2 - - - name: copy necessary dlls - run: cp /usr/bin/msys-2.0.dll /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - - - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - - - name: run flashfetch - run: ./flashfetch - - - name: upload artifacts - uses: actions/upload-artifact@v3 - with: - name: fastfetch-msys - path: | - ./*.dll - ./*.exe - windows: name: Windows runs-on: windows-latest @@ -271,7 +201,6 @@ jobs: - linux - macos - bsd - - msys - windows permissions: contents: write diff --git a/CMakeLists.txt b/CMakeLists.txt index a675706b6..3f4526855 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,11 +15,11 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) -elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS AND NOT WIN32) +elseif(NOT APPLE AND NOT ANDROID AND NOT WIN32) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() -if(MSYS OR WIN32) +if(WIN32) enable_language(CXX) endif() @@ -41,7 +41,7 @@ include(CheckIncludeFile) include(CMakeDependentOption) cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS OR WIN32" OFF) +cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF) @@ -60,8 +60,8 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS OR WIN32" OFF) -cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS OR WIN32" OFF) +cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32" OFF) +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) @@ -90,7 +90,7 @@ endif() set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") -if(MSYS OR WIN32) +if(WIN32) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti") endif() @@ -102,7 +102,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) endif() set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer") -if(NOT MSYS AND NOT WIN32) +if(NOT WIN32) set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") @@ -288,8 +288,8 @@ set(LIBFASTFETCH_SRC if(LINUX OR APPLE OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC - src/detection/users/users_linux.c src/common/processing_linux.c + src/detection/users/users_linux.c src/detection/disk/disk.c src/detection/terminalshell/terminalshell_linux.c src/detection/localip/localip_linux.c @@ -345,8 +345,9 @@ if(LINUX OR BSD) ) endif() -if(MSYS OR WIN32) +if(WIN32) list(APPEND LIBFASTFETCH_SRC + src/common/processing_windows.c src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp @@ -367,29 +368,15 @@ if(MSYS OR WIN32) src/detection/terminalfont/terminalfont_windows.c src/detection/localip/localip_windows.c src/detection/uptime/uptime_windows.c - src/util/windows/wmi.cpp - - src/detection/poweradapter/poweradapter_nosupport.c - src/detection/media/media_nosupport.c - ) -endif() - -if(MSYS) - list(APPEND LIBFASTFETCH_SRC - src/common/processing_linux.c - src/detection/terminalshell/terminalshell_linux.c - src/detection/packages/packages_linux.c - ) -endif() - -if(WIN32) - list(APPEND LIBFASTFETCH_SRC - src/common/processing_windows.c src/detection/packages/packages_windows.c src/detection/terminalshell/terminalshell_windows.cpp + src/util/windows/wmi.cpp src/util/windows/getline.c src/util/windows/pwd.c src/util/windows/utsname.c + + src/detection/poweradapter/poweradapter_nosupport.c + src/detection/media/media_nosupport.c ) endif() @@ -527,15 +514,15 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" ) -elseif(MSYS OR WIN32) +elseif(WIN32) target_link_libraries(libfastfetch - PRIVATE "wbemuuid" - PRIVATE "ole32" - PRIVATE "oleaut32" PRIVATE "dwmapi" - PRIVATE "opengl32" PRIVATE "gdi32" PRIVATE "iphlpapi" + PRIVATE "ole32" + PRIVATE "oleaut32" + PRIVATE "opengl32" + PRIVATE "wbemuuid" PRIVATE "ws2_32" ) endif() diff --git a/src/common/init.c b/src/common/init.c index 00b3c687a..0427d419b 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -285,7 +285,7 @@ void ffInitInstance(FFinstance* instance) FF_THREAD_ENTRY_DECL_WRAPPER(ffConnectDisplayServer, FFinstance*) -#if !(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32)) +#if !(defined(__APPLE__) || defined(_WIN32)) #define FF_DETECT_QT_GTK 1 @@ -294,7 +294,7 @@ FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK2, FFinstance*) FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK3, FFinstance*) FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK4, FFinstance*) -#endif //!(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32)) +#endif //!(defined(__APPLE__) || defined(_WIN32)) #endif //FF_HAVE_THREADS diff --git a/src/common/library.c b/src/common/library.c index 554cc9f39..e771b8d4d 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -22,7 +22,7 @@ static void* libraryLoad(const char* path, int maxVersion) { void* result = dlopen(path, FF_DLOPEN_FLAGS); - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 // libX.dll.1 never exists on Windows, while libX-1.dll may exist FF_UNUSED(maxVersion) diff --git a/src/common/library.h b/src/common/library.h index fd12c0b05..fbbbdac44 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -16,7 +16,7 @@ #include #endif -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 #define FF_LIBRARY_EXTENSION ".dll" #elif defined(__APPLE__) #define FF_LIBRARY_EXTENSION ".dylib" diff --git a/src/common/networking.c b/src/common/networking.c index d3685a543..a5c8ed629 100644 --- a/src/common/networking.c +++ b/src/common/networking.c @@ -1,4 +1,4 @@ -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 #include #include #include @@ -31,7 +31,7 @@ FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout) { - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 static INIT_ONCE once = INIT_ONCE_STATIC_INIT; WSADATA* pData; if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData)) diff --git a/src/common/networking.h b/src/common/networking.h index f64288066..0a1b36e5d 100644 --- a/src/common/networking.h +++ b/src/common/networking.h @@ -5,7 +5,7 @@ #include "util/FFstrbuf.h" -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 typedef uintptr_t FFSockType; //SOCKET, unsigned #ifndef INVALID_SOCKET //Don't conflict with #define INVALID_SOCKET ((uintptr_t)~0) diff --git a/src/common/time.h b/src/common/time.h index 7569d40e2..a765e7834 100644 --- a/src/common/time.h +++ b/src/common/time.h @@ -4,7 +4,7 @@ #define FF_INCLUDED_common_time #include -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 #include #include #else @@ -14,7 +14,7 @@ static inline uint64_t ffTimeGetTick() //In msec { - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 return GetTickCount64(); #else struct timeval timeNow; @@ -25,7 +25,7 @@ static inline uint64_t ffTimeGetTick() //In msec static inline void ffTimeSleep(uint32_t msec) { - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 SleepEx(msec, TRUE); #else nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL); diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index 4ac03c222..126fc1a8e 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -3,7 +3,7 @@ #ifndef FF_INCLUDED_detection_cpu_cpuUsage #define FF_INCLUDED_detection_cpu_cpuUsage -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 // Disabled by default because the result does need some time to generate #define FF_DETECTION_CPUUSAGE_NOWAIT 0 #endif diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 1607e0555..aa04bb976 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -59,11 +59,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufClear(&os->variant); } - #ifdef __MSYS__ - ffStrbufAppendS(&os->id, "MSYS2"); - #else - ffStrbufAppendF(&os->id, "Windows %*s", os->version.length, os->version.chars); - #endif + ffStrbufAppendF(&os->id, "Windows %*s", os->version.length, os->version.chars); ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index c79ed7827..4d33bb78b 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -64,7 +64,7 @@ static void detectTTY(FFTerminalFontResult* terminalFont) ffStrbufDestroy(&fontName); } -#if defined(_WIN32) || defined(__MSYS__) || defined(__linux__) +#if defined(_WIN32) || defined(__linux__) #ifdef FF_HAVE_LIBCJSON #include "common/library.h" @@ -241,7 +241,7 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFon } #endif -#endif //defined(_WIN32) || defined(__MSYS__) || defined(__linux__) +#endif //defined(_WIN32) || defined(__linux__) void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); @@ -259,7 +259,7 @@ const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) detectTTY(&result); - #if defined(_WIN32) || defined(__MSYS__) || defined(__linux__) + #if defined(_WIN32) || defined(__linux__) //Used by both Linux (WSL) and Windows else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 5615f97b3..de8b85942 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -28,7 +28,7 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex assert(processName->length > 0); ffStrbufClear(exe); - #if defined(__linux__) || defined(__MSYS__) + #ifdef __linux__ char cmdlineFilePath[64]; snprintf(cmdlineFilePath, sizeof(cmdlineFilePath), "/proc/%d/cmdline", (int)pid); @@ -61,7 +61,7 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid) { const char* error = NULL; - #if defined(__linux__) || defined(__MSYS__) + #ifdef __linux__ char statFilePath[64]; snprintf(statFilePath, sizeof(statFilePath), "/proc/%d/stat", (int)pid); diff --git a/src/modules/cursor.c b/src/modules/cursor.c index e6d50d333..c7285427e 100644 --- a/src/modules/cursor.c +++ b/src/modules/cursor.c @@ -11,7 +11,7 @@ #define FF_CURSOR_MODULE_NAME "Cursor" #define FF_CURSOR_NUM_FORMAT_ARGS 2 -#if !(defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__)) +#if !(defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32)) static void printCursor(FFinstance* instance, FFstrbuf* cursorTheme, const FFstrbuf* cursorSize) { @@ -196,7 +196,7 @@ static bool printCursorFromEnv(FFinstance* instance) void ffPrintCursor(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) FF_UNUSED(instance); ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Cursor detection is not supported"); diff --git a/src/modules/font.c b/src/modules/font.c index 4223eb799..9ca20b547 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -41,7 +41,7 @@ static void printFont(const FFFontResult* font) printf("%s [User]", font->fonts[1].chars); } -#elif defined(_WIN32) || defined(__MSYS__) +#elif defined(_WIN32) static void printFont(const FFFontResult* font) { diff --git a/src/modules/icons.c b/src/modules/icons.c index c489b9a86..4597cf2e8 100644 --- a/src/modules/icons.c +++ b/src/modules/icons.c @@ -10,7 +10,7 @@ void ffPrintIcons(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) FF_UNUSED(instance); ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons, "Icons detection is not supported"); diff --git a/src/modules/theme.c b/src/modules/theme.c index 5d294c196..5c10ee485 100644 --- a/src/modules/theme.c +++ b/src/modules/theme.c @@ -10,7 +10,7 @@ void ffPrintTheme(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) FF_UNUSED(instance); ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme, "Theme detection is not supported"); From d5e00c3517a9a385937362ba8fc2234d25ca3629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 16:41:41 +0800 Subject: [PATCH 082/311] ci: package Windows artifacts; run tests on Windows --- .github/workflows/push.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index f89ea0f11..897556254 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -185,6 +185,9 @@ jobs: - name: run flashfetch run: ./flashfetch + - name: run tests + run: ctest + - name: upload artifacts uses: actions/upload-artifact@v3 with: @@ -221,4 +224,4 @@ jobs: tag: ${{ needs.linux.outputs.ffversion }} commit: ${{ github.sha }} artifactErrorsFailBuild: true - artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/* + artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/*,fastfetch-windows/* From 4bd6f2da89516e4271761b58817d990b4b0038d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 17:19:36 +0800 Subject: [PATCH 083/311] TerminalShell: add lock ( Windows ) --- .../terminalshell/terminalshell_windows.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index ed19f9099..0f72942cd 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -1,6 +1,7 @@ extern "C" { #include "terminalshell.h" #include "common/processing.h" +#include "common/thread.h" } #include "util/windows/wmi.hpp" @@ -108,10 +109,17 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { + FF_UNUSED(instance); + + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static FFTerminalShellResult result; static bool init = false; + ffThreadMutexLock(&mutex); if(init) + { + ffThreadMutexUnlock(&mutex); return &result; + } init = true; ffStrbufInit(&result.shellProcessName); @@ -131,17 +139,17 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) uint32_t ppid = GetCurrentProcessId(); if(!getProcessInfo(ppid, &ppid, nullptr, nullptr)) - return &result; + goto exit; ppid = getShellInfo(&result, ppid); if(ppid == 0) - return &result; + goto exit; // TODO: handle nested shells - ppid = getTerminalInfo(&result, ppid); - if(ppid == 0) - return &result; + getTerminalInfo(&result, ppid); +exit: + ffThreadMutexUnlock(&mutex); return &result; } From 3b541d36702481b2374f7beb69b07d546ef7568a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 18:13:19 +0800 Subject: [PATCH 084/311] Thread: fix compile errors --- src/common/thread.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/thread.h b/src/common/thread.h index 3c80f84fd..035ff9350 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -14,9 +14,9 @@ typedef SRWLOCK FFThreadMutex; static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); } static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); } - static inline void ffThreadCreateAndDetach(__stdcall unsigned (* func)(void*), void* data) { - uintptr_t newThread = _beginthreadex(func, 0, data, NULL, 0, NULL); - if(newThread != 0) + static inline void ffThreadCreateAndDetach(unsigned (__stdcall* func)(void*), void* data) { + uintptr_t newThread = _beginthreadex(NULL, 0, func, data, 0, NULL); + if(newThread) CloseHandle((HANDLE)newThread); } #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; } From 220a7d24bc9c36b087bc986e55d4ae6161a15c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 18:31:17 +0800 Subject: [PATCH 085/311] TerminalShell: detect first shell we found only. Previously we always detect login shell as current shell, which seems duplicate with userShell --- src/detection/terminalshell/terminalshell_linux.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index de8b85942..0765d1a18 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -138,8 +138,11 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) strcasecmp(name, "nu") == 0 || strcasecmp(name, "git-shell") == 0 ) { - ffStrbufSetS(&result->shellProcessName, name); // prevent from `fishbash` - getProcessInformation(pid, &result->shellProcessName, &result->shellExe, &result->shellExeName); + if (result->shellProcessName.length == 0) + { + ffStrbufSetS(&result->shellProcessName, name); + getProcessInformation(pid, &result->shellProcessName, &result->shellExe, &result->shellExeName); + } getTerminalShell(result, ppid); return; From af93157a7651f0e593ae3716f57cd3d620d0ce96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 18:38:18 +0800 Subject: [PATCH 086/311] TerminalShell: handle nested shell --- .../terminalshell/terminalshell_linux.c | 2 +- .../terminalshell/terminalshell_windows.cpp | 75 +++++++++++++++++-- 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 0765d1a18..0e80e743a 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -164,7 +164,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0 ) return; - char* term = NULL; + const char* term = NULL; //SSH if(getenv("SSH_CONNECTION") != NULL) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 0f72942cd..a6d02c612 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -57,7 +57,7 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; - if(!getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe)) + if(pid == 0 || !getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe)) return 0; result->shellExeName = result->shellExe.chars + ffStrbufLastIndexC(&result->shellExe, '\\') + 1; @@ -76,6 +76,8 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell ISE"); else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "cmd") == 0) ffStrbufSetS(&result->shellPrettyName, "Command Prompt"); + else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "nu") == 0) + ffStrbufSetS(&result->shellPrettyName, "nushell"); else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0) { ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); // Started without shell @@ -89,7 +91,7 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; - if(!getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe)) + if(pid == 0 || !getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe)) return 0; result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\'); @@ -97,6 +99,24 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe")) ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4); + if( + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "pwsh") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "cmd") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "bash") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "zsh") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "fish") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "nu") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell_ise") == 0 + ) { + //We are nested shell + ffStrbufClear(&result->terminalProcessName); + ffStrbufClear(&result->terminalPrettyName); + ffStrbufClear(&result->terminalExe); + result->terminalExeName = NULL; + return getTerminalInfo(result, ppid); + } + if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "WindowsTerminal") == 0) ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal"); else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost") == 0) @@ -107,6 +127,50 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) return ppid; } +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 + ) return; + + const char* term = NULL; + + //SSH + if(getenv("SSH_CONNECTION") != NULL) + term = getenv("SSH_TTY"); + + //Windows Terminal + if(!term && ( + getenv("WT_SESSION") != NULL || + getenv("WT_PROFILE_ID") != NULL + )) term = "Windows Terminal"; + + //Alacritty + if(!term && ( + getenv("ALACRITTY_SOCKET") != NULL || + getenv("ALACRITTY_LOG") != NULL || + getenv("ALACRITTY_WINDOW_ID") != NULL + )) term = "Alacritty"; + + //Normal Terminal + if(!term) + term = getenv("TERM"); + + if(term) + { + ffStrbufSetS(&result->terminalProcessName, term); + ffStrbufSetS(&result->terminalPrettyName, term); + ffStrbufSetS(&result->terminalExe, term); + result->terminalExeName = ""; + } +} + const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { FF_UNUSED(instance); @@ -142,12 +206,9 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) goto exit; ppid = getShellInfo(&result, ppid); - if(ppid == 0) - goto exit; - - // TODO: handle nested shells - getTerminalInfo(&result, ppid); + if(result.terminalProcessName.length == 0) + getTerminalFromEnv(&result); exit: ffThreadMutexUnlock(&mutex); From 3f4926cbd5f5ac77cb1d062296e91e24879c8e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 18:51:04 +0800 Subject: [PATCH 087/311] TerminalShell: detect platform specific terminal on correct system only --- src/detection/terminalshell/terminalshell_linux.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 0e80e743a..80ace12bd 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -183,30 +183,36 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) getenv("ALACRITTY_WINDOW_ID") != NULL )) term = "Alacritty"; + #ifdef __ANDROID__ //Termux if(!ffStrSet(term) && ( getenv("TERMUX_VERSION") != NULL || getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL || getenv("TMUX_TMPDIR") != NULL )) term = "Termux"; + #endif + #ifdef __linux__ //Konsole if(!ffStrSet(term) && ( getenv("KONSOLE_VERSION") != NULL )) term = "konsole"; + #endif //MacOS, mintty if(!ffStrSet(term)) term = getenv("TERM_PROGRAM"); - //We are in WSL but not in Windows Terminal + #ifdef __linux__ 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"; } + #endif //Normal Terminal if(!ffStrSet(term)) From 4f67ed2b77ce6a4c036c1eab7bbeb169edcb466d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 19:02:51 +0800 Subject: [PATCH 088/311] TerminalShell: add some pretty names --- .../terminalshell/terminalshell_linux.c | 17 ++++++++++++++--- src/util/FFstrbuf.h | 10 ++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 80ace12bd..e04f41f66 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -316,10 +316,21 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) else ffStrbufSet(&result.userShellVersion, &result.shellVersion); - // https://github.com/LinusDierheimer/fastfetch/discussions/280#discussioncomment-3831734 - ffStrbufInitS(&result.shellPrettyName, result.shellExeName); + if(ffStrbufEqualS(&result.shellProcessName, "pwsh")) + ffStrbufInitS(&result.shellPrettyName, "PowerShell"); + else if(ffStrbufEqualS(&result.shellProcessName, "nu")) + ffStrbufInitS(&result.shellPrettyName, "nushell"); + else + { + // https://github.com/LinusDierheimer/fastfetch/discussions/280#discussioncomment-3831734 + ffStrbufInitS(&result.shellPrettyName, result.shellExeName); + } - if(strncmp(result.terminalExeName, result.terminalProcessName.chars, result.terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName + if(ffStrbufEqualS(&result.terminalProcessName, "iTerm.app")) + ffStrbufInitS(&result.terminalPrettyName, "iTerm"); + else if(ffStrbufEqualS(&result.terminalProcessName, "Apple_Terminal")) + ffStrbufInitS(&result.terminalPrettyName, "Apple Terminal"); + 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 ffStrbufInitCopy(&result.terminalPrettyName, &result.terminalProcessName); diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 8966b569e..cfe6449d4 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -147,11 +147,21 @@ static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) return memcmp(strbuf->chars, comp->chars, length + 1); } +static inline FF_C_NODISCARD int ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) +{ + return ffStrbufComp(strbuf, comp) == 0; +} + static inline FF_C_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp) { return strcmp(strbuf->chars, comp); } +static inline FF_C_NODISCARD int ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp) +{ + return ffStrbufCompS(strbuf, comp) == 0; +} + static inline FF_C_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp) { return strcasecmp(strbuf->chars, comp); From 869f544babea6c3d6df8b12f08898c9b01fd66c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 19:40:13 +0800 Subject: [PATCH 089/311] ci: fix errors --- .github/workflows/push.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 897556254..6a41daff2 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -171,7 +171,7 @@ jobs: run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . - name: build project - run: cmake --build . --target fastfetch --target flashfetch + run: cmake --build . - name: perform CodeQL analysis uses: github/codeql-action/analyze@v2 @@ -194,7 +194,8 @@ jobs: name: fastfetch-windows path: | ./*.dll - ./*.exe + ./fastfetch.exe + ./flashfetch.exe release: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch' From 4f0dd5176117f9046112909b3016f1bf1bca975b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 14 Oct 2022 22:58:56 +0800 Subject: [PATCH 090/311] TerminalShell: fix bash version detection on Windows Currently we use `env -i /path/to/bash --norc --noprofile -c printf "%s" "$BASH_VERSION"` to detect bash version. This is problematic on Windows because there is no `env` in $PATH ( there is env in $PATH of msys2 but not in $PATH of Windows ) With this modification the detection is also faster because 1 process is created only --- src/detection/terminalshell/terminalshell.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index 606d7ad7e..e48b919a3 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -4,16 +4,14 @@ static void getShellVersionBash(FFstrbuf* exe, FFstrbuf* version) { ffProcessAppendStdOut(version, (char* const[]) { - "env", - "-i", exe->chars, - "--norc", - "--noprofile", - "-c", - "printf \"%s\" \"$BASH_VERSION\"", + "--version", NULL - }); - ffStrbufSubstrBeforeFirstC(version, '('); + }); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)\nCopyright... + ffStrbufSubstrBeforeFirstC(version, '\n'); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys) + ffStrbufSubstrBeforeLastC(version, ' '); // GNU bash, version 5.1.16(1)-release + ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16(1)-release + ffStrbufSubstrBeforeFirstC(version, '('); // 5.1.16 } static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version) From f05d036023dd6ba00155ba9325c8d3ab22e0e2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 01:02:16 +0800 Subject: [PATCH 091/311] README: update description on different platforms --- README.md | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b5282ea46..76e026e01 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, BSD, MacOS and Windows on [MSYS2](https://www.msys2.org/) 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, BSD, MacOS and Windows are supported. @@ -21,10 +21,13 @@ There are some premade config files in [`presets`](presets), including the ones ## Dependencies -Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it. +Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions. + The following libraries are used if present at runtime: -* [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html): For multithreading support, which may improve performance + +### Linux and BSD + * [`libpci`](https://github.com/pciutils/pciutils): GPU output. * [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output. * [`libxcb-randr`](https://xcb.freedesktop.org/), @@ -46,7 +49,21 @@ The following libraries are used if present at runtime: * [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count. * [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE. * [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( Windows, WSL ). -* [`freetype`](https://www.freetype.org/): Needed for Termux font detection ( Android ). + +### macOS + +* [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system. +* [`libvulkan`](https://www.vulkan.org/): Vulkan module. To get it actually working, both loader (`vulkan-loader`) and driver (molten-vk) need to be installed. + +### Windows + +* [`libcJSON`](https://github.com/DaveGamble/cJSON): Used for Windows Terminal font detection. +* [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. +* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module + +### Android + +* [`freetype`](https://www.freetype.org/): Used for Termux font detection. ## Support status All categories not listed here should work without needing a specific implementation. @@ -100,9 +117,7 @@ If pkg-config fails to find the headers for a library listed in [dependencies](# ### Building on Windows -Currently [MSYS2](https://www.msys2.org/) is required to build fastfetch. Running fastfetch requires msys2 runtime library (`msys-2.0.dll`) but not full MSYS2 environment. - -Full native Windows executable is planned. +Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 sub system is suggested (and tested) to build fastfetch. ## Packaging From a99ca9a1a1c74b91c59cb8d6362b27a18eecff2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 01:02:46 +0800 Subject: [PATCH 092/311] macOS: remove unneeded dependencies --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f4526855..1687f162c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -508,7 +508,6 @@ if(APPLE) target_link_libraries(libfastfetch PRIVATE "-framework CoreFoundation" PRIVATE "-framework IOKit" - PRIVATE "-framework CoreGraphics" PRIVATE "-framework OpenGL" PRIVATE "-framework OpenCL" PRIVATE "-framework Cocoa" From b042b90d9ba49c6feeded008d5c3141bb80567fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 11:36:24 +0800 Subject: [PATCH 093/311] TerminalShell: improve shell detection on Windows --- .../terminalshell/terminalshell_windows.cpp | 78 ++++++++++++------- src/util/FFstrbuf.h | 14 +++- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index a6d02c612..cd904f97e 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -18,13 +18,16 @@ struct ProcessInfo static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe) { wchar_t query[256] = {}; - swprintf(query, 256, L"SELECT Name, ParentProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId = %" PRIu32, pid); + swprintf(query, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32, + pname ? L"Name," : L"", + pname ? L"ExecutablePath," : L"", + pid); IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr); if(!pEnumerator) return false; - IWbemClassObject *pclsObj = NULL; + IWbemClassObject *pclsObj = nullptr; ULONG uReturn = 0; if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) @@ -65,20 +68,39 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) if(ffStrbufEndsWithIgnCaseS(&result->shellPrettyName, ".exe")) ffStrbufSubstrBefore(&result->shellPrettyName, result->shellPrettyName.length - 4); + //Common programs that are between terminal and own process, but are not the shell + if( + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "sudo") || + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "su") || + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "doas") || + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "strace") || + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "sshd") || + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "gdb") || + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "lldb") || + ffStrbufIgnCaseEqualS(&result->shellPrettyName, "guake-wrapped") || + ffStrbufContainIgnCaseS(&result->shellPrettyName, "debug") + ) { + ffStrbufClear(&result->shellProcessName); + ffStrbufClear(&result->shellPrettyName); + ffStrbufClear(&result->shellExe); + result->shellExeName = nullptr; + return getShellInfo(result, ppid); + } + ffStrbufClear(&result->shellVersion); fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion); - if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "pwsh") == 0) + if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "pwsh")) ffStrbufSetS(&result->shellPrettyName, "PowerShell"); - else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell") == 0) + else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "powershell")) ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell"); - else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell_ise") == 0) + else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "powershell_ise")) ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell ISE"); - else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "cmd") == 0) + else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "cmd")) ffStrbufSetS(&result->shellPrettyName, "Command Prompt"); - else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "nu") == 0) + else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "nu")) ffStrbufSetS(&result->shellPrettyName, "nushell"); - else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0) + else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer")) { ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); // Started without shell return 0; @@ -100,28 +122,30 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4); if( - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "pwsh") == 0 || - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "cmd") == 0 || - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "bash") == 0 || - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "zsh") == 0 || - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "fish") == 0 || - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "nu") == 0 || - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell") == 0 || - ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell_ise") == 0 + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "pwsh") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "cmd") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "bash") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "zsh") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "fish") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "nu") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell_ise") ) { //We are nested shell ffStrbufClear(&result->terminalProcessName); ffStrbufClear(&result->terminalPrettyName); ffStrbufClear(&result->terminalExe); - result->terminalExeName = NULL; + result->terminalExeName = nullptr; return getTerminalInfo(result, ppid); } - if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "WindowsTerminal") == 0) + if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "WindowsTerminal")) ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal"); - else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost") == 0) + else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "conhost")) ffStrbufSetS(&result->terminalPrettyName, "Console Window Host"); - else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0) + else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "Code")) + ffStrbufSetS(&result->terminalPrettyName, "Visual Studio Code"); + else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer")) ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); return ppid; @@ -139,23 +163,23 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0 ) return; - const char* term = NULL; + const char* term = nullptr; //SSH - if(getenv("SSH_CONNECTION") != NULL) + if(getenv("SSH_CONNECTION") != nullptr) term = getenv("SSH_TTY"); //Windows Terminal if(!term && ( - getenv("WT_SESSION") != NULL || - getenv("WT_PROFILE_ID") != NULL + getenv("WT_SESSION") != nullptr || + getenv("WT_PROFILE_ID") != nullptr )) term = "Windows Terminal"; //Alacritty if(!term && ( - getenv("ALACRITTY_SOCKET") != NULL || - getenv("ALACRITTY_LOG") != NULL || - getenv("ALACRITTY_WINDOW_ID") != NULL + getenv("ALACRITTY_SOCKET") != nullptr || + getenv("ALACRITTY_LOG") != nullptr || + getenv("ALACRITTY_WINDOW_ID") != nullptr )) term = "Alacritty"; //Normal Terminal diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index cfe6449d4..11ce0518b 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -147,7 +147,7 @@ static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) return memcmp(strbuf->chars, comp->chars, length + 1); } -static inline FF_C_NODISCARD int ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) +static inline FF_C_NODISCARD bool ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) { return ffStrbufComp(strbuf, comp) == 0; } @@ -157,7 +157,7 @@ static inline FF_C_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const cha return strcmp(strbuf->chars, comp); } -static inline FF_C_NODISCARD int ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp) +static inline FF_C_NODISCARD bool ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp) { return ffStrbufCompS(strbuf, comp) == 0; } @@ -167,11 +167,21 @@ static inline FF_C_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, co return strcasecmp(strbuf->chars, comp); } +static inline FF_C_NODISCARD bool ffStrbufIgnCaseEqualS(const FFstrbuf* strbuf, const char* comp) +{ + return ffStrbufIgnCaseCompS(strbuf, comp) == 0; +} + static inline FF_C_NODISCARD int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp) { return ffStrbufIgnCaseCompS(strbuf, comp->chars); } +static inline FF_C_NODISCARD bool ffStrbufIgnCaseEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) +{ + return ffStrbufIgnCaseComp(strbuf, comp) == 0; +} + static inline FF_C_NODISCARD bool ffStrbufContainS(const FFstrbuf* strbuf, const char* str) { return strstr(strbuf->chars, str) != NULL; From 5749a8f7c193b6a86f5fb15dd4b19bea9c6aba2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 19:51:33 +0800 Subject: [PATCH 094/311] TerminalShell: improve speed on Windows [NtQueryInformationProcess](https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess) is an internal NT syscall which may change in the future. However, unlike other NT syscalls NtQueryInformationProcess is well documented on MSDN, so I think it's safe to use. Boost shell detection by 0.3s on my machine. Note querying PowerShell's version `pwsh --version` costs another 0.2s --- CMakeLists.txt | 5 ++ .../terminalshell/terminalshell_windows.cpp | 87 +++++++++++++++---- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1687f162c..880839700 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ 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) 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 @@ -523,7 +524,11 @@ elseif(WIN32) PRIVATE "opengl32" PRIVATE "wbemuuid" PRIVATE "ws2_32" + PRIVATE "ntdll" ) + if(USE_WIN_FAST_PPID_DETECTION) + target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_FAST_PPID_DETECTION) + endif() endif() target_include_directories(libfastfetch diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index cd904f97e..71a34c6ea 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -3,20 +3,68 @@ extern "C" { #include "common/processing.h" #include "common/thread.h" } -#include "util/windows/wmi.hpp" #include #include #include -struct ProcessInfo -{ - uint32_t pid; - FFstrbuf psName; -}; +#include -static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe) +#ifdef FF_USE_WIN_FAST_PPID_DETECTION + +#include + +static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName) { + HANDLE hProcess = pid == 0 + ? GetCurrentProcess() + : OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, TRUE, pid); + + if(ppid) + { + PROCESS_BASIC_INFORMATION info; + ULONG size; + if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &info, sizeof(info), &size))) + { + assert(size == sizeof(info)); + *ppid = (uint32_t)info.InheritedFromUniqueProcessId; + } + else + { + CloseHandle(hProcess); + return false; + } + } + if(exe) + { + DWORD bufSize = exe->allocated; + if(QueryFullProcessImageNameA(hProcess, 0, exe->chars, &bufSize)) + exe->length = bufSize; + else + { + CloseHandle(hProcess); + return false; + } + } + if(pname && exeName) + { + *exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1; + ffStrbufSetS(pname, *exeName); + } + + CloseHandle(hProcess); + return true; +} + +#else + +#include "util/windows/wmi.hpp" + +static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName) +{ + if(pid == 0) + pid = GetCurrentProcessId(); + wchar_t query[256] = {}; swprintf(query, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32, pname ? L"Name," : L"", @@ -49,20 +97,26 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb if(exe) ffGetWmiObjString(pclsObj, L"ExecutablePath", exe); + if(exeName) + { + *exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1; + } + pclsObj->Release(); pEnumerator->Release(); return true; } +#endif + extern "C" bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version); static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; - if(pid == 0 || !getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe)) + if(pid == 0 || !getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe, &result->shellExeName)) return 0; - result->shellExeName = result->shellExe.chars + ffStrbufLastIndexC(&result->shellExe, '\\') + 1; ffStrbufSet(&result->shellPrettyName, &result->shellProcessName); if(ffStrbufEndsWithIgnCaseS(&result->shellPrettyName, ".exe")) @@ -113,9 +167,8 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; - if(pid == 0 || !getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe)) + if(pid == 0 || !getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName)) return 0; - result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\'); ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName); if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe")) @@ -135,7 +188,7 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufClear(&result->terminalProcessName); ffStrbufClear(&result->terminalPrettyName); ffStrbufClear(&result->terminalExe); - result->terminalExeName = nullptr; + result->terminalExeName = ""; return getTerminalInfo(result, ppid); } @@ -212,21 +265,21 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) ffStrbufInit(&result.shellProcessName); ffStrbufInitA(&result.shellExe, 128); - result.shellExeName = result.shellExe.chars; + result.shellExeName = ""; ffStrbufInit(&result.shellPrettyName); ffStrbufInit(&result.shellVersion); ffStrbufInit(&result.terminalProcessName); ffStrbufInitA(&result.terminalExe, 128); - result.terminalExeName = result.terminalExe.chars; + result.terminalExeName = ""; ffStrbufInit(&result.terminalPrettyName); ffStrbufInit(&result.userShellExe); - result.userShellExeName = result.userShellExe.chars; + result.userShellExeName = ""; ffStrbufInit(&result.userShellVersion); - uint32_t ppid = GetCurrentProcessId(); - if(!getProcessInfo(ppid, &ppid, nullptr, nullptr)) + uint32_t ppid; + if(!getProcessInfo(0, &ppid, nullptr, nullptr, nullptr)) goto exit; ppid = getShellInfo(&result, ppid); From 437431a8212c1c937c92456f891b8df542a4b1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 21:44:28 +0800 Subject: [PATCH 095/311] TerminalShell: support Windows PowerShell version detection --- src/detection/terminalshell/terminalshell.c | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index e48b919a3..260b28faa 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -36,6 +36,22 @@ static void getShellVersionFishPwsh(FFstrbuf* exe, FFstrbuf* version) ffStrbufSubstrAfterLastC(version, ' '); } +#ifdef _WIN32 +static void getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) +{ + ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "-NoLogo", + "-NoProfile", + "-Command", + "$PSVersionTable.PSVersion.ToString()", + NULL + }); + ffStrbufTrimRight(version, '\n'); + ffStrbufSubstrAfterLastC(version, ' '); +} +#endif + static void getShellVersionNu(FFstrbuf* exe, FFstrbuf* version) { ffProcessAppendStdOut(version, (char* const[]) { @@ -56,6 +72,12 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) getShellVersionFishPwsh(exe, version); else if(strcasecmp(exeName, "nu") == 0) getShellVersionNu(exe, version); + + #ifdef _WIN32 + else if(strcasecmp(exeName, "powershell") == 0 || strcasecmp(exeName, "powershell_ise") == 0) + getShellVersionWinPowerShell(exe, version); + #endif + else ok = false; return ok; From c1fc6e27627bdf56e49d3aa4570a1ea2a028d42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 21:59:50 +0800 Subject: [PATCH 096/311] Processing: handle a possible error --- src/common/processing_windows.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 9ec6da811..cd091ac6c 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -28,7 +28,7 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) }; FFstrbuf cmdline; - ffStrbufInitS(&cmdline, argv[0]); + ffStrbufInitF(&cmdline, "\"%s\"", argv[0]); for(char* const* parg = &argv[1]; *parg; ++parg) { ffStrbufAppendC(&cmdline, ' '); From 76684e49cadf95bf926298313ea7f881d905ab64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 22:35:04 +0800 Subject: [PATCH 097/311] TerminalShell: speed up PowerShell version detection by querying the version of pwsh.exe file Also add cmd version detection --- CMakeLists.txt | 1 + src/detection/terminalshell/terminalshell.c | 66 ++++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 880839700..1d0cf1b4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -525,6 +525,7 @@ elseif(WIN32) PRIVATE "wbemuuid" PRIVATE "ws2_32" PRIVATE "ntdll" + PRIVATE "version" ) if(USE_WIN_FAST_PPID_DETECTION) target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_FAST_PPID_DETECTION) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index 260b28faa..f4141a6b2 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -1,6 +1,41 @@ #include "fastfetch.h" #include "common/processing.h" +#ifdef _WIN32 + +#include + +static bool getFileVersion(const char* exePath, FFstrbuf* version) +{ + DWORD handle; + DWORD size = GetFileVersionInfoSizeA(exePath, &handle); + if(size > 0) + { + void* versionData = malloc(size); + if(GetFileVersionInfoA(exePath, handle, size, versionData)) + { + VS_FIXEDFILEINFO* verInfo; + UINT len; + if(VerQueryValueW(versionData, L"\\", (void**)&verInfo, &len) && len && verInfo->dwSignature == 0xFEEF04BD) + { + ffStrbufAppendF(version, "%u.%u.%u.%u", + (unsigned)(( verInfo->dwFileVersionMS >> 16 ) & 0xffff), + (unsigned)(( verInfo->dwFileVersionMS >> 0 ) & 0xffff), + (unsigned)(( verInfo->dwFileVersionLS >> 16 ) & 0xffff), + (unsigned)(( verInfo->dwFileVersionLS >> 0 ) & 0xffff) + ); + free(versionData); + return true; + } + } + free(versionData); + } + + return false; +} + +#endif + static void getShellVersionBash(FFstrbuf* exe, FFstrbuf* version) { ffProcessAppendStdOut(version, (char* const[]) { @@ -25,7 +60,7 @@ static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version) ffStrbufSubstrAfterFirstC(version, ' '); } -static void getShellVersionFishPwsh(FFstrbuf* exe, FFstrbuf* version) +static void getShellVersionFish(FFstrbuf* exe, FFstrbuf* version) { ffProcessAppendStdOut(version, (char* const[]) { exe->chars, @@ -36,6 +71,22 @@ static void getShellVersionFishPwsh(FFstrbuf* exe, FFstrbuf* version) ffStrbufSubstrAfterLastC(version, ' '); } +static void getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version) +{ + #ifdef _WIN32 + if(getFileVersion(exe->chars, version)) + return; + #endif + + ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "--version", + NULL + }); + ffStrbufTrimRight(version, '\n'); + ffStrbufSubstrAfterLastC(version, ' '); +} + #ifdef _WIN32 static void getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) { @@ -50,6 +101,11 @@ static void getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); } + +static void getShellVersionCmd(FFstrbuf* exe, FFstrbuf* version) +{ + getFileVersion(exe->chars, version); +} #endif static void getShellVersionNu(FFstrbuf* exe, FFstrbuf* version) @@ -68,14 +124,18 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) getShellVersionBash(exe, version); else if(strcasecmp(exeName, "zsh") == 0) getShellVersionZsh(exe, version); - else if(strcasecmp(exeName, "fish") == 0 || strcasecmp(exeName, "pwsh") == 0) - getShellVersionFishPwsh(exe, version); + else if(strcasecmp(exeName, "fish") == 0) + getShellVersionFish(exe, version); + else if(strcasecmp(exeName, "pwsh") == 0) + getShellVersionPwsh(exe, version); else if(strcasecmp(exeName, "nu") == 0) getShellVersionNu(exe, version); #ifdef _WIN32 else if(strcasecmp(exeName, "powershell") == 0 || strcasecmp(exeName, "powershell_ise") == 0) getShellVersionWinPowerShell(exe, version); + else if(strcasecmp(exeName, "cmd") == 0) + getShellVersionCmd(exe, version); #endif else From a090bed6c004c2b98b759105776c67bacc292779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 15 Oct 2022 23:46:00 +0800 Subject: [PATCH 098/311] Logo: try printing logo on Windows Server Completely untested --- src/detection/os/os_windows.cpp | 14 +++++++++++++- src/logo/builtin.c | 6 +++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index aa04bb976..c6dd9977e 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -51,6 +51,18 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) 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 { @@ -59,7 +71,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufClear(&os->variant); } - ffStrbufAppendF(&os->id, "Windows %*s", os->version.length, os->version.chars); + ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars); ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 86376c7fa..e11dc0954 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1280,7 +1280,7 @@ static const FFlogo* getLogoMsys2() static const FFlogo* getLogoWindows11() { FF_LOGO_INIT - FF_LOGO_NAMES("Windows 11") + FF_LOGO_NAMES("Windows 11", "Windows Server 2022") FF_LOGO_LINES( "$1\n" "################ ################\n" @@ -1310,7 +1310,7 @@ static const FFlogo* getLogoWindows11() static const FFlogo* getLogoWindows8() { FF_LOGO_INIT - FF_LOGO_NAMES("Windows 8", "Windows 8.1", "Windows 10") + FF_LOGO_NAMES("Windows 8", "Windows 8.1", "Windows 10", "Windows Server 2012", "Windows Server 2012 R2", "Windows Server 2016", "Windows Server 2019") FF_LOGO_LINES( "$1 ..,\n" " ....,,:;+ccllll\n" @@ -1343,7 +1343,7 @@ static const FFlogo* getLogoWindows8() static const FFlogo* getLogoWindows() { FF_LOGO_INIT - FF_LOGO_NAMES("Windows") + FF_LOGO_NAMES("Windows", "Windows 7", "Windows Server 2008", "Windows Server 2008 R2") FF_LOGO_LINES( "$1 ,.=:!!t3Z3z.,\n" " :tt:::tt333EE3\n" From a829e85ef5271be028824a72ebcc3ee18446e329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 16 Oct 2022 01:34:26 +0800 Subject: [PATCH 099/311] LocalIP: support --localip-name-prefix on Windows --- src/detection/localip/localip_windows.c | 27 +++++++++---------------- src/modules/localip.c | 5 ++++- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c index 275987f10..e23a32fe8 100644 --- a/src/detection/localip/localip_windows.c +++ b/src/detection/localip/localip_windows.c @@ -5,24 +5,10 @@ #include "localip.h" -static void addNewIp(FFlist* list, const wchar_t* name, const char* addr, bool ipv6) +static void addNewIp(FFlist* list, const char* name, const char* addr, bool ipv6) { FFLocalIpResult* ip = (FFLocalIpResult*) ffListAdd(list); - - int len = (int)wcslen(name); - if(len > 0) - { - int size_needed = WideCharToMultiByte(CP_UTF8, 0, name, len, NULL, 0, NULL, NULL); - ffStrbufInitA(&ip->name, (uint32_t)size_needed + 1); - WideCharToMultiByte(CP_UTF8, 0, name, len, ip->name.chars, size_needed, NULL, NULL); - ip->name.length = (uint32_t)size_needed; - ip->name.chars[size_needed] = '\0'; - } - else - { - ffStrbufInitS(&ip->name, "*"); - } - + ffStrbufInitS(&ip->name, name); ffStrbufInitS(&ip->addr, addr); ip->ipv6 = ipv6; } @@ -64,6 +50,11 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK && !instance->config.localIpShowLoop) continue; + char name[128]; + WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, sizeof(name), NULL, NULL); + if (instance->config.localIpNamePrefix.length && strncmp(name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0) + continue; + for (IP_ADAPTER_UNICAST_ADDRESS* ifa = adapter->FirstUnicastAddress; ifa; ifa = ifa->Next) { if (ifa->Address.lpSockaddr->sa_family == AF_INET) @@ -75,7 +66,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr; char addressBuffer[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN); - addNewIp(results, adapter->FriendlyName, addressBuffer, false); + addNewIp(results, name, addressBuffer, false); } else if (ifa->Address.lpSockaddr->sa_family == AF_INET6) { @@ -86,7 +77,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr; char addressBuffer[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN); - addNewIp(results, adapter->FriendlyName, addressBuffer, false); + addNewIp(results, name, addressBuffer, false); } } } diff --git a/src/modules/localip.c b/src/modules/localip.c index 07508f3bd..89df09962 100644 --- a/src/modules/localip.c +++ b/src/modules/localip.c @@ -33,7 +33,10 @@ void ffPrintLocalIp(FFinstance* instance) if(instance->config.localIP.key.length == 0) { - ffStrbufSetF(&key, FF_LOCALIP_MODULE_NAME " (%*s)", ip->name.length, ip->name.chars); + if(ip->name.length) + ffStrbufSetF(&key, FF_LOCALIP_MODULE_NAME " (%*s)", ip->name.length, ip->name.chars); + else + ffStrbufSetS(&key, FF_LOCALIP_MODULE_NAME); } else { From 2499cbdab8dc8b032a36a16f51f30ed1caca28f3 Mon Sep 17 00:00:00 2001 From: VitoFe Date: Sat, 15 Oct 2022 18:05:21 +0000 Subject: [PATCH 100/311] Add Garuda small variant --- src/logo/builtin.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index e11dc0954..cbc16ae4b 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -863,6 +863,25 @@ static const FFlogo* getLogoGaruda() FF_LOGO_RETURN } +static const FFlogo* getLogoGarudaSmall() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("garuda_small", "garudalinux_small", "garuda-linux-small") + FF_LOGO_LINES( + " .----.\n" + " .' , '.\n" + " .' '-----|\n" + "'. -----,\n" + " '.____.'" + ) + FF_LOGO_COLORS( + "31" //red + ) + FF_LOGO_COLOR_KEYS("31"); //red + FF_LOGO_COLOR_TITLE("31"); //red + FF_LOGO_RETURN +} + static const FFlogo* getLogoGentoo() { FF_LOGO_INIT @@ -2098,6 +2117,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoFedoraOld, getLogoFreeBSD, getLogoGaruda, + getLogoGarudaSmall, getLogoGentoo, getLogoGentooSmall, getLogoKDENeon, From 5d5663e2a785994dc25be235236aa69f11cab050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 16 Oct 2022 21:44:09 +0800 Subject: [PATCH 101/311] Kernel: fix detection on Windows According to MSDN, GetVersionExA is not reliable. We have to query WMI instead. --- CMakeLists.txt | 2 +- src/util/windows/utsname.c | 59 ------------------------------------ src/util/windows/utsname.cpp | 43 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 60 deletions(-) delete mode 100644 src/util/windows/utsname.c create mode 100644 src/util/windows/utsname.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d0cf1b4d..ce3a3a99b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -374,7 +374,7 @@ if(WIN32) src/util/windows/wmi.cpp src/util/windows/getline.c src/util/windows/pwd.c - src/util/windows/utsname.c + src/util/windows/utsname.cpp src/detection/poweradapter/poweradapter_nosupport.c src/detection/media/media_nosupport.c diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c deleted file mode 100644 index 403f5e6fd..000000000 --- a/src/util/windows/utsname.c +++ /dev/null @@ -1,59 +0,0 @@ -// https://github.com/tniessen/iperf-windows/blob/master/win32-compat/sys/utsname.c - -#define WIN32_LEAN_AND_MEAN -#include - -#include - -#include "utsname.h" - -int uname(struct utsname *name) -{ - memset(name, 0, sizeof(*name)); - - // Get Windows version info - OSVERSIONINFOA versionInfo = { - .dwOSVersionInfoSize = sizeof(OSVERSIONINFO), - }; - GetVersionExA(&versionInfo); - - // Get hardware info - SYSTEM_INFO sysInfo = {0}; - GetSystemInfo(&sysInfo); - - // Set implementation name - strcpy(name->sysname, "Windows_NT"); - sprintf(name->release, "%u.%u.%u", (unsigned)versionInfo.dwMajorVersion, (unsigned)versionInfo.dwMinorVersion, (unsigned)versionInfo.dwBuildNumber); - name->version[0] = '\0'; - - // Set hostname - DWORD bufSize = UTSNAME_MAXLENGTH - 1; - if(GetComputerNameA(name->nodename, &bufSize)) - return 1; - name->nodename[bufSize] = '\0'; - - // Set processor architecture - switch (sysInfo.wProcessorArchitecture) - { - case PROCESSOR_ARCHITECTURE_AMD64: - strcpy(name->machine, "x86_64"); - break; - case PROCESSOR_ARCHITECTURE_IA64: - strcpy(name->machine, "ia64"); - break; - case PROCESSOR_ARCHITECTURE_INTEL: - strcpy(name->machine, "x86"); - break; - case PROCESSOR_ARCHITECTURE_ARM64: - strcpy(name->machine, "aarch64"); - break; - case PROCESSOR_ARCHITECTURE_ARM: - strcpy(name->machine, "arm"); - break; - case PROCESSOR_ARCHITECTURE_UNKNOWN: - default: - strcpy(name->machine, "unknown"); - } - - return 0; -} diff --git a/src/util/windows/utsname.cpp b/src/util/windows/utsname.cpp new file mode 100644 index 000000000..4d1036d52 --- /dev/null +++ b/src/util/windows/utsname.cpp @@ -0,0 +1,43 @@ +#include "util/windows/wmi.hpp" +extern "C" { + #include "utsname.h" +} + +int uname(struct utsname *name) +{ + memset(name, 0, sizeof(*name)); + + strncpy(name->sysname, "Windows_NT", UTSNAME_MAXLENGTH); + + IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Version, CSName, OSArchitecture FROM Win32_OperatingSystem", nullptr); + if(!pEnumerator) + return -1; + + IWbemClassObject *pclsObj = NULL; + ULONG uReturn = 0; + + if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + { + pEnumerator->Release(); + return -1; + } + + FFstrbuf value; + ffStrbufInit(&value); + ffGetWmiObjString(pclsObj, L"Version", &value); + strncpy(name->release, value.chars, UTSNAME_MAXLENGTH); + + ffStrbufClear(&value); + ffGetWmiObjString(pclsObj, L"CSName", &value); + strncpy(name->nodename, value.chars, UTSNAME_MAXLENGTH); + + ffStrbufClear(&value); + ffGetWmiObjString(pclsObj, L"OSArchitecture", &value); + strncpy(name->machine, value.chars, UTSNAME_MAXLENGTH); + + ffStrbufDestroy(&value); + pclsObj->Release(); + pEnumerator->Release(); + + return 0; +} From 38b3aae1e334a9feb1ff4e1641c9a55af8d9c5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 16 Oct 2022 23:58:13 +0800 Subject: [PATCH 102/311] Windows: simplify WMI query code by making C++ code more C++ --- src/detection/battery/battery_windows.cpp | 21 ++--- src/detection/bios/bios_windows.cpp | 28 ++---- src/detection/board/board_windows.cpp | 26 ++---- src/detection/cpu/cpu_windows.cpp | 45 ++++----- .../cpuUsage/cpuUsage_nowait_windows.cpp | 20 ++-- src/detection/font/font_windows.cpp | 42 ++++----- src/detection/gpu/gpu_windows.cpp | 18 ++-- src/detection/host/host_windows.cpp | 26 ++---- src/detection/memory/memory_windows.cpp | 62 +++++-------- src/detection/os/os_windows.cpp | 92 +++++++++---------- src/detection/processes/processes_windows.cpp | 23 ++--- .../terminalshell/terminalshell_windows.cpp | 51 ++++------ src/detection/users/users_windows.cpp | 15 +-- src/util/windows/utsname.cpp | 42 ++++----- src/util/windows/wmi.cpp | 36 +++++--- src/util/windows/wmi.hpp | 53 +++++++---- 16 files changed, 254 insertions(+), 346 deletions(-) diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp index fce0b5657..a3c2accf0 100644 --- a/src/detection/battery/battery_windows.cpp +++ b/src/detection/battery/battery_windows.cpp @@ -8,26 +8,23 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) FF_UNUSED(instance); //https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery", nullptr); + FFWmiQuery query(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery"); - if(!pEnumerator) + if(!query) return "Query WMI service failed"; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + while(FFWmiRecord record = query.next()) { BatteryResult* battery = (BatteryResult*)ffListAdd(results); ffStrbufInit(&battery->manufacturer); - ffGetWmiObjString(pclsObj, L"SystemName", &battery->manufacturer); + record.getString(L"SystemName", &battery->manufacturer); ffStrbufInit(&battery->modelName); - ffGetWmiObjString(pclsObj, L"Name", &battery->modelName); + record.getString(L"Name", &battery->modelName); uint64_t chemistry = 0; - ffGetWmiObjUnsigned(pclsObj, L"Chemistry", &chemistry); + record.getUnsigned(L"Chemistry", &chemistry); switch(chemistry) { case 1: ffStrbufInitS(&battery->technology, "Other"); break; @@ -42,11 +39,11 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) } uint64_t capacity; - ffGetWmiObjUnsigned(pclsObj, L"EstimatedChargeRemaining", &capacity); + record.getUnsigned(L"EstimatedChargeRemaining", &capacity); ffStrbufInitF(&battery->capacity, "%d", (int)capacity); uint64_t batteryStatus; - ffGetWmiObjUnsigned(pclsObj, L"BatteryStatus", &batteryStatus); + record.getUnsigned(L"BatteryStatus", &batteryStatus); switch(batteryStatus) { case 1: ffStrbufInitS(&battery->status, "Discharging"); break; @@ -66,7 +63,5 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) battery->temperature = FF_BATTERY_TEMP_UNSET; } - if(pclsObj) pclsObj->Release(); - pEnumerator->Release(); return nullptr; } diff --git a/src/detection/bios/bios_windows.cpp b/src/detection/bios/bios_windows.cpp index d04726ebb..a48d5d538 100644 --- a/src/detection/bios/bios_windows.cpp +++ b/src/detection/bios/bios_windows.cpp @@ -12,27 +12,17 @@ extern "C" void ffDetectBios(FFBiosResult* bios) ffStrbufInit(&bios->biosVendor); ffStrbufInit(&bios->biosVersion); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error); - if(!pEnumerator) + FFWmiQuery query(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); - - if(uReturn == 0) + if(FFWmiRecord record = query.next()) { - ffStrbufInitS(&bios->error, "No Wmi result returned"); - pEnumerator->Release(); - return; + record.getString(L"Name", &bios->biosRelease); + record.getString(L"ReleaseDate", &bios->biosDate); + record.getString(L"Version", &bios->biosVersion); + record.getString(L"Manufacturer", &bios->biosVendor); } - - ffGetWmiObjString(pclsObj, L"Name", &bios->biosRelease); - ffGetWmiObjString(pclsObj, L"ReleaseDate", &bios->biosDate); - ffGetWmiObjString(pclsObj, L"Version", &bios->biosVersion); - ffGetWmiObjString(pclsObj, L"Manufacturer", &bios->biosVendor); - - pclsObj->Release(); - pEnumerator->Release(); + else + ffStrbufInitS(&bios->error, "No Wmi result returned"); } diff --git a/src/detection/board/board_windows.cpp b/src/detection/board/board_windows.cpp index 895d6f8ed..e0f92bcf5 100644 --- a/src/detection/board/board_windows.cpp +++ b/src/detection/board/board_windows.cpp @@ -11,26 +11,16 @@ extern "C" void ffDetectBoard(FFBoardResult* board) ffStrbufInit(&board->boardVendor); ffStrbufInit(&board->boardVersion); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error); - if(!pEnumerator) + FFWmiQuery query(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); - - if(uReturn == 0) + if(FFWmiRecord record = query.next()) { - ffStrbufInitS(&board->error, "No Wmi result returned"); - pEnumerator->Release(); - return; + record.getString(L"Product", &board->boardName); + record.getString(L"Manufacturer", &board->boardVendor); + record.getString(L"Version", &board->boardVersion); } - - ffGetWmiObjString(pclsObj, L"Product", &board->boardName); - ffGetWmiObjString(pclsObj, L"Manufacturer", &board->boardVendor); - ffGetWmiObjString(pclsObj, L"Version", &board->boardVersion); - - pclsObj->Release(); - pEnumerator->Release(); + else + ffStrbufInitS(&board->error, "No Wmi result returned"); } diff --git a/src/detection/cpu/cpu_windows.cpp b/src/detection/cpu/cpu_windows.cpp index 250212cfc..8740fa4b9 100644 --- a/src/detection/cpu/cpu_windows.cpp +++ b/src/detection/cpu/cpu_windows.cpp @@ -17,35 +17,26 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) ffStrbufInit(&cpu->name); ffStrbufInit(&cpu->vendor); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, ThreadCount, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3", nullptr); - if(!pEnumerator) + FFWmiQuery query(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, ThreadCount, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3"); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - pEnumerator->Release(); - return; + 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; + record.getUnsigned(L"ThreadCount", &value); + cpu->coresOnline = (uint16_t)value; + 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; } - - ffGetWmiObjString(pclsObj, L"Name", &cpu->name); - ffGetWmiObjString(pclsObj, L"Manufacturer", &cpu->vendor); - - uint64_t value; - - ffGetWmiObjUnsigned(pclsObj, L"NumberOfCores", &value); - cpu->coresPhysical = (uint16_t)value; - ffGetWmiObjUnsigned(pclsObj, L"NumberOfLogicalProcessors", &value); - cpu->coresLogical = (uint16_t)value; - ffGetWmiObjUnsigned(pclsObj, L"ThreadCount", &value); - cpu->coresOnline = (uint16_t)value; - ffGetWmiObjUnsigned(pclsObj, L"CurrentClockSpeed", &value); //There's no MinClockSpeed in Win32_Processor - cpu->frequencyMin = (double)value / 1000.0; - ffGetWmiObjUnsigned(pclsObj, L"MaxClockSpeed", &value); - cpu->frequencyMax = (double)value / 1000.0; - - pclsObj->Release(); - pEnumerator->Release(); } diff --git a/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp b/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp index 19af6ffbe..7ef1aa855 100644 --- a/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp +++ b/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp @@ -5,22 +5,14 @@ extern "C" { extern "C" const char* ffGetCpuUsageResultNoWait(double* result) { - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT LoadPercentage FROM Win32_Processor", nullptr); - if(!pEnumerator) + FFWmiQuery query(L"SELECT LoadPercentage FROM Win32_Processor"); + if(!query) return "Query WMI service failed"; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) - { - pEnumerator->Release(); + if(FFWmiRecord record = query.next()) + record.getReal(L"LoadPercentage", result); + else return "No WMI result returned"; - } - ffGetWmiObjReal(pclsObj, L"LoadPercentage", result); - - pclsObj->Release(); - pEnumerator->Release(); - return NULL; + return nullptr; } diff --git a/src/detection/font/font_windows.cpp b/src/detection/font/font_windows.cpp index 0ade9812e..3d883bd58 100644 --- a/src/detection/font/font_windows.cpp +++ b/src/detection/font/font_windows.cpp @@ -9,34 +9,26 @@ extern "C" { extern "C" void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) { - wchar_t query[256] = {}; - swprintf(query, 256, L"SELECT IconTitleFaceName, IconTitleSize FROM Win32_Desktop WHERE Name LIKE '%%\\\\%s'", instance->state.passwd->pw_name); + wchar_t sql[256] = {}; + swprintf(sql, 256, L"SELECT IconTitleFaceName, IconTitleSize FROM Win32_Desktop WHERE Name LIKE '%%\\\\%s'", instance->state.passwd->pw_name); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, &result->error); - if(!pEnumerator) + FFWmiQuery query(sql, &result->error); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - ffStrbufInitS(&result->error, "No WMI result returned"); - pEnumerator->Release(); - return; + FFstrbuf 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); + + ffStrbufDestroy(&fontName); } - - FFstrbuf fontName; - ffStrbufInit(&fontName); - ffGetWmiObjString(pclsObj, L"IconTitleFaceName", &fontName); - - uint64_t fontSize; - ffGetWmiObjUnsigned(pclsObj, L"IconTitleSize", &fontSize); - - ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize); - - ffStrbufDestroy(&fontName); - - pclsObj->Release(); - pEnumerator->Release(); + else + ffStrbufInitS(&result->error, "No WMI result returned"); } diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index d99885633..374c8e035 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -8,20 +8,16 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) { FF_UNUSED(instance); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr); - - if(!pEnumerator) + FFWmiQuery query(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr); + if(!query) return "Query WMI service failed"; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + while(FFWmiRecord record = query.next()) { FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); ffStrbufInit(&gpu->vendor); - ffGetWmiObjString(pclsObj, L"AdapterCompatibility", &gpu->vendor); + record.getString(L"AdapterCompatibility", &gpu->vendor); if(ffStrbufStartsWithS(&gpu->vendor, "Intel ")) { //Intel returns "Intel Corporation", not sure about AMD @@ -29,16 +25,14 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) } ffStrbufInit(&gpu->name); - ffGetWmiObjString(pclsObj, L"Name", &gpu->name); + record.getString(L"Name", &gpu->name); ffStrbufInit(&gpu->driver); - ffGetWmiObjString(pclsObj, L"DriverVersion", &gpu->driver); + record.getString(L"DriverVersion", &gpu->driver); gpu->temperature = FF_GPU_TEMP_UNSET; gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; } - if(pclsObj) pclsObj->Release(); - pEnumerator->Release(); return nullptr; } diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp index 60f3fcedf..5d0333db8 100644 --- a/src/detection/host/host_windows.cpp +++ b/src/detection/host/host_windows.cpp @@ -16,25 +16,17 @@ extern "C" void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->chassisVendor); ffStrbufInit(&host->chassisVersion); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error); - if(!pEnumerator) + FFWmiQuery query(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - ffStrbufInitS(&host->error, "No Wmi result returned"); - pEnumerator->Release(); - return; + record.getString(L"Name", &host->productName); + record.getString(L"Version", &host->productVersion); + record.getString(L"SKUNumber", &host->productSku); + record.getString(L"Vendor", &host->sysVendor); } - - ffGetWmiObjString(pclsObj, L"Name", &host->productName); - ffGetWmiObjString(pclsObj, L"Version", &host->productVersion); - ffGetWmiObjString(pclsObj, L"SKUNumber", &host->productSku); - ffGetWmiObjString(pclsObj, L"Vendor", &host->sysVendor); - - pclsObj->Release(); - pEnumerator->Release(); + else + ffStrbufInitS(&host->error, "No Wmi result returned"); } diff --git a/src/detection/memory/memory_windows.cpp b/src/detection/memory/memory_windows.cpp index 91a42ef3c..a11308e0d 100644 --- a/src/detection/memory/memory_windows.cpp +++ b/src/detection/memory/memory_windows.cpp @@ -5,58 +5,40 @@ extern "C" { void detectRam(FFMemoryStorage* ram) { - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error); - if(!pEnumerator) + FFWmiQuery query(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - ffStrbufInitS(&ram->error, "No WMI result returned"); - pEnumerator->Release(); - return; + //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; } - - //KB - ffGetWmiObjUnsigned(pclsObj, L"TotalVisibleMemorySize", &ram->bytesTotal); - uint64_t bytesFree; - ffGetWmiObjUnsigned(pclsObj, L"FreePhysicalMemory", &bytesFree); - ram->bytesUsed = ram->bytesTotal - bytesFree; - - pclsObj->Release(); - pEnumerator->Release(); - - ram->bytesTotal *= 1024; - ram->bytesUsed *= 1024; + else + ffStrbufInitS(&ram->error, "No Wmi result returned"); } void detectSwap(FFMemoryStorage* swap) { - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error); - if(!pEnumerator) + FFWmiQuery query(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - ffStrbufInitS(&swap->error, "No WMI result returned"); - pEnumerator->Release(); - return; + //MB + record.getUnsigned(L"AllocatedBaseSize", &swap->bytesTotal); + record.getUnsigned(L"CurrentUsage", &swap->bytesUsed); + swap->bytesTotal *= 1024 * 1024; + swap->bytesUsed *= 1024 * 1024; } - - //MB - ffGetWmiObjUnsigned(pclsObj, L"AllocatedBaseSize", &swap->bytesTotal); - ffGetWmiObjUnsigned(pclsObj, L"CurrentUsage", &swap->bytesUsed); - - pclsObj->Release(); - pEnumerator->Release(); - - swap->bytesTotal *= 1024 * 1024; - swap->bytesUsed *= 1024 * 1024; + else + ffStrbufInitS(&swap->error, "No Wmi result returned"); } extern "C" diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index c6dd9977e..e28607c9c 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -19,65 +19,55 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->systemName); ffStrbufInit(&os->architecture); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Caption, Version, BuildNumber, OSArchitecture FROM Win32_OperatingSystem", nullptr); - - if(!pEnumerator) + FFWmiQuery query(L"SELECT Caption, Version, BuildNumber, OSArchitecture FROM Win32_OperatingSystem"); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - pEnumerator->Release(); - return; - } - - ffGetWmiObjString(pclsObj, L"Caption", &os->variant); - if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows ")) - { - ffStrbufAppendS(&os->name, "Microsoft Windows"); - ffStrbufAppendS(&os->prettyName, "Windows"); - - ffStrbufSubstrAfter(&os->variant, strlen("Microsoft Windows ") - 1); - - if(ffStrbufStartsWithS(&os->variant, "Server ")) + record.getString(L"Caption", &os->variant); + if(ffStrbufStartsWithS(&os->variant, "Microsoft Windows ")) { - ffStrbufAppendS(&os->name, " Server"); - ffStrbufAppendS(&os->prettyName, " Server"); - ffStrbufSubstrAfter(&os->variant, strlen(" Server") - 1); - } + ffStrbufAppendS(&os->name, "Microsoft Windows"); + ffStrbufAppendS(&os->prettyName, "Windows"); - uint32_t index = ffStrbufFirstIndexC(&os->variant, ' '); - ffStrbufAppendNS(&os->version, index, os->variant.chars); - ffStrbufSubstrAfter(&os->variant, index); + ffStrbufSubstrAfter(&os->variant, strlen("Microsoft Windows ") - 1); - // 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] == ' ')) + if(ffStrbufStartsWithS(&os->variant, "Server ")) { - ffStrbufAppendF(&os->version, " R%c", os->variant.chars[1]); - ffStrbufSubstrAfter(&os->variant, strlen("Rx ") - 1); + 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); + } + + ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars); + + record.getString(L"BuildNumber", &os->buildID); + record.getString(L"OSArchitecture", &os->architecture); + + ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); } - 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); - - ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); - ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); - - ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); - - pclsObj->Release(); - pEnumerator->Release(); } diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp index 5d491d16e..68de794a6 100644 --- a/src/detection/processes/processes_windows.cpp +++ b/src/detection/processes/processes_windows.cpp @@ -7,24 +7,19 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) { FF_UNUSED(instance); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error); - - if(!pEnumerator) + FFWmiQuery query(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error); + if(!query) return 0; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) + { + uint64_t result = 0; + record.getUnsigned(L"NumberOfProcesses", &result); + return (uint32_t)result; + } + else { ffStrbufAppendS(error, "No Wmi result returned"); - pEnumerator->Release(); return 0; } - - uint64_t result = 0; - ffGetWmiObjUnsigned(pclsObj, L"NumberOfProcesses", &result); - pclsObj->Release(); - pEnumerator->Release(); - return (uint32_t)result; } diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 71a34c6ea..770e043eb 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -65,45 +65,34 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb if(pid == 0) pid = GetCurrentProcessId(); - wchar_t query[256] = {}; - swprintf(query, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32, + wchar_t sql[256] = {}; + swprintf(sql, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32, pname ? L"Name," : L"", pname ? L"ExecutablePath," : L"", pid); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr); - if(!pEnumerator) + FFWmiQuery query(sql); + if(!query) return false; - IWbemClassObject *pclsObj = nullptr; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - pEnumerator->Release(); - return false; + if(ppid) + { + uint64_t value; + record.getUnsigned(L"ParentProcessId", &value); + *ppid = (uint32_t) value; + } + + if(pname) + record.getString(L"Name", pname); + + if(exe) + record.getString(L"ExecutablePath", exe); + + if(exeName) + *exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1; } - - if(ppid) - { - uint64_t value; - ffGetWmiObjUnsigned(pclsObj, L"ParentProcessId", &value); - *ppid = (uint32_t) value; - } - - if(pname) - ffGetWmiObjString(pclsObj, L"Name", pname); - - if(exe) - ffGetWmiObjString(pclsObj, L"ExecutablePath", exe); - - if(exeName) - { - *exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1; - } - - pclsObj->Release(); - pEnumerator->Release(); return true; } diff --git a/src/detection/users/users_windows.cpp b/src/detection/users/users_windows.cpp index 41dd9674b..9e50cd365 100644 --- a/src/detection/users/users_windows.cpp +++ b/src/detection/users/users_windows.cpp @@ -5,20 +5,16 @@ extern "C" { void ffDetectUsers(FFlist* users, FFstrbuf* error) { - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Antecedent FROM Win32_LoggedOnUser", error); - - if(!pEnumerator) + FFWmiQuery query(L"SELECT Antecedent FROM Win32_LoggedOnUser", error); + if(!query) return; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - next: - while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) + while(FFWmiRecord record = query.next()) { FFstrbuf antecedent; ffStrbufInit(&antecedent); - ffGetWmiObjString(pclsObj, L"Antecedent", &antecedent); // \\.\root\cimv2:Win32_Account.Domain="DOMAIN",Name="NAME" + 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, '"'); @@ -36,7 +32,4 @@ next: if(users->length == 0) ffStrbufAppendS(error, "Unable to detect users"); - - if(pclsObj) pclsObj->Release(); - pEnumerator->Release(); } diff --git a/src/util/windows/utsname.cpp b/src/util/windows/utsname.cpp index 4d1036d52..10c0f7b68 100644 --- a/src/util/windows/utsname.cpp +++ b/src/util/windows/utsname.cpp @@ -9,35 +9,27 @@ int uname(struct utsname *name) strncpy(name->sysname, "Windows_NT", UTSNAME_MAXLENGTH); - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Version, CSName, OSArchitecture FROM Win32_OperatingSystem", nullptr); - if(!pEnumerator) + FFWmiQuery query(L"SELECT Version, CSName, OSArchitecture FROM Win32_OperatingSystem"); + if(!query) return -1; - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) + if(FFWmiRecord record = query.next()) { - pEnumerator->Release(); - return -1; + FFstrbuf value; + ffStrbufInit(&value); + record.getString(L"Version", &value); + strncpy(name->release, value.chars, UTSNAME_MAXLENGTH); + + ffStrbufClear(&value); + record.getString(L"CSName", &value); + strncpy(name->nodename, value.chars, UTSNAME_MAXLENGTH); + + ffStrbufClear(&value); + record.getString(L"OSArchitecture", &value); + strncpy(name->machine, value.chars, UTSNAME_MAXLENGTH); + + ffStrbufDestroy(&value); } - FFstrbuf value; - ffStrbufInit(&value); - ffGetWmiObjString(pclsObj, L"Version", &value); - strncpy(name->release, value.chars, UTSNAME_MAXLENGTH); - - ffStrbufClear(&value); - ffGetWmiObjString(pclsObj, L"CSName", &value); - strncpy(name->nodename, value.chars, UTSNAME_MAXLENGTH); - - ffStrbufClear(&value); - ffGetWmiObjString(pclsObj, L"OSArchitecture", &value); - strncpy(name->machine, value.chars, UTSNAME_MAXLENGTH); - - ffStrbufDestroy(&value); - pclsObj->Release(); - pEnumerator->Release(); - return 0; } diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 9b1a120d0..6a273f86a 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -4,6 +4,21 @@ #include #include +namespace +{ + // Provide our bstr_t to avoid libstdc++ dependency + struct bstr_t + { + explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {} + ~bstr_t() noexcept { SysFreeString(_bstr); } + explicit operator const wchar_t*() const noexcept { return _bstr; } + operator BSTR() const noexcept { return _bstr; } + + private: + BSTR _bstr; + }; +} + //https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer //https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes static void CoUninitializeWrap() @@ -105,8 +120,8 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) return TRUE; } - -IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) +FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error) + : pEnumerator(nullptr) { static INIT_ONCE s_InitOnce = INIT_ONCE_STATIC_INIT; const char* context; @@ -114,11 +129,10 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) { if(error) ffStrbufInitS(error, context); - return nullptr; + return; } // Use the IWbemServices pointer to make requests of WMI - IEnumWbemClassObject* pEnumerator = nullptr; HRESULT hres; hres = ((IWbemServices*)context)->ExecQuery( @@ -132,13 +146,11 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) { if(error) ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%lX", queryStr, hres); - return nullptr; } - - return pEnumerator; } -void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { +static void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) +{ int len = (int)SysStringLen(bstr); if(len <= 0) { @@ -152,7 +164,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { strbuf->chars[size_needed] = '\0'; } -bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf) +bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf) { bool result = true; @@ -202,7 +214,7 @@ bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strb return result; } -bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integer) +bool FFWmiRecord::getSigned(const wchar_t* key, int64_t* integer) { bool result = true; @@ -237,7 +249,7 @@ bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integ return result; } -bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* integer) +bool FFWmiRecord::getUnsigned(const wchar_t* key, uint64_t* integer) { bool result = true; @@ -271,7 +283,7 @@ bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* in return result; } -bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real) +bool FFWmiRecord::getReal(const wchar_t* key, double* real) { bool result = true; diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 53122dfa2..0fec1ee64 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -11,32 +11,51 @@ extern "C" { #include -// is not usable in MSYS, so provide our simple bstr_t implementation -struct bstr_t +struct FFWmiRecord { - explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {} + IWbemClassObject* obj; - ~bstr_t() noexcept { SysFreeString(_bstr); } + explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator): obj(nullptr) { + if(!pEnumerator) return; - explicit operator const wchar_t*() const noexcept { - return _bstr; + ULONG ret; + bool ok = SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &obj, &ret)) && ret; + if(!ok) obj = nullptr; } - - operator BSTR() const noexcept { - return _bstr; + FFWmiRecord(const FFWmiRecord&) = delete; + FFWmiRecord(FFWmiRecord&& other) { + obj = other.obj; + other.obj = nullptr; } + ~FFWmiRecord() { if(obj) obj->Release(); } + explicit operator bool() { return !!obj; } -private: - BSTR _bstr; + bool getString(const wchar_t* key, FFstrbuf* strbuf); + bool getSigned(const wchar_t* key, int64_t* integer); + bool getUnsigned(const wchar_t* key, uint64_t* integer); + bool getReal(const wchar_t* key, double* real); }; -void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf); +struct FFWmiQuery +{ + IEnumWbemClassObject* pEnumerator = nullptr; -IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error); -bool ffGetWmiObjString(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf); -bool ffGetWmiObjSigned(IWbemClassObject* obj, const wchar_t* key, int64_t* integer); -bool ffGetWmiObjUnsigned(IWbemClassObject* obj, const wchar_t* key, uint64_t* integer); -bool ffGetWmiObjReal(IWbemClassObject* obj, const wchar_t* key, double* real); + 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() { if(pEnumerator) pEnumerator->Release(); } + + explicit operator bool() { return !!pEnumerator; } + + FFWmiRecord next() { + FFWmiRecord result(pEnumerator); + return result; + } +}; #else // Win32 COM headers requires C++ compiler From 19a9b18c696bacb0aaa76d5016147f1290365de0 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 17 Oct 2022 13:19:48 +0200 Subject: [PATCH 103/311] Disk: Linux impl working --- CMakeLists.txt | 3 +- src/common/format.c | 5 +- src/common/format.h | 5 +- src/common/init.c | 3 +- src/common/printing.c | 4 +- src/detection/disk/disk.c | 71 +++++++------------- src/detection/disk/disk.h | 37 ++++++++-- src/detection/disk/disk_apple.m | 10 +-- src/detection/disk/disk_linux.c | 85 +++++++++++++++++++---- src/detection/disk/disk_windows.c | 107 +++++++++++++++-------------- src/fastfetch.c | 2 - src/fastfetch.h | 3 +- src/modules/disk.c | 108 +++++++++++++++++++++--------- src/util/FFlist.h | 6 ++ src/util/FFstrbuf.c | 12 ++++ src/util/FFstrbuf.h | 6 ++ 16 files changed, 301 insertions(+), 166 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d0cf1b4d..990441a6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,6 +241,7 @@ set(LIBFASTFETCH_SRC src/detection/terminalshell/terminalshell.c src/detection/media/media.c src/detection/packages/packages.c + src/detection/disk/disk.c src/modules/break.c src/modules/custom.c src/modules/title.c @@ -285,13 +286,13 @@ set(LIBFASTFETCH_SRC src/modules/opengl.c src/modules/opencl.c src/modules/users.c + src/detection/disk/disk_apple.m ) if(LINUX OR APPLE OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/common/processing_linux.c src/detection/users/users_linux.c - src/detection/disk/disk.c src/detection/terminalshell/terminalshell_linux.c src/detection/localip/localip_linux.c ) diff --git a/src/common/format.c b/src/common/format.c index 19d5d289d..136b053d2 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -20,6 +20,8 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_DOUBLE) ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value); + else if(formatarg->type == FF_FORMAT_ARG_TYPE_BOOL) + ffStrbufAppendS(buffer, formatarg->value != NULL ? "true" : "false"); else if(formatarg->type == FF_FORMAT_ARG_TYPE_LIST) { const FFlist* list = formatarg->value; @@ -74,7 +76,8 @@ static inline bool formatArgSet(const FFformatarg* arg) (arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet(arg->value)) || (arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) || (arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) || - (arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) + (arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) || + (arg->type == FF_FORMAT_ARG_TYPE_BOOL && arg->value != NULL) ); } diff --git a/src/common/format.h b/src/common/format.h index 51413a1fb..d860dbd29 100644 --- a/src/common/format.h +++ b/src/common/format.h @@ -13,7 +13,8 @@ typedef enum FFformatargtype FF_FORMAT_ARG_TYPE_STRING, FF_FORMAT_ARG_TYPE_STRBUF, FF_FORMAT_ARG_TYPE_DOUBLE, - FF_FORMAT_ARG_TYPE_LIST + FF_FORMAT_ARG_TYPE_LIST, + FF_FORMAT_ARG_TYPE_BOOL } FFformatargtype; typedef struct FFformatarg @@ -25,4 +26,6 @@ typedef struct FFformatarg void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg); void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments); +#define FF_FORMAT_ARG_VALUE_BOOL(xpr) ((xpr) ? (const void*) 1 : NULL) + #endif diff --git a/src/common/init.c b/src/common/init.c index 0427d419b..af4ab7bfe 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -253,7 +253,8 @@ static void defaultConfig(FFinstance* instance) instance->config.titleFQDN = false; ffStrbufInitA(&instance->config.diskFolders, 0); - instance->config.diskRemovable = false; + instance->config.diskShowRemovable = true; + instance->config.diskShowHidden = false; ffStrbufInitA(&instance->config.batteryDir, 0); diff --git a/src/common/printing.c b/src/common/printing.c index a6911db15..148266d26 100644 --- a/src/common/printing.c +++ b/src/common/printing.c @@ -93,7 +93,9 @@ static void printError(FFinstance* instance, const char* moduleName, uint8_t mod vprintf(message, arguments); if(!instance->config.pipe) - puts(FASTFETCH_TEXT_MODIFIER_RESET); + fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); + + putchar('\n'); } } diff --git a/src/detection/disk/disk.c b/src/detection/disk/disk.c index 7d469c2ba..3ce33aed5 100644 --- a/src/detection/disk/disk.c +++ b/src/detection/disk/disk.c @@ -1,56 +1,35 @@ -#include "fastfetch.h" #include "disk.h" +#include "detection/internal.h" -#include +void ffDetectDisksImpl(FFDiskResult* disks); -void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result) +static int compareDisks(const void* disk1, const void* disk2) { - ffStrbufInitS(&result->path, folderPath); - result->used = result->total = 0; - ffStrbufInit(&result->error); + return ffStrbufCompAlphabetically(&((const FFDisk*) disk1)->mountpoint, &((const FFDisk*) disk2)->mountpoint); +} - struct statvfs newFs; +const FFDiskResult* ffDetectDisks() +{ + FF_DETECTION_INTERNAL_GUARD(FFDiskResult, + ffStrbufInit(&result.error); + ffListInitA(&result.disks, sizeof(FFDisk), 4); - if(fs == NULL) - { - fs = &newFs; - int ret = statvfs(folderPath, fs); - if(ret != 0) + ffDetectDisksImpl(&result); + + if(result.disks.length == 0 && result.error.length == 0) + ffStrbufAppendS(&result.error, "No disks found"); + + for(uint32_t i = 0; i < result.disks.length; ++i) { - ffStrbufAppendF(&result->error, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret); - return; + FFDisk* disk = ffListGet(&result.disks, i); + disk->bytesPercentage = (uint8_t) (((long double) disk->bytesUsed / (long double) disk->bytesTotal) * 100.0); + disk->filesPercentage = (uint8_t) (((long double) disk->filesUsed / (long double) disk->filesTotal) * 100.0); } - } - result->total = fs->f_blocks * fs->f_frsize; - - if(result->total == 0) - { - ffStrbufAppendF(&result->error, "statvfs for %s returned size 0", folderPath); - return; - } - - result->used = result->total - (fs->f_bavail * fs->f_frsize); - result->files = (uint32_t) (fs->f_files - fs->f_ffree); - result->removable = false; //To be set at other place -} - -bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders) -{ - ffStrbufTrim(&instance->config.diskFolders, ':'); - if(instance->config.diskFolders.length == 0) - return false; - - uint32_t startIndex = 0; - while(startIndex < instance->config.diskFolders.length) - { - uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':'); - instance->config.diskFolders.chars[colonIndex] = '\0'; - - ffDetectDiskWithStatvfs(instance->config.diskFolders.chars + startIndex, NULL, (FFDiskResult*)ffListAdd(folders)); - - startIndex = colonIndex + 1; - } - - return true; + //We need to sort the disks, so that we can detect, which disk a path resides on + // For example for /boot/efi/bootmgr we need to check /boot/efi before /boot + //Note that we sort alphabetically here for a better ordering when printing the list, + // so the check must be done in reverse order + ffListSort(&result.disks, compareDisks); + ); } diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index a68347fde..30243d73c 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -5,17 +5,40 @@ #include "fastfetch.h" +typedef enum FFDiskType +{ + FF_DISK_TYPE_REGULAR, + FF_DISK_TYPE_HIDDEN, + FF_DISK_TYPE_EXTERNAL +} FFDiskType; + +typedef struct FFDisk +{ + FFstrbuf mountpoint; + FFstrbuf filesystem; + FFDiskType type; + + uint64_t bytesUsed; + uint64_t bytesTotal; + uint8_t bytesPercentage; + + uint32_t filesUsed; + uint32_t filesTotal; + uint8_t filesPercentage; +} FFDisk; + typedef struct FFDiskResult { - FFstrbuf path; - uint64_t used; - uint64_t total; - uint32_t files; - bool removable; FFstrbuf error; + FFlist disks; //List of FFDisk } FFDiskResult; -const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders); -bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders); +/** + * Returns a List of FFDisk, sorted alphabetically by mountpoint. + * If error is not set, disks contains at least one disk. + * + * @return const FFDiskResult* + */ +const FFDiskResult* ffDetectDisks(); #endif diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index 8341ef74e..a4e38376d 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -3,15 +3,17 @@ #include #import -void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result); - -const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) +void ffDetectDisksImpl(FFDiskResult* disks) { NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil]; NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys options:NSVolumeEnumerationSkipHiddenVolumes]; + if(urls == nil) - return "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed"; + { + ffStrbufAppendS(&disks->error, "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed"); + return; + } for (NSURL *url in urls) { NSError *error; diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index eb8ceb0f3..bbf4e22a8 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -1,24 +1,81 @@ #include "disk.h" +#include #include -void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result); - -const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) +void ffDetectDisksImpl(FFDiskResult* disks) { - FF_UNUSED(instance); + FILE* mountsFile = fopen("/proc/mounts", "r"); + if(mountsFile == NULL) + { + ffStrbufAppendS(&disks->error, "fopen(\"/proc/mounts\", \"r\") == NULL"); + return; + } - struct statvfs fsRoot; - int rootRet = statvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot); - if(rootRet != 0) - return "statvfs(\"/\") failed"; + char* line = NULL; + size_t len = 0; - ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot, (FFDiskResult*)ffListAdd(folders)); + while(getline(&line, &len, mountsFile) != EOF) + { + //Format of the file: " ..." (Same as fstab) + char* currentPos = line; - struct statvfs fsHome; - int homeRet = statvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome); - if(homeRet == 0 && (fsRoot.f_fsid != fsHome.f_fsid)) - ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome, (FFDiskResult*)ffListAdd(folders)); + //Non pseudo filesystems have their device in /dev/, we only add those + if(strncasecmp(currentPos, "/dev/", 5) != 0) + continue; - return NULL; + //Skip /dev/ + currentPos += 5; + + //Don't show loop file systems + if(strncasecmp(currentPos, "loop", 4) == 0) + continue; + + FFDisk* disk = ffListAdd(&disks->disks); + + //Go to mountpoint + while(!isspace(*currentPos) && *currentPos != '\0') + ++currentPos; + while(isspace(*currentPos)) + ++currentPos; + + ffStrbufInitA(&disk->mountpoint, 16); + ffStrbufAppendSUntilC(&disk->mountpoint, currentPos, ' '); + + //Go to filesystem + currentPos += disk->mountpoint.length; + while(isspace(*currentPos)) + ++currentPos; + + ffStrbufInitA(&disk->filesystem, 16); + ffStrbufAppendSUntilC(&disk->filesystem, currentPos, ' '); + + //Go to options, detect type + currentPos += disk->filesystem.length; + while(isspace(*currentPos)) + ++currentPos; + + if(strstr(currentPos, "nosuid") != NULL || strstr(currentPos, "nodev") != NULL) + disk->type = FF_DISK_TYPE_EXTERNAL; + else if(ffStrbufStartsWithS(&disk->mountpoint, "/boot") || ffStrbufStartsWithS(&disk->mountpoint, "/efi")) + disk->type = FF_DISK_TYPE_HIDDEN; + else + disk->type = FF_DISK_TYPE_REGULAR; + + //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 + + disk->bytesTotal = fs.f_blocks * fs.f_frsize; + disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize); + + disk->filesTotal = (uint32_t) fs.f_files; + disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); + } + + if(line != NULL) + free(line); + + fclose(mountsFile); } diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c index 27117a017..b3c50456c 100644 --- a/src/detection/disk/disk_windows.c +++ b/src/detection/disk/disk_windows.c @@ -1,66 +1,65 @@ #include "disk.h" #define WIN32_LEAN_AND_MEAN 1 -#include +#include -static void detectDrive(const char* folderPath, uint32_t pathLen, FFDiskResult* result) +void ffDetectDisksImpl(FFDiskResult* disks) { - ffStrbufInitNS(&result->path, pathLen, folderPath); - result->removable = false; //To be set at other place - result->files = 0; //Unsupported - - //According to https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa - //GetDiskFreeSpaceExA does not have to specify the root directory on a disk. The function accepts any directory on a disk. - uint64_t freeBytes; - if(GetDiskFreeSpaceExA(folderPath, NULL, (PULARGE_INTEGER)&result->total, (PULARGE_INTEGER)&freeBytes)) { - result->used = result->total - freeBytes; - ffStrbufInit(&result->error); - } - else - ffStrbufInitS(&result->error, "GetDiskFreeSpaceExA() failed"); -} - -const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) -{ - FF_UNUSED(instance); - - char buf[128]; // "C:\\\0D:\\\0" - uint32_t length = GetLogicalDriveStringsA(sizeof(buf) / sizeof(*buf), buf); - - for(size_t i = 0; i < length;) + uint32_t length = GetLogicalDriveStringsA(0, NULL); + if(length == 0) { - const char* drive = buf + i; - uint32_t driveLen = (uint32_t) strlen(drive); - i += driveLen + 1; + ffStrbufAppendS(&disks->error, "GetLogicalDriveStringsA failed"); + return; + } - bool removable = GetDriveTypeA(drive) == DRIVE_REMOVABLE; - if(removable && !instance->config.diskRemovable) + char* buff = malloc(length + 1); + GetLogicalDriveStringsA(length, buf); + + for(uint32_t i = 0; i < length; i++) + { + const char* mountpoint = buf + i; + + UINT driveType = GetDriveTypeA(mountpoint); + if(driveType == DRIVE_NO_ROOT_DIR) + { + i += strlen(mountpoint); continue; + } - FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); - detectDrive(drive, driveLen, folder); - folder->removable = removable; + FFDisk* disk = ffListAdd(&disks->disks); + ffStrbufInitS(&disk->mountpoint, mountpoint); + + uint64_t bytesFree; + if(!GetDiskFreeSpaceExA(mountpoint, NULL, (PULARGE_INTEGER)&disk->bytesTotal, (PULARGE_INTEGER)&bytesFree)) + { + disk->bytesTotal = 0; + bytesFree = 0; + } + disk->bytesUsed = disk->bytesTotal - bytesFree; + + if(driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM) + disk->type = FF_DISK_TYPE_EXTERNAL; + else if(driveType == DRIVE_FIXED) + disk->type = FF_DISK_TYPE_REGULAR; + else + disk->type = FF_DISK_TYPE_HIDDEN; + + ffStrbufInitA(&disk->filesystem, MAX_PATH + 1); + GetVolumeInformationA(mountpoint + NULL, 0, //Volume name + NULL, //Serial number + NULL, //Max component length + NULL, //File system flags + disk->filesystem.chars, ffStrbufGetFree(&disk->filesystem) + ); + ffStrbufRecalculateLength(&disk->filesystem); + + //TODO: implement + disk->filesUsed = 0; + disk->filesTotal = 0; + + i += disk->mountpoint.length; } - return NULL; -} - -bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders) -{ - ffStrbufTrim(&instance->config.diskFolders, ';'); - if(instance->config.diskFolders.length == 0) - return false; - - uint32_t startIndex = 0; - while(startIndex < instance->config.diskFolders.length) - { - uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ';'); - instance->config.diskFolders.chars[colonIndex] = '\0'; - - detectDrive(instance->config.diskFolders.chars + startIndex, colonIndex - startIndex, (FFDiskResult*)ffListAdd(folders)); - - startIndex = colonIndex + 1; - } - - return true; + free(buff); } diff --git a/src/fastfetch.c b/src/fastfetch.c index 6d1a2b8d2..f395d808b 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1314,8 +1314,6 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.titleFQDN = optionParseBoolean(value); else if(strcasecmp(key, "--disk-folders") == 0) optionParseString(key, value, &instance->config.diskFolders); - else if(strcasecmp(key, "--disk-removable") == 0) - instance->config.diskRemovable = optionParseBoolean(value); else if(strcasecmp(key, "--battery-dir") == 0) optionParseString(key, value, &instance->config.batteryDir); else if(strcasecmp(key, "--separator-string") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index afb697cbf..d62348e80 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -168,7 +168,8 @@ typedef struct FFconfig bool titleFQDN; FFstrbuf diskFolders; - bool diskRemovable; + bool diskShowRemovable; + bool diskShowHidden; FFstrbuf batteryDir; diff --git a/src/modules/disk.c b/src/modules/disk.c index 1a2c97be8..88dd6634d 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -4,78 +4,120 @@ #include "detection/disk/disk.h" #define FF_DISK_MODULE_NAME "Disk" -#define FF_DISK_NUM_FORMAT_ARGS 4 +#define FF_DISK_NUM_FORMAT_ARGS 9 -static void printFolder(FFinstance* instance, FFDiskResult* folder) +static void printDisk(FFinstance* instance, const FFDisk* disk) { FFstrbuf key; ffStrbufInit(&key); if(instance->config.disk.key.length == 0) { - ffStrbufAppendF(&key, "%s (%*s)", FF_DISK_MODULE_NAME, folder->path.length, folder->path.chars); + ffStrbufAppendF(&key, "%s (%s)", FF_DISK_MODULE_NAME, disk->mountpoint.chars); } else { ffParseFormatString(&key, &instance->config.disk.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &folder->path} + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->mountpoint} }); } - uint8_t percentage = (uint8_t) (((long double) folder->used / (long double) folder->total) * 100.0); - FFstrbuf usedPretty; ffStrbufInit(&usedPretty); - ffParseSize(folder->used, instance->config.binaryPrefixType, &usedPretty); + ffParseSize(disk->bytesUsed, instance->config.binaryPrefixType, &usedPretty); FFstrbuf totalPretty; ffStrbufInit(&totalPretty); - ffParseSize(folder->total, instance->config.binaryPrefixType, &totalPretty); + ffParseSize(disk->bytesTotal, instance->config.binaryPrefixType, &totalPretty); if(instance->config.disk.outputFormat.length == 0) { ffPrintLogoAndKey(instance, key.chars, 0, NULL); - printf("%s / %s (%u%%)%s\n", usedPretty.chars, totalPretty.chars, percentage, folder->removable ? " [Removable]" : ""); + printf("%s / %s (%u%%)", usedPretty.chars, totalPretty.chars, disk->bytesPercentage); + if(disk->type == FF_DISK_TYPE_EXTERNAL) + printf(" [Removable]"); + putchar('\n'); } else { ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, - {FF_FORMAT_ARG_TYPE_UINT, &folder->files}, + {FF_FORMAT_ARG_TYPE_UINT8, &disk->bytesPercentage}, + {FF_FORMAT_ARG_TYPE_UINT, &disk->filesUsed}, + {FF_FORMAT_ARG_TYPE_UINT, &disk->filesTotal}, + {FF_FORMAT_ARG_TYPE_UINT8, &disk->filesPercentage}, + {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type == FF_DISK_TYPE_EXTERNAL)}, + {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type == FF_DISK_TYPE_HIDDEN)}, + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem} }); } - ffStrbufDestroy(&key); ffStrbufDestroy(&totalPretty); ffStrbufDestroy(&usedPretty); + ffStrbufDestroy(&key); +} + +static void printMountpoint(FFinstance* instance, const FFlist* disks, const char* mountpoint) +{ + for(uint32_t i = disks->length; i > 0; i--) + { + FFDisk* disk = ffListGet(disks, i - 1); + if(strncmp(mountpoint, disk->mountpoint.chars, disk->mountpoint.length) == 0) + { + printDisk(instance, disk); + return; + } + } + + ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "No disk found for mountpoint: %s", mountpoint); +} + +static void printMountpoints(FFinstance* instance, const FFlist* disks) +{ + FFstrbuf mountpoints; + ffStrbufInitCopy(&mountpoints, &instance->config.diskFolders); + ffStrbufTrim(&mountpoints, ':'); + + uint32_t startIndex = 0; + while(startIndex < mountpoints.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&mountpoints, startIndex, ':'); + mountpoints.chars[colonIndex] = '\0'; + + printMountpoint(instance, disks, mountpoints.chars + startIndex); + + startIndex = colonIndex + 1; + } +} + +static void printAutodetected(FFinstance* instance, const FFlist* disks) +{ + for(uint32_t i = 0; i < disks->length; i++) + { + const FFDisk* disk = ffListGet(disks, i); + + if(disk->type == FF_DISK_TYPE_EXTERNAL && !instance->config.diskShowRemovable) + continue; + + if(disk->type == FF_DISK_TYPE_HIDDEN && !instance->config.diskShowHidden) + continue; + + printDisk(instance, disk); + } } void ffPrintDisk(FFinstance* instance) { - FFlist folders; - ffListInit(&folders, sizeof(FFDiskResult)); - - const char* error = NULL; - - if(!ffDiskDetectDiskFolders(instance, &folders)) - error = ffDiskAutodetectFolders(instance, &folders); - - if(error) + const FFDiskResult* disks = ffDetectDisks(); + if(disks->error.length > 0) { - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", error); + ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", disks->error.chars); + return; } + + if(instance->config.diskFolders.length == 0) + printAutodetected(instance, &disks->disks); else - { - for(uint32_t i = 0; i < folders.length; ++i) - { - FFDiskResult* folder = (FFDiskResult*)ffListGet(&folders, i); - printFolder(instance, folder); - ffStrbufDestroy(&folder->path); - ffStrbufDestroy(&folder->error); - } - } - - ffListDestroy(&folders); + printMountpoints(instance, &disks->disks); } diff --git a/src/util/FFlist.h b/src/util/FFlist.h index d1eee05ad..d9d516792 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -8,6 +8,7 @@ #include #include #include +#include #define FF_LIST_DEFAULT_ALLOC 16 @@ -39,4 +40,9 @@ static inline void* ffListGet(const FFlist* list, uint32_t index) return list->data + (index * list->elementSize); } +static inline void ffListSort(FFlist* list, int(*compar)(const void*, const void*)) +{ + qsort(list->data, list->length, list->elementSize, compar); +} + #endif diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index b302bce0a..415ec6fb7 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -155,6 +155,18 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) strbuf->chars[strbuf->length] = '\0'; } +void ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until) +{ + if(value == NULL) + return; + + char* end = strchr(value, until); + if(end == NULL) + ffStrbufAppendS(strbuf, value); + else + ffStrbufAppendNS(strbuf, (uint32_t) (end - value), value); +} + void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...) { assert(format != NULL); diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 11ce0518b..736e1d26d 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -45,6 +45,7 @@ void ffStrbufAppendNSExludingC(FFstrbuf* strbuf, uint32_t length, const char* va void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int(*transformFunc)(int)); FF_C_PRINTF(2, 3) void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...); void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments); +void ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until); void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value); @@ -147,6 +148,11 @@ static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) return memcmp(strbuf->chars, comp->chars, length + 1); } +static inline int ffStrbufCompAlphabetically(const FFstrbuf* strbuf, const FFstrbuf* comp) +{ + return strcmp(strbuf->chars, comp->chars); +} + static inline FF_C_NODISCARD bool ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) { return ffStrbufComp(strbuf, comp) == 0; From c1fec9b4117f111742260eda6412af5b4661c23c Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 17 Oct 2022 08:10:58 -0700 Subject: [PATCH 104/311] Disk: Apple implementation working --- src/detection/disk/disk_apple.m | 57 +++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index a4e38376d..804a75dd8 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -2,12 +2,22 @@ #include #import +#import + +static bool getBool(NSURL* url, NSURLResourceKey key) +{ + NSError *error; + NSNumber* result; + if([url getResourceValue:&result forKey:key error:&error] == NO) + return false; + + return result.boolValue; +} void ffDetectDisksImpl(FFDiskResult* disks) { NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil]; - NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys - options:NSVolumeEnumerationSkipHiddenVolumes]; + NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys options:0]; if(urls == nil) { @@ -15,18 +25,37 @@ void ffDetectDisksImpl(FFDiskResult* disks) return; } - for (NSURL *url in urls) { - NSError *error; - NSNumber* removable; - if([url getResourceValue:&removable forKey:NSURLVolumeIsRemovableKey error:&error] == NO) - continue; - if(removable.boolValue && !instance->config.diskRemovable) - continue; + for (NSURL *url in urls) + { + FFDisk* disk = ffListAdd(&disks->disks); - FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); - ffDetectDiskWithStatvfs([url.relativePath cStringUsingEncoding:NSUTF8StringEncoding], NULL, folder); - folder->removable = removable.boolValue; + ffStrbufInitS(&disk->mountpoint, [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]); + + NSString* filesystem; + [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:url.relativePath + isRemovable:nil + isWritable:nil + isUnmountable:nil + description:nil + type:&filesystem + ]; + ffStrbufInitS(&disk->filesystem, [filesystem cStringUsingEncoding:NSUTF8StringEncoding]); + + if(getBool(url, NSURLVolumeIsRemovableKey)) + disk->type = FF_DISK_TYPE_EXTERNAL; + else if(getBool(url, NSURLVolumeIsBrowsableKey)) + disk->type = FF_DISK_TYPE_REGULAR; + else + disk->type = FF_DISK_TYPE_HIDDEN; + + 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 + + disk->bytesTotal = fs.f_blocks * fs.f_frsize; + disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize); + + disk->filesTotal = (uint32_t) fs.f_files; + disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); } - - return NULL; } From ee705363c126acf23a72ca8f272a0bbd9100d731 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 17 Oct 2022 17:13:45 +0200 Subject: [PATCH 105/311] Disk: Don't always build apple code --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 990441a6d..7bed7d016 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,7 +286,6 @@ set(LIBFASTFETCH_SRC src/modules/opengl.c src/modules/opencl.c src/modules/users.c - src/detection/disk/disk_apple.m ) if(LINUX OR APPLE OR ANDROID OR BSD) From a03eaed4e295588f116f242ac524bf2f33c41a89 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 17 Oct 2022 17:35:06 +0200 Subject: [PATCH 106/311] Disk: add options# --- completions/bash | 2 ++ presets/verbose | 2 +- src/data/help.txt | 39 ++++++++++++++++--------------- src/detection/disk/disk_windows.c | 2 +- src/fastfetch.c | 19 +++++++++++---- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/completions/bash b/completions/bash index a27172dfd..907f8c27f 100644 --- a/completions/bash +++ b/completions/bash @@ -188,6 +188,8 @@ __fastfetch_completion() "--pipe" "--title-fqdn" "--escape-bedrock" + "--disk-show-removable" + "--disk-show-hidden" ) local FF_OPTIONS_STRING=( diff --git a/presets/verbose b/presets/verbose index 9b7713eae..95512dc86 100644 --- a/presets/verbose +++ b/presets/verbose @@ -19,7 +19,7 @@ --cpu-usage-format Percentage: {} --gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {} --memory-format Used: {}; Total: {}; Percentage: {} ---disk-format Used: {}; Total: {}; Files: {}; Percentage: {} +--disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; Removable: {}; Hidden: {}; Filesystem: {} --battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {} --poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {} --player-format Pretty: {}; Name: {}; Bus: {}; Url: {} diff --git a/src/data/help.txt b/src/data/help.txt index 181f24671..9d8c32027 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -87,25 +87,26 @@ Library options: Set the path of a library to load --lib-cjson Module specific options: - --title-fqdn : Sets if the title should use fully qualified domain name. Default is false. - --separator-string : Set the string printed by the separator module - --os-file : Set the path to the file containing OS informations - --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) - --disk-removable : Sets if removable volume should be printed. Default is false - --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ - --cpu-temp : Detect and display CPU temperature if supported. Default is false - --gpu-temp : Detect and display GPU temperature if supported. Default is false - --battery-temp : Detect and display Battery temperature if supported. Default is false - --localip-show-ipv4 : Show ipv4 addresses in local ip module. Default is true - --localip-show-ipv6 : Show ipv6 addresses in local ip module. Default is false - --localip-show-loop : Show loop back addresses (127.0.0.1) in local ip module. Default is false - --localip-name-prefix : Show ips with given name prefix only. Default is empty - --public-ip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0) - --public-ip-url: The URL of public IP detection server to be used. - --weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0) - --weather-output-format: The output weather format to be used. It must be URI encoded. - --player-name: The name of the player to use - --gl : Sets the opengl context creation library to use. Must be auto, egl, glx or osmesa. Default is auto + --title-fqdn : Sets if the title should use fully qualified domain name. Default is false. + --separator-string : Set the string printed by the separator module + --os-file : Set the path to the file containing OS informations + --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) + --disk-show-removable : Sets if removable volume should be printed. Default is true. + --disk-show-hidden : Sets if hidden volumes should be printed. Default is false + --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ + --cpu-temp : Detect and display CPU temperature if supported. Default is false + --gpu-temp : Detect and display GPU temperature if supported. Default is false + --battery-temp : Detect and display Battery temperature if supported. Default is false + --localip-show-ipv4 : Show ipv4 addresses in local ip module. Default is true + --localip-show-ipv6 : Show ipv6 addresses in local ip module. Default is false + --localip-show-loop : Show loop back addresses (127.0.0.1) in local ip module. Default is false + --localip-name-prefix : Show ips with given name prefix only. Default is empty + --public-ip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0) + --public-ip-url: The URL of public IP detection server to be used. + --weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0) + --weather-output-format: The output weather format to be used. It must be URI encoded. + --player-name: The name of the player to use + --gl : Sets the opengl context creation library to use. Must be auto, egl, glx or osmesa. Default is auto Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci" If a value starts with a ?, it is optional. "true" will be used if not set. diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c index b3c50456c..6f6908ca9 100644 --- a/src/detection/disk/disk_windows.c +++ b/src/detection/disk/disk_windows.c @@ -12,7 +12,7 @@ void ffDetectDisksImpl(FFDiskResult* disks) return; } - char* buff = malloc(length + 1); + char* buf = malloc(length + 1); GetLogicalDriveStringsA(length, buf); for(uint32_t i = 0; i < length; i++) diff --git a/src/fastfetch.c b/src/fastfetch.c index f395d808b..ea2818b96 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -300,11 +300,16 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "disk-format") == 0) { - constructAndPrintCommandHelpFormat("disk", "{}GiB / {}GiB ({4}%)", 4, - "Used size", - "Total size", - "Percentage used", - "Num files" + constructAndPrintCommandHelpFormat("disk", "{1} / {2} ({3}%)", 9, + "Size used", + "Size total", + "Size percentage", + "Files used", + "Files total", + "Files percentage", + "True if removable volume", + "True if hidden volume", + "Filesystem" ); } else if(strcasecmp(command, "battery-format") == 0) @@ -1314,6 +1319,10 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.titleFQDN = optionParseBoolean(value); else if(strcasecmp(key, "--disk-folders") == 0) optionParseString(key, value, &instance->config.diskFolders); + else if(strcasecmp(key, "--disk-show-removable") == 0) + instance->config.diskShowRemovable = optionParseBoolean(value); + else if(strcasecmp(key, "--disk-show-hidden") == 0) + instance->config.diskShowHidden = optionParseBoolean(value); else if(strcasecmp(key, "--battery-dir") == 0) optionParseString(key, value, &instance->config.batteryDir); else if(strcasecmp(key, "--separator-string") == 0) From b812f1dcb4bb066008b12ab9fcd3b3e82bf9310c Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 17 Oct 2022 17:52:43 +0200 Subject: [PATCH 107/311] Disk: Fix build on windows --- src/detection/disk/disk_windows.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c index 6f6908ca9..28e010b0b 100644 --- a/src/detection/disk/disk_windows.c +++ b/src/detection/disk/disk_windows.c @@ -45,12 +45,12 @@ void ffDetectDisksImpl(FFDiskResult* disks) disk->type = FF_DISK_TYPE_HIDDEN; ffStrbufInitA(&disk->filesystem, MAX_PATH + 1); - GetVolumeInformationA(mountpoint + GetVolumeInformationA(mountpoint, NULL, 0, //Volume name NULL, //Serial number NULL, //Max component length NULL, //File system flags - disk->filesystem.chars, ffStrbufGetFree(&disk->filesystem) + disk->filesystem.chars, disk->filesystem.allocated ); ffStrbufRecalculateLength(&disk->filesystem); @@ -61,5 +61,5 @@ void ffDetectDisksImpl(FFDiskResult* disks) i += disk->mountpoint.length; } - free(buff); + free(buf); } From 727a6988c2de7e5bebd9a96d13b484114e1e8a1a Mon Sep 17 00:00:00 2001 From: Jin Asanami <101626649+Jin-Asanami@users.noreply.github.com> Date: Tue, 18 Oct 2022 11:26:31 +0900 Subject: [PATCH 108/311] Update builtin.c --- src/logo/builtin.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index cbc16ae4b..ba129927f 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2000,6 +2000,35 @@ static const FFlogo* getLogoUbuntuSmall() FF_LOGO_RETURN } +static const FFlogo* getLogoUnivalent() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("univalent", "univalent-linux") + FF_LOGO_LINES( + "UUUUU$2\VVVVVVVVVVVVVVVVVVVVV/$1UUUUU\n" + "UUUUUU$2\VVVVVVVVVVVVVVVVVVV/$1UUUUUU\n" + "UUUUUUU$2\VVVVVVVVVVVVVVVVV/$1UUUUUUU\n" + "UUUUUUU $2\VVVVVVVVVVVVVVV/$1 UUUUUUU\n" + "UUUUUUUEE$2\VVVVVVVVVVVVV/$1 UUUUUUU\n" + "UUUUUUUEEE$2\VVVVVVVVVVV/$1 UUUUUUU\n" + "UUUUUUU $2\VVVVVVVVV/$1 UUUUUUU\n" + "UUUUUUUEEEEE$2\VVVVVVV/$1 UUUUUUU\n" + "UUUUUUUEEEEEE$2\VVVVV/$1 UUUUUUU\n" + "UUUUUUU $2\VVV/$1 UUUUUUU\n" + " UUUUUUU $2\V/$1 UUUUUUU\n" + " UUUUUUU $2V$1 UUUUUUU\n" + " UUUUUUUUUUUUUUUUUUU\n" + " UUUUUUUUUUUUU\n" + ) + FF_LOGO_COLORS( + "34" //blue + "32" //green + ) + FF_LOGO_COLOR_KEYS("32"); //blue + FF_LOGO_COLOR_TITLE("32"); //blue + FF_LOGO_RETURN +} + static const FFlogo* getLogoVoid() { FF_LOGO_INIT @@ -2155,6 +2184,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoUbuntu, getLogoUbuntuOld, getLogoUbuntuSmall, + getlogoUnivalent, getLogoVoid, getLogoVoidSmall, getLogoZorin, From bbcc040dc40a807497a01442b9672ff9416237cd Mon Sep 17 00:00:00 2001 From: Jin Asanami <101626649+Jin-Asanami@users.noreply.github.com> Date: Tue, 18 Oct 2022 11:27:54 +0900 Subject: [PATCH 109/311] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 76e026e01..b3364752c 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Univalent, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. From 7f9269cff21b6136de4b743ec7330d1cdfd37f07 Mon Sep 17 00:00:00 2001 From: Jin Asanami <101626649+Jin-Asanami@users.noreply.github.com> Date: Tue, 18 Oct 2022 11:30:48 +0900 Subject: [PATCH 110/311] Update builtin.c --- src/logo/builtin.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index ba129927f..f55fa6172 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2005,17 +2005,17 @@ static const FFlogo* getLogoUnivalent() FF_LOGO_INIT FF_LOGO_NAMES("univalent", "univalent-linux") FF_LOGO_LINES( - "UUUUU$2\VVVVVVVVVVVVVVVVVVVVV/$1UUUUU\n" - "UUUUUU$2\VVVVVVVVVVVVVVVVVVV/$1UUUUUU\n" - "UUUUUUU$2\VVVVVVVVVVVVVVVVV/$1UUUUUUU\n" - "UUUUUUU $2\VVVVVVVVVVVVVVV/$1 UUUUUUU\n" - "UUUUUUUEE$2\VVVVVVVVVVVVV/$1 UUUUUUU\n" - "UUUUUUUEEE$2\VVVVVVVVVVV/$1 UUUUUUU\n" - "UUUUUUU $2\VVVVVVVVV/$1 UUUUUUU\n" - "UUUUUUUEEEEE$2\VVVVVVV/$1 UUUUUUU\n" - "UUUUUUUEEEEEE$2\VVVVV/$1 UUUUUUU\n" - "UUUUUUU $2\VVV/$1 UUUUUUU\n" - " UUUUUUU $2\V/$1 UUUUUUU\n" + "UUUUU$2VVVVVVVVVVVVVVVVVVVVVVV$1UUUUU\n" + "UUUUUU$2VVVVVVVVVVVVVVVVVVVVV$1UUUUUU\n" + "UUUUUUU$2VVVVVVVVVVVVVVVVVVV$1UUUUUUU\n" + "UUUUUUU $2VVVVVVVVVVVVVVVVV$1 UUUUUUU\n" + "UUUUUUUEE$2VVVVVVVVVVVVVVV$1 UUUUUUU\n" + "UUUUUUUEEE$2VVVVVVVVVVVVV$1 UUUUUUU\n" + "UUUUUUU $2VVVVVVVVVVV$1 UUUUUUU\n" + "UUUUUUUEEEEE$2VVVVVVVVV$1 UUUUUUU\n" + "UUUUUUUEEEEEE$2VVVVVVV$1 UUUUUUU\n" + "UUUUUUU $2VVVVV$1 UUUUUUU\n" + " UUUUUUU $2VVV$1 UUUUUUU\n" " UUUUUUU $2V$1 UUUUUUU\n" " UUUUUUUUUUUUUUUUUUU\n" " UUUUUUUUUUUUU\n" From e3ea39afaa040a0e3534bbbd8bf73ba8e5fa9ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 18 Oct 2022 18:39:28 +0800 Subject: [PATCH 111/311] Disk: add volume name detection --- presets/verbose | 2 +- src/detection/disk/disk.h | 1 + src/detection/disk/disk_apple.m | 28 ++++++++++++++-------------- src/detection/disk/disk_linux.c | 2 ++ src/detection/disk/disk_windows.c | 9 +++++++-- src/modules/disk.c | 5 +++-- 6 files changed, 28 insertions(+), 19 deletions(-) diff --git a/presets/verbose b/presets/verbose index 95512dc86..3ab55d1c0 100644 --- a/presets/verbose +++ b/presets/verbose @@ -19,7 +19,7 @@ --cpu-usage-format Percentage: {} --gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {} --memory-format Used: {}; Total: {}; Percentage: {} ---disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; Removable: {}; Hidden: {}; Filesystem: {} +--disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; Removable: {}; Hidden: {}; Filesystem: {}; Name: {} --battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {} --poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {} --player-format Pretty: {}; Name: {}; Bus: {}; Url: {} diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index 30243d73c..e8b6b100b 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -16,6 +16,7 @@ typedef struct FFDisk { FFstrbuf mountpoint; FFstrbuf filesystem; + FFstrbuf name; FFDiskType type; uint64_t bytesUsed; diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index 804a75dd8..a267d1177 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -4,16 +4,6 @@ #import #import -static bool getBool(NSURL* url, NSURLResourceKey key) -{ - NSError *error; - NSNumber* result; - if([url getResourceValue:&result forKey:key error:&error] == NO) - return false; - - return result.boolValue; -} - void ffDetectDisksImpl(FFDiskResult* disks) { NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil]; @@ -32,8 +22,9 @@ void ffDetectDisksImpl(FFDiskResult* disks) ffStrbufInitS(&disk->mountpoint, [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]); NSString* filesystem; - [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:url.relativePath - isRemovable:nil + BOOL removable; + [NSWorkspace.sharedWorkspace getFileSystemInfoForPath:url.relativePath + isRemovable:&removable isWritable:nil isUnmountable:nil description:nil @@ -41,13 +32,22 @@ void ffDetectDisksImpl(FFDiskResult* disks) ]; ffStrbufInitS(&disk->filesystem, [filesystem cStringUsingEncoding:NSUTF8StringEncoding]); - if(getBool(url, NSURLVolumeIsRemovableKey)) + NSError* error; + + NSNumber* isBrowsable; + if(removable) disk->type = FF_DISK_TYPE_EXTERNAL; - else if(getBool(url, NSURLVolumeIsBrowsableKey)) + else if([url getResourceValue:&isBrowsable forKey:NSURLVolumeIsBrowsableKey error:&error] == YES && isBrowsable.boolValue) disk->type = FF_DISK_TYPE_REGULAR; else disk->type = FF_DISK_TYPE_HIDDEN; + NSString* volumeName; + if([url getResourceValue:&volumeName forKey:NSURLVolumeNameKey error:&error] == YES) + ffStrbufInitS(&disk->name, [volumeName cStringUsingEncoding:NSUTF8StringEncoding]); + else + ffStrbufInit(&disk->name); + 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 diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index bbf4e22a8..2ff4395a9 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -72,6 +72,8 @@ void ffDetectDisksImpl(FFDiskResult* disks) disk->filesTotal = (uint32_t) fs.f_files; disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); + + ffStrbufInit(&disk->name); //TODO: implement this } if(line != NULL) diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c index 28e010b0b..2d11739b4 100644 --- a/src/detection/disk/disk_windows.c +++ b/src/detection/disk/disk_windows.c @@ -22,7 +22,7 @@ void ffDetectDisksImpl(FFDiskResult* disks) UINT driveType = GetDriveTypeA(mountpoint); if(driveType == DRIVE_NO_ROOT_DIR) { - i += strlen(mountpoint); + i += (uint32_t)strlen(mountpoint); continue; } @@ -45,13 +45,18 @@ void ffDetectDisksImpl(FFDiskResult* disks) disk->type = FF_DISK_TYPE_HIDDEN; ffStrbufInitA(&disk->filesystem, MAX_PATH + 1); + ffStrbufInitA(&disk->name, MAX_PATH + 1); + //https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa#remarks + UINT errorMode = SetErrorMode(SEM_FAILCRITICALERRORS); GetVolumeInformationA(mountpoint, - NULL, 0, //Volume name + disk->name.chars, disk->name.allocated, //Volume name NULL, //Serial number NULL, //Max component length NULL, //File system flags disk->filesystem.chars, disk->filesystem.allocated ); + SetErrorMode(errorMode); + ffStrbufRecalculateLength(&disk->name); ffStrbufRecalculateLength(&disk->filesystem); //TODO: implement diff --git a/src/modules/disk.c b/src/modules/disk.c index 88dd6634d..3ec02f59f 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -4,7 +4,7 @@ #include "detection/disk/disk.h" #define FF_DISK_MODULE_NAME "Disk" -#define FF_DISK_NUM_FORMAT_ARGS 9 +#define FF_DISK_NUM_FORMAT_ARGS 10 static void printDisk(FFinstance* instance, const FFDisk* disk) { @@ -49,7 +49,8 @@ static void printDisk(FFinstance* instance, const FFDisk* disk) {FF_FORMAT_ARG_TYPE_UINT8, &disk->filesPercentage}, {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type == FF_DISK_TYPE_EXTERNAL)}, {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type == FF_DISK_TYPE_HIDDEN)}, - {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem} + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem}, + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->name} }); } From 3d5ef186baa0496edca28a034144dea769d92f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 18 Oct 2022 18:50:38 +0800 Subject: [PATCH 112/311] Disk: don't convert NAN to integer; don't print 0B / 0B (0%) fix ASAN warning: `runtime error: nan is outside the range of representable values of type 'unsigned char'` --- src/detection/disk/disk.c | 7 ------- src/detection/disk/disk.h | 2 -- src/modules/disk.c | 14 +++++++++++--- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/detection/disk/disk.c b/src/detection/disk/disk.c index 3ce33aed5..de25d634e 100644 --- a/src/detection/disk/disk.c +++ b/src/detection/disk/disk.c @@ -19,13 +19,6 @@ const FFDiskResult* ffDetectDisks() if(result.disks.length == 0 && result.error.length == 0) ffStrbufAppendS(&result.error, "No disks found"); - for(uint32_t i = 0; i < result.disks.length; ++i) - { - FFDisk* disk = ffListGet(&result.disks, i); - disk->bytesPercentage = (uint8_t) (((long double) disk->bytesUsed / (long double) disk->bytesTotal) * 100.0); - disk->filesPercentage = (uint8_t) (((long double) disk->filesUsed / (long double) disk->filesTotal) * 100.0); - } - //We need to sort the disks, so that we can detect, which disk a path resides on // For example for /boot/efi/bootmgr we need to check /boot/efi before /boot //Note that we sort alphabetically here for a better ordering when printing the list, diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index e8b6b100b..c061ce6c9 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -21,11 +21,9 @@ typedef struct FFDisk uint64_t bytesUsed; uint64_t bytesTotal; - uint8_t bytesPercentage; uint32_t filesUsed; uint32_t filesTotal; - uint8_t filesPercentage; } FFDisk; typedef struct FFDiskResult diff --git a/src/modules/disk.c b/src/modules/disk.c index 3ec02f59f..0245d8a4a 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -30,23 +30,31 @@ static void printDisk(FFinstance* instance, const FFDisk* disk) ffStrbufInit(&totalPretty); ffParseSize(disk->bytesTotal, instance->config.binaryPrefixType, &totalPretty); + uint8_t bytesPercentage = disk->bytesTotal > 0 ? (uint8_t) (((long double) disk->bytesUsed / (long double) disk->bytesTotal) * 100.0) : 0; + if(instance->config.disk.outputFormat.length == 0) { ffPrintLogoAndKey(instance, key.chars, 0, NULL); - printf("%s / %s (%u%%)", usedPretty.chars, totalPretty.chars, disk->bytesPercentage); + if(disk->bytesTotal > 0) + printf("%s / %s (%u%%)", usedPretty.chars, totalPretty.chars, bytesPercentage); + else + fputs("unknown", stdout); + if(disk->type == FF_DISK_TYPE_EXTERNAL) printf(" [Removable]"); putchar('\n'); } else { + uint8_t filesPercentage = disk->filesTotal > 0 ? (uint8_t) (((double) disk->filesUsed / (double) disk->filesTotal) * 100.0) : 0; + ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &disk->bytesPercentage}, + {FF_FORMAT_ARG_TYPE_UINT8, &bytesPercentage}, {FF_FORMAT_ARG_TYPE_UINT, &disk->filesUsed}, {FF_FORMAT_ARG_TYPE_UINT, &disk->filesTotal}, - {FF_FORMAT_ARG_TYPE_UINT8, &disk->filesPercentage}, + {FF_FORMAT_ARG_TYPE_UINT8, &filesPercentage}, {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type == FF_DISK_TYPE_EXTERNAL)}, {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type == FF_DISK_TYPE_HIDDEN)}, {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem}, From 581c6f547dd839b812c1cbe75882b3f7ae49a284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 18 Oct 2022 23:46:42 +0800 Subject: [PATCH 113/311] Swap: split code out from memory detection 1. Since swap module is disabled by default, swap detection is unnecessary in most cases. 2. On platform other than Linux, swap detection doesn't share code with memory. 3. Swap detection can be expensive. On Windows, it requires another WMI query which can lag heavily in some cases. Don't pay for you don't use. --- CMakeLists.txt | 5 ++++ src/detection/memory/memory.c | 22 +++------------- src/detection/memory/memory.h | 18 ++----------- src/detection/memory/memory_apple.c | 22 +--------------- src/detection/memory/memory_bsd.c | 12 +-------- src/detection/memory/memory_linux.c | 34 ++++++++++--------------- src/detection/memory/memory_windows.cpp | 28 ++------------------ src/detection/storage.h | 16 ++++++++++++ src/detection/swap/swap.c | 13 ++++++++++ src/detection/swap/swap.h | 10 ++++++++ src/detection/swap/swap_apple.c | 18 +++++++++++++ src/detection/swap/swap_bsd.c | 6 +++++ src/detection/swap/swap_linux.c | 34 +++++++++++++++++++++++++ src/detection/swap/swap_windows.cpp | 23 +++++++++++++++++ src/modules/memory.c | 21 ++++++++++----- 15 files changed, 163 insertions(+), 119 deletions(-) create mode 100644 src/detection/storage.h create mode 100644 src/detection/swap/swap.c create mode 100644 src/detection/swap/swap.h create mode 100644 src/detection/swap/swap_apple.c create mode 100644 src/detection/swap/swap_bsd.c create mode 100644 src/detection/swap/swap_linux.c create mode 100644 src/detection/swap/swap_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f66eb6f62..78bbf0d33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,6 +235,7 @@ set(LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage.c src/detection/gpu/gpu.c src/detection/memory/memory.c + src/detection/swap/swap.c src/detection/font/font.c src/detection/displayserver/displayserver.c src/detection/terminalfont/terminalfont.c @@ -307,6 +308,7 @@ if(LINUX OR ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c + src/detection/swap/swap_linux.c ) endif() @@ -365,6 +367,7 @@ if(WIN32) src/detection/cpuUsage/cpuUsage_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp + src/detection/swap/swap_windows.cpp src/detection/font/font_windows.cpp src/detection/terminalfont/terminalfont_windows.c src/detection/localip/localip_windows.c @@ -393,6 +396,7 @@ if(APPLE) src/detection/battery/battery_apple.c src/detection/poweradapter/poweradapter_apple.c src/detection/memory/memory_apple.c + src/detection/swap/swap_apple.c src/detection/displayserver/displayserver_apple.c src/detection/terminalfont/terminalfont_apple.m src/detection/media/media_apple.m @@ -414,6 +418,7 @@ if(BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_bsd.c src/detection/memory/memory_bsd.c + src/detection/swap/swap_bsd.c ) endif() diff --git a/src/detection/memory/memory.c b/src/detection/memory/memory.c index 62be6197e..107e7d716 100644 --- a/src/detection/memory/memory.c +++ b/src/detection/memory/memory.c @@ -1,27 +1,13 @@ #include "memory.h" #include "detection/internal.h" -void ffDetectMemoryImpl(FFMemoryResult* memory); +void ffDetectMemoryImpl(FFMemoryStorage* memory); -static void calculatePercentage(FFMemoryStorage* storage) +const FFMemoryStorage* ffDetectMemory() { - if(storage->error.length != 0) - return; - - if(storage->bytesTotal == 0) - storage->percentage = 0; - else - storage->percentage = (uint8_t) (((long double) storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); -} - -const FFMemoryResult* ffDetectMemory() -{ - FF_DETECTION_INTERNAL_GUARD(FFMemoryResult, - ffStrbufInitA(&result.ram.error, 0); - ffStrbufInitA(&result.swap.error, 0); + FF_DETECTION_INTERNAL_GUARD(FFMemoryStorage, + ffStrbufInit(&result.error); ffDetectMemoryImpl(&result); - calculatePercentage(&result.ram); - calculatePercentage(&result.swap); ); } diff --git a/src/detection/memory/memory.h b/src/detection/memory/memory.h index a46d259c1..1114ff4cb 100644 --- a/src/detection/memory/memory.h +++ b/src/detection/memory/memory.h @@ -3,22 +3,8 @@ #ifndef FF_INCLUDED_detection_memory_memory #define FF_INCLUDED_detection_memory_memory -#include "fastfetch.h" +#include "detection/storage.h" -typedef struct FFMemoryStorage -{ - FFstrbuf error; - uint64_t bytesUsed; - uint64_t bytesTotal; - uint8_t percentage; -} FFMemoryStorage; - -typedef struct FFMemoryResult -{ - FFMemoryStorage ram; - FFMemoryStorage swap; -} FFMemoryResult; - -const FFMemoryResult* ffDetectMemory(); +const FFMemoryStorage* ffDetectMemory(); #endif diff --git a/src/detection/memory/memory_apple.c b/src/detection/memory/memory_apple.c index 235b13443..b3616ec59 100644 --- a/src/detection/memory/memory_apple.c +++ b/src/detection/memory/memory_apple.c @@ -4,7 +4,7 @@ #include #include -static void detectRam(FFMemoryStorage* ram) +void ffDetectMemoryImpl(FFMemoryStorage* ram) { ram->bytesTotal = (uint64_t) ffSysctlGetInt64("hw.memsize", 0); if(ram->bytesTotal == 0) @@ -30,23 +30,3 @@ static void detectRam(FFMemoryStorage* ram) ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * pagesize; } - -static void detectSwap(FFMemoryStorage* swap) -{ - struct xsw_usage xsw; - size_t size = sizeof(xsw); - if(sysctlbyname("vm.swapusage", &xsw, &size, 0, 0) != 0) - { - ffStrbufAppendS(&swap->error, "Failed to read vm.swapusage"); - return; - } - - swap->bytesTotal = xsw.xsu_total; - swap->bytesUsed = xsw.xsu_used; -} - -void ffDetectMemoryImpl(FFMemoryResult* memory) -{ - detectRam(&memory->ram); - detectSwap(&memory->swap); -} diff --git a/src/detection/memory/memory_bsd.c b/src/detection/memory/memory_bsd.c index 55f34c83c..881b3dfb3 100644 --- a/src/detection/memory/memory_bsd.c +++ b/src/detection/memory/memory_bsd.c @@ -1,7 +1,7 @@ #include "memory.h" #include "common/sysctl.h" -static void detectRam(FFMemoryStorage* ram) +void ffDetectMemoryImpl(FFMemoryStorage* ram) { uint32_t pageSize = (uint32_t) ffSysctlGetInt("hw.pagesize", 0); if(pageSize == 0) @@ -22,13 +22,3 @@ static void detectRam(FFMemoryStorage* ram) - (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_inactive_count", 0) * pageSize ; } - -static void detectSwap(FFMemoryStorage* swap) -{ - ffStrbufAppendS(&swap->error, "Not implemented"); -} -void ffDetectMemoryImpl(FFMemoryResult* memory) -{ - detectRam(&memory->ram); - detectSwap(&memory->swap); -} diff --git a/src/detection/memory/memory_linux.c b/src/detection/memory/memory_linux.c index b83819295..3a5d55ee0 100644 --- a/src/detection/memory/memory_linux.c +++ b/src/detection/memory/memory_linux.c @@ -3,13 +3,12 @@ #include #include -void ffDetectMemoryImpl(FFMemoryResult* memory) +void ffDetectMemoryImpl(FFMemoryStorage* swap) { FILE* meminfo = fopen("/proc/meminfo", "r"); if(meminfo == NULL) { - ffStrbufAppendS(&memory->ram.error, "Failed to open /proc/meminfo"); - ffStrbufAppendS(&memory->swap.error, "Failed to open /proc/meminfo"); + ffStrbufAppendS(&swap->error, "Failed to open /proc/meminfo"); return; } @@ -21,20 +20,16 @@ void ffDetectMemoryImpl(FFMemoryResult* memory) memFree = 0, buffers = 0, cached = 0, - sReclaimable = 0, - swapTotal = 0, - swapFree = 0; + sReclaimable = 0; while (getline(&line, &len, meminfo) != EOF) { - sscanf(line, "MemTotal: %u", &memTotal); - sscanf(line, "Shmem: %u", &shmem); - sscanf(line, "MemFree: %u", &memFree); - sscanf(line, "Buffers: %u", &buffers); - sscanf(line, "Cached: %u", &cached); - sscanf(line, "SReclaimable: %u", &sReclaimable); - sscanf(line, "SwapTotal: %u", &swapTotal); - sscanf(line, "SwapFree: %u", &swapFree); + if(!sscanf(line, "MemTotal: %u", &memTotal)) + if(!sscanf(line, "Shmem: %u", &shmem)) + if(!sscanf(line, "MemFree: %u", &memFree)) + if(!sscanf(line, "Buffers: %u", &buffers)) + if(!sscanf(line, "Cached: %u", &cached)) + sscanf(line, "SReclaimable: %u", &sReclaimable); } if(line != NULL) @@ -42,12 +37,9 @@ void ffDetectMemoryImpl(FFMemoryResult* memory) fclose(meminfo); - memory->ram.bytesTotal = memTotal * (uint64_t) 1024; - if(memory->ram.bytesTotal == 0) - ffStrbufAppendS(&memory->ram.error, "Failed to read MemTotal"); + swap->bytesTotal = memTotal * (uint64_t) 1024; + if(swap->bytesTotal == 0) + ffStrbufAppendS(&swap->error, "Failed to read MemTotal"); else - memory->ram.bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024; - - memory->swap.bytesTotal = swapTotal * (uint64_t) 1024; - memory->swap.bytesUsed = (swapTotal - swapFree) * (uint64_t) 1024; + swap->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024; } diff --git a/src/detection/memory/memory_windows.cpp b/src/detection/memory/memory_windows.cpp index a11308e0d..122e28d26 100644 --- a/src/detection/memory/memory_windows.cpp +++ b/src/detection/memory/memory_windows.cpp @@ -3,7 +3,8 @@ extern "C" { } #include "util/windows/wmi.hpp" -void detectRam(FFMemoryStorage* ram) +extern "C" +void ffDetectMemoryImpl(FFMemoryStorage* ram) { FFWmiQuery query(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error); if(!query) @@ -22,28 +23,3 @@ void detectRam(FFMemoryStorage* ram) else ffStrbufInitS(&ram->error, "No Wmi result returned"); } - -void detectSwap(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"); -} - -extern "C" -void ffDetectMemoryImpl(FFMemoryResult* memory) -{ - detectRam(&memory->ram); - detectSwap(&memory->swap); -} diff --git a/src/detection/storage.h b/src/detection/storage.h new file mode 100644 index 000000000..c4cce7ede --- /dev/null +++ b/src/detection/storage.h @@ -0,0 +1,16 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_storage +#define FF_INCLUDED_detection_storage + +#include "fastfetch.h" + +typedef struct FFMemoryStorage +{ + FFstrbuf error; + uint64_t bytesUsed; + uint64_t bytesTotal; + uint8_t percentage; +} FFMemoryStorage; + +#endif diff --git a/src/detection/swap/swap.c b/src/detection/swap/swap.c new file mode 100644 index 000000000..0a790c9f7 --- /dev/null +++ b/src/detection/swap/swap.c @@ -0,0 +1,13 @@ +#include "swap.h" +#include "detection/internal.h" + +void ffDetectSwapImpl(FFMemoryStorage* swap); + +const FFMemoryStorage* ffDetectSwap() +{ + FF_DETECTION_INTERNAL_GUARD(FFMemoryStorage, + ffStrbufInit(&result.error); + + ffDetectSwapImpl(&result); + ); +} diff --git a/src/detection/swap/swap.h b/src/detection/swap/swap.h new file mode 100644 index 000000000..a0374cf2b --- /dev/null +++ b/src/detection/swap/swap.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_swap_swap +#define FF_INCLUDED_detection_swap_swap + +#include "detection/storage.h" + +const FFMemoryStorage* ffDetectSwap(); + +#endif diff --git a/src/detection/swap/swap_apple.c b/src/detection/swap/swap_apple.c new file mode 100644 index 000000000..19ea32c00 --- /dev/null +++ b/src/detection/swap/swap_apple.c @@ -0,0 +1,18 @@ +#include "swap.h" +#include "common/sysctl.h" + +#include + +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + struct xsw_usage xsw; + size_t size = sizeof(xsw); + if(sysctlbyname("vm.swapusage", &xsw, &size, 0, 0) != 0) + { + ffStrbufAppendS(&swap->error, "Failed to read vm.swapusage"); + return; + } + + swap->bytesTotal = xsw.xsu_total; + swap->bytesUsed = xsw.xsu_used; +} diff --git a/src/detection/swap/swap_bsd.c b/src/detection/swap/swap_bsd.c new file mode 100644 index 000000000..8af98a16f --- /dev/null +++ b/src/detection/swap/swap_bsd.c @@ -0,0 +1,6 @@ +#include "swap.h" + +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + ffStrbufAppendS(&swap->error, "Not implemented"); +} diff --git a/src/detection/swap/swap_linux.c b/src/detection/swap/swap_linux.c new file mode 100644 index 000000000..e176bb158 --- /dev/null +++ b/src/detection/swap/swap_linux.c @@ -0,0 +1,34 @@ +#include "swap.h" + +#include +#include + +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + FILE* meminfo = fopen("/proc/meminfo", "r"); + if(meminfo == NULL) + { + ffStrbufAppendS(&swap->error, "Failed to open /proc/meminfo"); + return; + } + + char* line = NULL; + size_t len = 0; + + uint32_t swapTotal = 0, + swapFree = 0; + + while (getline(&line, &len, meminfo) != EOF) + { + if(!sscanf(line, "SwapTotal: %u", &swapTotal)) + sscanf(line, "SwapFree: %u", &swapFree); + } + + if(line != NULL) + free(line); + + fclose(meminfo); + + swap->bytesTotal = swapTotal * (uint64_t) 1024; + swap->bytesUsed = (swapTotal - swapFree) * (uint64_t) 1024; +} diff --git a/src/detection/swap/swap_windows.cpp b/src/detection/swap/swap_windows.cpp new file mode 100644 index 000000000..6e82cccab --- /dev/null +++ b/src/detection/swap/swap_windows.cpp @@ -0,0 +1,23 @@ +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"); +} diff --git a/src/modules/memory.c b/src/modules/memory.c index f3f2c17ee..c3681a136 100644 --- a/src/modules/memory.c +++ b/src/modules/memory.c @@ -2,12 +2,21 @@ #include "common/printing.h" #include "common/parsing.h" #include "detection/memory/memory.h" +#include "detection/swap/swap.h" #define FF_MEMORY_MODULE_NAME "Memory" #define FF_SWAP_MODULE_NAME "Swap" #define FF_MEMORY_NUM_FORMAT_ARGS 3 +static uint8_t calculatePercentage(const FFMemoryStorage* storage) +{ + if(storage->error.length != 0 || storage->bytesTotal == 0) + return 0; + else + return (uint8_t) (((long double) storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); +} + static void printMemory(FFinstance* instance, const char* name, const FFModuleArgs* moduleArgs, const FFMemoryStorage* storage) { if(storage->error.length > 0) @@ -24,20 +33,22 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr ffStrbufInit(&totalPretty); ffParseSize(storage->bytesTotal, instance->config.binaryPrefixType, &totalPretty); + uint8_t percentage = calculatePercentage(storage); + if(moduleArgs->outputFormat.length == 0) { ffPrintLogoAndKey(instance, name, 0, &moduleArgs->key); if (storage->bytesTotal == 0) puts("Disabled"); else - printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, storage->percentage); + printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, percentage); } else { ffPrintFormat(instance, name, 0, moduleArgs, FF_MEMORY_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &storage->percentage}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, }); } @@ -47,12 +58,10 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr void ffPrintMemory(FFinstance* instance) { - const FFMemoryResult* memory = ffDetectMemory(); - printMemory(instance, FF_MEMORY_MODULE_NAME, &instance->config.memory, &memory->ram); + printMemory(instance, FF_MEMORY_MODULE_NAME, &instance->config.memory, ffDetectMemory()); } void ffPrintSwap(FFinstance* instance) { - const FFMemoryResult* memory = ffDetectMemory(); - printMemory(instance, FF_SWAP_MODULE_NAME, &instance->config.swap, &memory->swap); + printMemory(instance, FF_SWAP_MODULE_NAME, &instance->config.swap, ffDetectSwap()); } From 596c7764639bf6da622c5ec3e12fc960b522d965 Mon Sep 17 00:00:00 2001 From: Jin Asanami <101626649+Jin-Asanami@users.noreply.github.com> Date: Wed, 19 Oct 2022 12:18:39 +0900 Subject: [PATCH 114/311] fix univalent's colours --- src/logo/builtin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index f55fa6172..157888d6a 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2021,11 +2021,11 @@ static const FFlogo* getLogoUnivalent() " UUUUUUUUUUUUU\n" ) FF_LOGO_COLORS( - "34" //blue + "34", //blue "32" //green ) - FF_LOGO_COLOR_KEYS("32"); //blue - FF_LOGO_COLOR_TITLE("32"); //blue + FF_LOGO_COLOR_KEYS("34"); //blue + FF_LOGO_COLOR_TITLE("34"); //blue FF_LOGO_RETURN } From b27453d2751468cc079bcf4120731bc31ee60568 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Wed, 19 Oct 2022 08:29:39 +0200 Subject: [PATCH 115/311] Revert "Add Univalent GNU/Linux's logo" --- README.md | 2 +- src/logo/builtin.c | 30 ------------------------------ 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/README.md b/README.md index b3364752c..76e026e01 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Univalent, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 157888d6a..cbc16ae4b 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2000,35 +2000,6 @@ static const FFlogo* getLogoUbuntuSmall() FF_LOGO_RETURN } -static const FFlogo* getLogoUnivalent() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("univalent", "univalent-linux") - FF_LOGO_LINES( - "UUUUU$2VVVVVVVVVVVVVVVVVVVVVVV$1UUUUU\n" - "UUUUUU$2VVVVVVVVVVVVVVVVVVVVV$1UUUUUU\n" - "UUUUUUU$2VVVVVVVVVVVVVVVVVVV$1UUUUUUU\n" - "UUUUUUU $2VVVVVVVVVVVVVVVVV$1 UUUUUUU\n" - "UUUUUUUEE$2VVVVVVVVVVVVVVV$1 UUUUUUU\n" - "UUUUUUUEEE$2VVVVVVVVVVVVV$1 UUUUUUU\n" - "UUUUUUU $2VVVVVVVVVVV$1 UUUUUUU\n" - "UUUUUUUEEEEE$2VVVVVVVVV$1 UUUUUUU\n" - "UUUUUUUEEEEEE$2VVVVVVV$1 UUUUUUU\n" - "UUUUUUU $2VVVVV$1 UUUUUUU\n" - " UUUUUUU $2VVV$1 UUUUUUU\n" - " UUUUUUU $2V$1 UUUUUUU\n" - " UUUUUUUUUUUUUUUUUUU\n" - " UUUUUUUUUUUUU\n" - ) - FF_LOGO_COLORS( - "34", //blue - "32" //green - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - static const FFlogo* getLogoVoid() { FF_LOGO_INIT @@ -2184,7 +2155,6 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoUbuntu, getLogoUbuntuOld, getLogoUbuntuSmall, - getlogoUnivalent, getLogoVoid, getLogoVoidSmall, getLogoZorin, From fbc76714f57a801a666cdbb98e255c2169c550e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 20 Oct 2022 15:46:41 +0800 Subject: [PATCH 116/311] Android: add vulkan support for GPU detection Termux does have package pciutils, but it's put inside of root-repo and and doesn't provide libpci.pc. So I think use vulkan can be a better option than libpci because vulkan.so is provided by Android system. To build with android support, install `vulkan-headers` and `vulkan-loader-android` (for `vulkan.pc`). --- CMakeLists.txt | 2 +- README.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78bbf0d33..2276a01fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ include(CheckIncludeFile) include(CMakeDependentOption) cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32" OFF) +cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF) diff --git a/README.md b/README.md index 76e026e01..df0d96a52 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ The following libraries are used if present at runtime: ### macOS * [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system. -* [`libvulkan`](https://www.vulkan.org/): Vulkan module. To get it actually working, both loader (`vulkan-loader`) and driver (molten-vk) need to be installed. +* [`libvulkan`](https://www.vulkan.org/): Vulkan module. To get it actually working, both loader (`vulkan-loader`) and driver (`molten-vk`) need to be installed. ### Windows @@ -64,6 +64,7 @@ The following libraries are used if present at runtime: ### Android * [`freetype`](https://www.freetype.org/): Used for Termux font detection. +* [`libvulkan`](https://www.vulkan.org/): Vulkan module, also used for GPU detection. Usually has been provided by Android system. ## Support status All categories not listed here should work without needing a specific implementation. From e13c88cea609fbf9869a9762ce2136a6bdea7621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 18 Oct 2022 22:55:28 +0800 Subject: [PATCH 117/311] Global: support bar output for percentage value #294 --- CMakeLists.txt | 1 + completions/bash | 1 + src/common/bar.c | 48 ++++++++++++++++++++++ src/common/bar.h | 16 ++++++++ src/common/init.c | 2 + src/data/config_user.txt | 6 +++ src/data/help.txt | 1 + src/detection/battery/battery.h | 2 +- src/detection/battery/battery_apple.c | 4 +- src/detection/battery/battery_linux.c | 12 +++--- src/detection/battery/battery_windows.cpp | 4 +- src/fastfetch.c | 2 + src/fastfetch.h | 2 + src/modules/battery.c | 50 ++++++++++++++++------- src/modules/cpuUsage.c | 20 +++++++-- src/modules/disk.c | 25 ++++++++++-- src/modules/memory.c | 20 ++++++++- 17 files changed, 180 insertions(+), 36 deletions(-) create mode 100644 src/common/bar.c create mode 100644 src/common/bar.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 78bbf0d33..a595fa5d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,6 +221,7 @@ set(LIBFASTFETCH_SRC src/common/settings.c src/common/library.c src/common/networking.c + src/common/bar.c src/logo/logo.c src/logo/builtin.c src/logo/image/image.c diff --git a/completions/bash b/completions/bash index 907f8c27f..fc771d5ad 100644 --- a/completions/bash +++ b/completions/bash @@ -218,6 +218,7 @@ __fastfetch_completion() "--set" "--set-keyless" "--player-name" + "--percent-type" "--public-ip-url" "--public-ip-timeout" "--weather-output-format" diff --git a/src/common/bar.c b/src/common/bar.c new file mode 100644 index 000000000..4b8ae00a3 --- /dev/null +++ b/src/common/bar.c @@ -0,0 +1,48 @@ +#include "bar.h" + +// green, yellow, red: print the color on nth (0~9) block +// set its value == 10 means the color will not be printed +void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red) +{ + assert(green <= 10 && yellow <= 10 && red <= 10); + + // [ 0%, 5%) prints 0 blocks + // [ 5%, 15%) prints 1 block; + // ... + // [85%, 95%) prints 9 blocks; + // [95%,100%] prints 10 blocks + percent = (percent + 5) / 10; + assert(percent <= 10); + + if(!instance->config.pipe) + ffStrbufAppendS(buffer, "\033[97m[ "); + else + ffStrbufAppendS(buffer, "[ "); + + for (uint8_t i = 0; i < percent; ++i) + { + if(!instance->config.pipe) + { + if (i == green) + ffStrbufAppendS(buffer, "\033[32m"); + else if (i == yellow) + ffStrbufAppendS(buffer, "\033[93m"); + else if (i == red) + ffStrbufAppendS(buffer, "\033[91m"); + } + ffStrbufAppendS(buffer, "■"); + } + + if (percent < 10) + { + if(!instance->config.pipe) + ffStrbufAppendS(buffer, "\033[97m"); + for (uint8_t i = percent; i < 10; ++i) + ffStrbufAppendS(buffer, "-"); + } + + if(!instance->config.pipe) + ffStrbufAppendS(buffer, "\033[97m ]" FASTFETCH_TEXT_MODIFIER_RESET); + else + ffStrbufAppendS(buffer, " ]"); +} diff --git a/src/common/bar.h b/src/common/bar.h new file mode 100644 index 000000000..a6c2be234 --- /dev/null +++ b/src/common/bar.h @@ -0,0 +1,16 @@ +#pragma once + +#ifndef FF_INCLUDED_common_bar +#define FF_INCLUDED_common_bar + +#include "fastfetch.h" + +enum +{ + FF_PERCENTAGE_TYPE_NUM_BIT = 1, + FF_PERCENTAGE_TYPE_BAR_BIT = 2, +}; + +void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red); + +#endif diff --git a/src/common/init.c b/src/common/init.c index af4ab7bfe..b2d69197c 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -274,6 +274,8 @@ static void defaultConfig(FFinstance* instance) ffStrbufInitA(&instance->config.osFile, 0); ffStrbufInitA(&instance->config.playerName, 0); + + instance->config.percentType = 1; } void ffInitInstance(FFinstance* instance) diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 1e68fe85b..95518af0f 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -200,6 +200,12 @@ # Default is auto. #--gl auto +# Percentage output type option +# Applies to all modules that prints percentage values. Currently memory, swap, disk, battery and CPU usage are supported. +# Only works with default format ( without --module-format option ). +# 0: prints none; 1: prints percent number only; 2: prints bar only; 3: prints both percent number and bar +#--percent-type 1 + # Key options: # Sets the displayed key of a module # Can be any string. Some of theme take an argument like a format string. See "fastfetch --help format" for help. diff --git a/src/data/help.txt b/src/data/help.txt index 9d8c32027..ed25dcb11 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -107,6 +107,7 @@ Module specific options: --weather-output-format: The output weather format to be used. It must be URI encoded. --player-name: The name of the player to use --gl : Sets the opengl context creation library to use. Must be auto, egl, glx or osmesa. Default is auto + --percent-type : Sets the percentage output type. 1 for percentage number, 2 for bar, 3 for both. Default is 1 Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci" If a value starts with a ?, it is optional. "true" will be used if not set. diff --git a/src/detection/battery/battery.h b/src/detection/battery/battery.h index 6269f590a..ab0021b91 100644 --- a/src/detection/battery/battery.h +++ b/src/detection/battery/battery.h @@ -12,7 +12,7 @@ typedef struct BatteryResult FFstrbuf manufacturer; FFstrbuf modelName; FFstrbuf technology; - FFstrbuf capacity; + double capacity; FFstrbuf status; double temperature; } BatteryResult; diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index 0e9667cf7..88499aaa7 100644 --- a/src/detection/battery/battery_apple.c +++ b/src/detection/battery/battery_apple.c @@ -55,7 +55,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) const char* error; BatteryResult* battery = ffListAdd(results); - ffStrbufInit(&battery->capacity); + battery->capacity = 0.0/0.0; int currentCapacity, maxCapacity; if ((error = ffCfDictGetInt(properties, CFSTR("MaxCapacity"), &maxCapacity))) @@ -68,7 +68,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) if(currentCapacity <= 0) return "Querying CurrentCapacity failed"; - ffStrbufAppendF(&battery->capacity, "%.0f", currentCapacity * 100.0 / maxCapacity); + battery->capacity = currentCapacity * 100.0 / maxCapacity; ffStrbufInit(&battery->manufacturer); ffStrbufInit(&battery->modelName); diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c index 6a8643521..6fe799eb0 100644 --- a/src/detection/battery/battery_linux.c +++ b/src/detection/battery/battery_linux.c @@ -33,18 +33,18 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) return; } - ffStrbufDestroy(&testBatteryBuffer); BatteryResult* result = ffListAdd(results); //capacity must exist and be not empty - ffStrbufInit(&result->capacity); ffStrbufAppendS(dir, "/capacity"); - ffReadFileBuffer(dir->chars, &result->capacity); + bool available = ffReadFileBuffer(dir->chars, &testBatteryBuffer); ffStrbufSubstrBefore(dir, dirLength); - - if(result->capacity.length == 0) + if(available) + result->capacity = ffStrbufToDouble(&testBatteryBuffer); + ffStrbufDestroy(&testBatteryBuffer); + if(!available) { - ffStrbufDestroy(&result->capacity); + result->capacity = 0.0/0.0; --results->length; return; } diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp index a3c2accf0..9cf53ee28 100644 --- a/src/detection/battery/battery_windows.cpp +++ b/src/detection/battery/battery_windows.cpp @@ -38,9 +38,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) default: ffStrbufInit(&battery->technology); break; } - uint64_t capacity; - record.getUnsigned(L"EstimatedChargeRemaining", &capacity); - ffStrbufInitF(&battery->capacity, "%d", (int)capacity); + record.getReal(L"EstimatedChargeRemaining", &battery->capacity); uint64_t batteryStatus; record.getUnsigned(L"BatteryStatus", &batteryStatus); diff --git a/src/fastfetch.c b/src/fastfetch.c index ea2818b96..b64abafb8 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1357,6 +1357,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con NULL ); } + else if(strcasecmp(key, "--percent-type") == 0) + instance->config.percentType = optionParseUInt32(key, value); ////////////////// //Unknown option// diff --git a/src/fastfetch.h b/src/fastfetch.h index d62348e80..b4e639edf 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -189,6 +189,8 @@ typedef struct FFconfig FFstrbuf osFile; FFstrbuf playerName; + + uint32_t percentType; } FFconfig; typedef struct FFstate diff --git a/src/modules/battery.c b/src/modules/battery.c index 58773bf0a..97c603d9a 100644 --- a/src/modules/battery.c +++ b/src/modules/battery.c @@ -1,11 +1,12 @@ #include "fastfetch.h" #include "common/printing.h" +#include "common/bar.h" #include "detection/battery/battery.h" #define FF_BATTERY_MODULE_NAME "Battery" #define FF_BATTERY_NUM_FORMAT_ARGS 5 -static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t index) +static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t index) { if(instance->config.battery.outputFormat.length == 0) { @@ -15,27 +16,47 @@ static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t i result->status.length > 0 && ffStrbufIgnCaseCompS(&result->status, "Unknown") != 0; - if(result->capacity.length > 0) - { - ffStrbufWriteTo(&result->capacity, stdout); - putchar('%'); + FFstrbuf str; + ffStrbufInit(&str); - if(showStatus) - fputs(" [", stdout); + if(result->capacity >= 0) + { + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + if(result->capacity <= 20) + ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 10, 10, 0); + else if(result->capacity <= 50) + ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 10, 0, 10); + else + ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 0, 10, 10); + } + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + ffStrbufAppendF(&str, "%.0f%%", result->capacity); + } } if(showStatus) { - ffStrbufWriteTo(&result->status, stdout); - - if(result->capacity.length > 0) - putchar(']'); + if(str.length > 0) + ffStrbufAppendF(&str, " [%s]", result->status.chars); + else + ffStrbufAppend(&str, &result->status); } if(result->temperature == result->temperature) //FF_BATTERY_TEMP_UNSET - printf(" - %.1f°C", result->temperature); + { + if(str.length > 0) + ffStrbufAppendS(&str, " - "); - putchar('\n'); + ffStrbufAppendF(&str, "%.1f°C", result->temperature); + } + + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); } else { @@ -43,7 +64,7 @@ static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t i {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->technology}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->capacity}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result->capacity}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->status}, {FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature}, }); @@ -71,7 +92,6 @@ void ffPrintBattery(FFinstance* instance) ffStrbufDestroy(&result->manufacturer); ffStrbufDestroy(&result->modelName); ffStrbufDestroy(&result->technology); - ffStrbufDestroy(&result->capacity); ffStrbufDestroy(&result->status); } if(results.length == 0) diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c index db8ea2e5d..3e4165b90 100644 --- a/src/modules/cpuUsage.c +++ b/src/modules/cpuUsage.c @@ -1,5 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" +#include "common/bar.h" #include "detection/cpuUsage/cpuUsage.h" #define FF_CPU_USAGE_MODULE_NAME "CPU Usage" @@ -7,8 +8,8 @@ void ffPrintCPUUsage(FFinstance* instance) { - double cpuPercent = 0.0/0.0; - const char* error = ffGetCpuUsageResult(&cpuPercent); + double percentage = 0.0/0.0; + const char* error = ffGetCpuUsageResult(&percentage); if(error) { @@ -20,12 +21,23 @@ void ffPrintCPUUsage(FFinstance* instance) { ffPrintLogoAndKey(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage.key); - printf("%.2lf%%\n", cpuPercent); + FFstrbuf str; + ffStrbufInit(&str); + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffAppendPercentBar(instance, &str, (uint8_t)percentage, 0, 5, 8); + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + ffStrbufAppendF(&str, "%.2lf%%", percentage); + } + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); } else { ffPrintFormat(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage, FF_CPU_USAGE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpuPercent} + {FF_FORMAT_ARG_TYPE_DOUBLE, &percentage} }); } } diff --git a/src/modules/disk.c b/src/modules/disk.c index 0245d8a4a..159acb471 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/printing.h" #include "common/parsing.h" +#include "common/bar.h" #include "detection/disk/disk.h" #define FF_DISK_MODULE_NAME "Disk" @@ -35,14 +36,30 @@ static void printDisk(FFinstance* instance, const FFDisk* disk) if(instance->config.disk.outputFormat.length == 0) { ffPrintLogoAndKey(instance, key.chars, 0, NULL); + + FFstrbuf str; + ffStrbufInit(&str); + if(disk->bytesTotal > 0) - printf("%s / %s (%u%%)", usedPretty.chars, totalPretty.chars, bytesPercentage); + { + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(instance, &str, bytesPercentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + ffStrbufAppendF(&str, "%s / %s", usedPretty.chars, totalPretty.chars); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffStrbufAppendF(&str, " (%u%%)", bytesPercentage); + } else - fputs("unknown", stdout); + ffStrbufAppendS(&str, "Unknown"); if(disk->type == FF_DISK_TYPE_EXTERNAL) - printf(" [Removable]"); - putchar('\n'); + ffStrbufAppendS(&str, " [Removable]"); + + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); } else { diff --git a/src/modules/memory.c b/src/modules/memory.c index c3681a136..5fab1b383 100644 --- a/src/modules/memory.c +++ b/src/modules/memory.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/printing.h" #include "common/parsing.h" +#include "common/bar.h" #include "detection/memory/memory.h" #include "detection/swap/swap.h" @@ -41,7 +42,24 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr if (storage->bytesTotal == 0) puts("Disabled"); else - printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, percentage); + { + FFstrbuf str; + ffStrbufInit(&str); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + ffStrbufAppendF(&str, "%s / %s", usedPretty.chars, totalPretty.chars); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffStrbufAppendF(&str, " (%u%%)", percentage); + + ffStrbufPutTo(&str, stdout); + ffStrbufDestroy(&str); + } } else { From 0aac358e333c226ebc255f394c4285f12d16a3a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 19 Oct 2022 15:03:59 +0800 Subject: [PATCH 118/311] Init: simplify module arg parsing code --- src/common/init.c | 6 +- src/fastfetch.c | 314 ++++++++++++---------------------------------- 2 files changed, 80 insertions(+), 240 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index b2d69197c..2340afcda 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -147,9 +147,9 @@ static void initState(FFstate* state) static void initModuleArg(FFModuleArgs* args) { - ffStrbufInitA(&args->key, 0); - ffStrbufInitA(&args->outputFormat, 0); - ffStrbufInitA(&args->errorFormat, 0); + ffStrbufInit(&args->key); + ffStrbufInit(&args->outputFormat); + ffStrbufInit(&args->errorFormat); } static void defaultConfig(FFinstance* instance) diff --git a/src/fastfetch.c b/src/fastfetch.c index b64abafb8..6fc84496b 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -801,6 +801,40 @@ static void optionParseEnum(const char* argumentKey, const char* requestedKey, v exit(478); } +static bool optionParseModuleArgs(const char* argumentKey, const char* value, const char* moduleName, struct FFModuleArgs* result) +{ + const char* pkey = argumentKey; + if(!(pkey[0] == '-' && pkey[1] == '-')) + return false; + + pkey += 2; + uint32_t moduleNameLen = (uint32_t)strlen(moduleName); + if(strncasecmp(pkey, moduleName, moduleNameLen) != 0) + return false; + + pkey += moduleNameLen; + if(pkey[0] != '-') + return false; + + pkey += 1; + if(strcasecmp(pkey, "key") == 0) + { + optionParseString(argumentKey, value, &result->key); + return true; + } + else if(strcasecmp(pkey, "format") == 0) + { + optionParseString(argumentKey, value, &result->outputFormat); + return true; + } + else if(strcasecmp(pkey, "error") == 0) + { + optionParseString(argumentKey, value, &result->errorFormat); + return true; + } + return false; +} + static void parseOption(FFinstance* instance, FFdata* data, const char* key, const char* value) { /////////////////////// @@ -1017,244 +1051,50 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con ); } - //////////////////////////////// - //Format + Key + Error options// - //////////////////////////////// + /////////////////////// + //Module args options// + /////////////////////// - else if(strcasecmp(key, "--os-key") == 0) - optionParseString(key, value, &instance->config.os.key); - else if(strcasecmp(key, "--os-format") == 0) - optionParseString(key, value, &instance->config.os.outputFormat); - else if(strcasecmp(key, "--os-error") == 0) - optionParseString(key, value, &instance->config.os.errorFormat); - else if(strcasecmp(key, "--host-key") == 0) - optionParseString(key, value, &instance->config.host.key); - else if(strcasecmp(key, "--host-format") == 0) - optionParseString(key, value, &instance->config.host.outputFormat); - else if(strcasecmp(key, "--host-error") == 0) - optionParseString(key, value, &instance->config.host.errorFormat); - else if(strcasecmp(key, "--bios-key") == 0) - optionParseString(key, value, &instance->config.bios.key); - else if(strcasecmp(key, "--bios-format") == 0) - optionParseString(key, value, &instance->config.bios.outputFormat); - else if(strcasecmp(key, "--bios-error") == 0) - optionParseString(key, value, &instance->config.bios.errorFormat); - else if(strcasecmp(key, "--kernel-key") == 0) - optionParseString(key, value, &instance->config.kernel.key); - else if(strcasecmp(key, "--kernel-format") == 0) - optionParseString(key, value, &instance->config.kernel.outputFormat); - else if(strcasecmp(key, "--kernel-error") == 0) - optionParseString(key, value, &instance->config.kernel.errorFormat); - else if(strcasecmp(key, "--uptime-key") == 0) - optionParseString(key, value, &instance->config.uptime.key); - else if(strcasecmp(key, "--uptime-format") == 0) - optionParseString(key, value, &instance->config.uptime.outputFormat); - else if(strcasecmp(key, "--uptime-error") == 0) - optionParseString(key, value, &instance->config.uptime.errorFormat); - else if(strcasecmp(key, "--processes-key") == 0) - optionParseString(key, value, &instance->config.processes.key); - else if(strcasecmp(key, "--processes-format") == 0) - optionParseString(key, value, &instance->config.processes.outputFormat); - else if(strcasecmp(key, "--processes-error") == 0) - optionParseString(key, value, &instance->config.processes.errorFormat); - else if(strcasecmp(key, "--packages-key") == 0) - optionParseString(key, value, &instance->config.packages.key); - else if(strcasecmp(key, "--packages-format") == 0) - optionParseString(key, value, &instance->config.packages.outputFormat); - else if(strcasecmp(key, "--packages-error") == 0) - optionParseString(key, value, &instance->config.packages.errorFormat); - else if(strcasecmp(key, "--shell-key") == 0) - optionParseString(key, value, &instance->config.shell.key); - else if(strcasecmp(key, "--shell-format") == 0) - optionParseString(key, value, &instance->config.shell.outputFormat); - else if(strcasecmp(key, "--shell-error") == 0) - optionParseString(key, value, &instance->config.shell.errorFormat); - else if(strcasecmp(key, "--resolution-key") == 0) - optionParseString(key, value, &instance->config.resolution.key); - else if(strcasecmp(key, "--resolution-format") == 0) - optionParseString(key, value, &instance->config.resolution.outputFormat); - else if(strcasecmp(key, "--resolution-error") == 0) - optionParseString(key, value, &instance->config.resolution.errorFormat); - else if(strcasecmp(key, "--de-key") == 0) - optionParseString(key, value, &instance->config.de.key); - else if(strcasecmp(key, "--de-format") == 0) - optionParseString(key, value, &instance->config.de.outputFormat); - else if(strcasecmp(key, "--de-error") == 0) - optionParseString(key, value, &instance->config.de.errorFormat); - else if(strcasecmp(key, "--wm-key") == 0) - optionParseString(key, value, &instance->config.wm.key); - else if(strcasecmp(key, "--wm-format") == 0) - optionParseString(key, value, &instance->config.wm.outputFormat); - else if(strcasecmp(key, "--wm-error") == 0) - optionParseString(key, value, &instance->config.wm.errorFormat); - else if(strcasecmp(key, "--wm-theme-key") == 0) - optionParseString(key, value, &instance->config.wmTheme.key); - else if(strcasecmp(key, "--wm-theme-format") == 0) - optionParseString(key, value, &instance->config.wmTheme.outputFormat); - else if(strcasecmp(key, "--wm-theme-error") == 0) - optionParseString(key, value, &instance->config.wmTheme.errorFormat); - else if(strcasecmp(key, "--theme-key") == 0) - optionParseString(key, value, &instance->config.theme.key); - else if(strcasecmp(key, "--theme-format") == 0) - optionParseString(key, value, &instance->config.theme.outputFormat); - else if(strcasecmp(key, "--theme-error") == 0) - optionParseString(key, value, &instance->config.theme.errorFormat); - else if(strcasecmp(key, "--icons-key") == 0) - optionParseString(key, value, &instance->config.icons.key); - else if(strcasecmp(key, "--icons-format") == 0) - optionParseString(key, value, &instance->config.icons.outputFormat); - else if(strcasecmp(key, "--icons-error") == 0) - optionParseString(key, value, &instance->config.icons.errorFormat); - else if(strcasecmp(key, "--font-key") == 0) - optionParseString(key, value, &instance->config.font.key); - else if(strcasecmp(key, "--font-format") == 0) - optionParseString(key, value, &instance->config.font.outputFormat); - else if(strcasecmp(key, "--font-error") == 0) - optionParseString(key, value, &instance->config.font.errorFormat); - else if(strcasecmp(key, "--cursor-key") == 0) - optionParseString(key, value, &instance->config.cursor.key); - else if(strcasecmp(key, "--cursor-format") == 0) - optionParseString(key, value, &instance->config.cursor.outputFormat); - else if(strcasecmp(key, "--cursor-error") == 0) - optionParseString(key, value, &instance->config.cursor.errorFormat); - else if(strcasecmp(key, "--terminal-key") == 0) - optionParseString(key, value, &instance->config.terminal.key); - else if(strcasecmp(key, "--terminal-format") == 0) - optionParseString(key, value, &instance->config.terminal.outputFormat); - else if(strcasecmp(key, "--terminal-error") == 0) - optionParseString(key, value, &instance->config.terminal.errorFormat); - else if(strcasecmp(key, "--terminal-font-key") == 0) - optionParseString(key, value, &instance->config.terminalFont.key); - else if(strcasecmp(key, "--terminal-font-format") == 0) - optionParseString(key, value, &instance->config.terminalFont.outputFormat); - else if(strcasecmp(key, "--terminal-font-error") == 0) - optionParseString(key, value, &instance->config.terminalFont.errorFormat); - else if(strcasecmp(key, "--cpu-key") == 0) - optionParseString(key, value, &instance->config.cpu.key); - else if(strcasecmp(key, "--cpu-format") == 0) - optionParseString(key, value, &instance->config.cpu.outputFormat); - else if(strcasecmp(key, "--cpu-error") == 0) - optionParseString(key, value, &instance->config.cpu.errorFormat); - else if(strcasecmp(key, "--cpu-usage-key") == 0) - optionParseString(key, value, &instance->config.cpuUsage.key); - else if(strcasecmp(key, "--cpu-usage-format") == 0) - optionParseString(key, value, &instance->config.cpuUsage.outputFormat); - else if(strcasecmp(key, "--cpu-usage-error") == 0) - optionParseString(key, value, &instance->config.cpuUsage.errorFormat); - else if(strcasecmp(key, "--gpu-key") == 0) - optionParseString(key, value, &instance->config.gpu.key); - else if(strcasecmp(key, "--gpu-format") == 0) - optionParseString(key, value, &instance->config.gpu.outputFormat); - else if(strcasecmp(key, "--gpu-error") == 0) - optionParseString(key, value, &instance->config.gpu.errorFormat); - else if(strcasecmp(key, "--memory-key") == 0) - optionParseString(key, value, &instance->config.memory.key); - else if(strcasecmp(key, "--memory-format") == 0) - optionParseString(key, value, &instance->config.memory.outputFormat); - else if(strcasecmp(key, "--memory-error") == 0) - optionParseString(key, value, &instance->config.memory.errorFormat); - else if(strcasecmp(key, "--swap-key") == 0) - optionParseString(key, value, &instance->config.swap.key); - else if(strcasecmp(key, "--swap-format") == 0) - optionParseString(key, value, &instance->config.swap.outputFormat); - else if(strcasecmp(key, "--swap-error") == 0) - optionParseString(key, value, &instance->config.swap.errorFormat); - else if(strcasecmp(key, "--disk-key") == 0) - optionParseString(key, value, &instance->config.disk.key); - else if(strcasecmp(key, "--disk-format") == 0) - optionParseString(key, value, &instance->config.disk.outputFormat); - else if(strcasecmp(key, "--disk-error") == 0) - optionParseString(key, value, &instance->config.disk.errorFormat); - else if(strcasecmp(key, "--battery-key") == 0) - optionParseString(key, value, &instance->config.battery.key); - else if(strcasecmp(key, "--battery-format") == 0) - optionParseString(key, value, &instance->config.battery.outputFormat); - else if(strcasecmp(key, "--battery-error") == 0) - optionParseString(key, value, &instance->config.battery.errorFormat); - else if(strcasecmp(key, "--poweradapter-key") == 0) - optionParseString(key, value, &instance->config.powerAdapter.key); - else if(strcasecmp(key, "--poweradapter-format") == 0) - optionParseString(key, value, &instance->config.powerAdapter.outputFormat); - else if(strcasecmp(key, "--poweradapter-error") == 0) - optionParseString(key, value, &instance->config.powerAdapter.errorFormat); - else if(strcasecmp(key, "--locale-key") == 0) - optionParseString(key, value, &instance->config.locale.key); - else if(strcasecmp(key, "--locale-format") == 0) - optionParseString(key, value, &instance->config.locale.outputFormat); - else if(strcasecmp(key, "--locale-error") == 0) - optionParseString(key, value, &instance->config.locale.errorFormat); - else if(strcasecmp(key, "--local-ip-key") == 0) - optionParseString(key, value, &instance->config.localIP.key); - else if(strcasecmp(key, "--local-ip-format") == 0) - optionParseString(key, value, &instance->config.localIP.outputFormat); - else if(strcasecmp(key, "--local-ip-error") == 0) - optionParseString(key, value, &instance->config.localIP.errorFormat); - else if(strcasecmp(key, "--public-ip-key") == 0) - optionParseString(key, value, &instance->config.publicIP.key); - else if(strcasecmp(key, "--public-ip-format") == 0) - optionParseString(key, value, &instance->config.publicIP.outputFormat); - else if(strcasecmp(key, "--public-ip-error") == 0) - optionParseString(key, value, &instance->config.publicIP.errorFormat); - else if(strcasecmp(key, "--weather-key") == 0) - optionParseString(key, value, &instance->config.weather.key); - else if(strcasecmp(key, "--weather-format") == 0) - optionParseString(key, value, &instance->config.weather.outputFormat); - else if(strcasecmp(key, "--weather-error") == 0) - optionParseString(key, value, &instance->config.weather.errorFormat); - else if(strcasecmp(key, "--player-key") == 0) - optionParseString(key, value, &instance->config.player.key); - else if(strcasecmp(key, "--player-format") == 0) - optionParseString(key, value, &instance->config.player.outputFormat); - else if(strcasecmp(key, "--player-error") == 0) - optionParseString(key, value, &instance->config.player.errorFormat); - else if(strcasecmp(key, "--song-key") == 0 || strcasecmp(key, "--media-key") == 0) - optionParseString(key, value, &instance->config.song.key); - else if(strcasecmp(key, "--song-format") == 0 || strcasecmp(key, "--media-format") == 0) - optionParseString(key, value, &instance->config.song.outputFormat); - else if(strcasecmp(key, "--song-error") == 0 || strcasecmp(key, "--media-error") == 0) - optionParseString(key, value, &instance->config.song.errorFormat); - else if(strcasecmp(key, "--datetime-key") == 0) - optionParseString(key, value, &instance->config.dateTime.key); - else if(strcasecmp(key, "--datetime-format") == 0) - optionParseString(key, value, &instance->config.dateTime.outputFormat); - else if(strcasecmp(key, "--datetime-error") == 0) - optionParseString(key, value, &instance->config.dateTime.errorFormat); - else if(strcasecmp(key, "--date-key") == 0) - optionParseString(key, value, &instance->config.date.key); - else if(strcasecmp(key, "--date-format") == 0) - optionParseString(key, value, &instance->config.date.outputFormat); - else if(strcasecmp(key, "--date-error") == 0) - optionParseString(key, value, &instance->config.date.errorFormat); - else if(strcasecmp(key, "--time-key") == 0) - optionParseString(key, value, &instance->config.time.key); - else if(strcasecmp(key, "--time-format") == 0) - optionParseString(key, value, &instance->config.time.outputFormat); - else if(strcasecmp(key, "--time-error") == 0) - optionParseString(key, value, &instance->config.time.errorFormat); - else if(strcasecmp(key, "--vulkan-key") == 0) - optionParseString(key, value, &instance->config.vulkan.key); - else if(strcasecmp(key, "--vulkan-format") == 0) - optionParseString(key, value, &instance->config.vulkan.outputFormat); - else if(strcasecmp(key, "--vulkan-error") == 0) - optionParseString(key, value, &instance->config.vulkan.errorFormat); - else if(strcasecmp(key, "--opengl-key") == 0) - optionParseString(key, value, &instance->config.openGL.key); - else if(strcasecmp(key, "--opengl-format") == 0) - optionParseString(key, value, &instance->config.openGL.outputFormat); - else if(strcasecmp(key, "--opengl-error") == 0) - optionParseString(key, value, &instance->config.openGL.errorFormat); - else if(strcasecmp(key, "--opencl-key") == 0) - optionParseString(key, value, &instance->config.openCL.key); - else if(strcasecmp(key, "--opencl-format") == 0) - optionParseString(key, value, &instance->config.openCL.outputFormat); - else if(strcasecmp(key, "--opencl-error") == 0) - optionParseString(key, value, &instance->config.openCL.errorFormat); - else if(strcasecmp(key, "--users-key") == 0) - optionParseString(key, value, &instance->config.users.key); - else if(strcasecmp(key, "--users-format") == 0) - optionParseString(key, value, &instance->config.users.outputFormat); - else if(strcasecmp(key, "--users-error") == 0) - optionParseString(key, value, &instance->config.users.errorFormat); + else if(optionParseModuleArgs(key, value, "os", &instance->config.os)) {} + else if(optionParseModuleArgs(key, value, "host", &instance->config.host)) {} + else if(optionParseModuleArgs(key, value, "bios", &instance->config.bios)) {} + else if(optionParseModuleArgs(key, value, "board", &instance->config.board)) {} + else if(optionParseModuleArgs(key, value, "kernel", &instance->config.kernel)) {} + else if(optionParseModuleArgs(key, value, "uptime", &instance->config.uptime)) {} + else if(optionParseModuleArgs(key, value, "processes", &instance->config.processes)) {} + else if(optionParseModuleArgs(key, value, "packages", &instance->config.packages)) {} + else if(optionParseModuleArgs(key, value, "shell", &instance->config.shell)) {} + else if(optionParseModuleArgs(key, value, "resolution", &instance->config.resolution)) {} + else if(optionParseModuleArgs(key, value, "de", &instance->config.de)) {} + else if(optionParseModuleArgs(key, value, "wm", &instance->config.wm)) {} + else if(optionParseModuleArgs(key, value, "wm-theme", &instance->config.wmTheme)) {} + else if(optionParseModuleArgs(key, value, "theme", &instance->config.theme)) {} + else if(optionParseModuleArgs(key, value, "icons", &instance->config.icons)) {} + else if(optionParseModuleArgs(key, value, "font", &instance->config.font)) {} + else if(optionParseModuleArgs(key, value, "cursor", &instance->config.cursor)) {} + else if(optionParseModuleArgs(key, value, "terminal", &instance->config.terminal)) {} + else if(optionParseModuleArgs(key, value, "terminal-font", &instance->config.terminalFont)) {} + else if(optionParseModuleArgs(key, value, "cpu", &instance->config.terminal)) {} + else if(optionParseModuleArgs(key, value, "cpu-usage", &instance->config.cpuUsage)) {} + else if(optionParseModuleArgs(key, value, "gpu", &instance->config.gpu)) {} + else if(optionParseModuleArgs(key, value, "memory", &instance->config.memory)) {} + else if(optionParseModuleArgs(key, value, "swap", &instance->config.swap)) {} + else if(optionParseModuleArgs(key, value, "disk", &instance->config.disk)) {} + else if(optionParseModuleArgs(key, value, "battery", &instance->config.battery)) {} + else if(optionParseModuleArgs(key, value, "poweradapter", &instance->config.powerAdapter)) {} + else if(optionParseModuleArgs(key, value, "locale", &instance->config.locale)) {} + else if(optionParseModuleArgs(key, value, "local-ip", &instance->config.localIP)) {} + else if(optionParseModuleArgs(key, value, "public-ip", &instance->config.publicIP)) {} + else if(optionParseModuleArgs(key, value, "weather", &instance->config.weather)) {} + else if(optionParseModuleArgs(key, value, "player", &instance->config.player)) {} + else if(optionParseModuleArgs(key, value, "song", &instance->config.song)) {} + else if(optionParseModuleArgs(key, value, "datetime", &instance->config.dateTime)) {} + else if(optionParseModuleArgs(key, value, "date", &instance->config.date)) {} + else if(optionParseModuleArgs(key, value, "time", &instance->config.time)) {} + else if(optionParseModuleArgs(key, value, "vulkan", &instance->config.vulkan)) {} + else if(optionParseModuleArgs(key, value, "opengl", &instance->config.openGL)) {} + else if(optionParseModuleArgs(key, value, "opencl", &instance->config.openCL)) {} + else if(optionParseModuleArgs(key, value, "users", &instance->config.users)) {} /////////////////// //Library options// From 69b3a6871fa9e5ce3be25307a2aba86a8d76c98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 22 Oct 2022 13:02:04 +0800 Subject: [PATCH 119/311] Init: improve option parsing performance --- src/fastfetch.c | 356 +++++++++++++++++++++++------------------------- 1 file changed, 169 insertions(+), 187 deletions(-) diff --git a/src/fastfetch.c b/src/fastfetch.c index 6fc84496b..4a7cf7406 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -647,79 +647,36 @@ static void optionParseString(const char* key, const char* value, FFstrbuf* buff ffStrbufSetS(buffer, value); } +static inline bool startsWith(const char* str, const char* compareTo) +{ + return strncasecmp(str, compareTo, strlen(compareTo)) == 0; +} + static void optionParseColor(const char* key, const char* value, FFstrbuf* buffer) { optionCheckString(key, value, buffer); - static const char reset[] = "reset_"; - static const char bright[] = "bright_"; - - static const char black[] = "black"; - static const char red[] = "red"; - static const char green[] = "green"; - static const char yellow[] = "yellow"; - static const char blue[] = "blue"; - static const char magenta[] = "magenta"; - static const char cyan[] = "cyan"; - static const char white[] = "white"; - while(*value != '\0') { - if(strncasecmp(value, reset, sizeof(reset) - 1) == 0) - { - ffStrbufAppendS(buffer, "0;"); - value += sizeof(reset) - 1; - } - else if(strncasecmp(value, bright, sizeof(bright) - 1) == 0) - { - ffStrbufAppendS(buffer, "1;"); - value += sizeof(bright) - 1; - } - else if(strncasecmp(value, black, sizeof(black) - 1) == 0) - { - ffStrbufAppendS(buffer, "30"); - value += sizeof(black) - 1; - } - else if(strncasecmp(value, red, sizeof(red) - 1) == 0) - { - ffStrbufAppendS(buffer, "31"); - value += sizeof(red) - 1; - } - else if(strncasecmp(value, green, sizeof(green) - 1) == 0) - { - ffStrbufAppendS(buffer, "32"); - value += sizeof(green) - 1; - } - else if(strncasecmp(value, yellow, sizeof(yellow) - 1) == 0) - { - ffStrbufAppendS(buffer, "33"); - value += sizeof(yellow) - 1; - } - else if(strncasecmp(value, blue, sizeof(blue) - 1) == 0) - { - ffStrbufAppendS(buffer, "34"); - value += sizeof(blue) - 1; - } - else if(strncasecmp(value, magenta, sizeof(magenta) - 1) == 0) - { - ffStrbufAppendS(buffer, "35"); - value += sizeof(magenta) - 1; - } - else if(strncasecmp(value, cyan, sizeof(cyan) - 1) == 0) - { - ffStrbufAppendS(buffer, "36"); - value += sizeof(cyan) - 1; - } - else if(strncasecmp(value, white, sizeof(white) - 1) == 0) - { - ffStrbufAppendS(buffer, "37"); - value += sizeof(white) - 1; - } - else + #define FF_APPEND_COLOR_CODE_COND(prefix, code) \ + if(startsWith(value, #prefix)) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); } + + FF_APPEND_COLOR_CODE_COND(reset_, "0;") + else FF_APPEND_COLOR_CODE_COND(bright_, "1;") + else FF_APPEND_COLOR_CODE_COND(black, "30") + else FF_APPEND_COLOR_CODE_COND(red, "31") + else FF_APPEND_COLOR_CODE_COND(green, "32") + else FF_APPEND_COLOR_CODE_COND(yellow, "33") + else FF_APPEND_COLOR_CODE_COND(blue, "34") + else FF_APPEND_COLOR_CODE_COND(magenta, "35") + else FF_APPEND_COLOR_CODE_COND(cyan, "36") + else FF_APPEND_COLOR_CODE_COND(white, "37") { ffStrbufAppendC(buffer, *value); ++value; } + + #undef FF_APPEND_COLOR_CODE_COND } } @@ -856,50 +813,62 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con puts(FASTFETCH_PROJECT_VERSION); exit(0); } - else if(strcasecmp(key, "--print-config-system") == 0) + else if(startsWith(key, "--print")) { - puts(FASTFETCH_DATATEXT_CONFIG_SYSTEM); - exit(0); + const char* subkey = key + strlen("--print"); + if(strcasecmp(subkey, "-config-system") == 0) + { + puts(FASTFETCH_DATATEXT_CONFIG_SYSTEM); + exit(0); + } + else if(strcasecmp(subkey, "-config-user") == 0) + { + puts(FASTFETCH_DATATEXT_CONFIG_USER); + exit(0); + } + else if(strcasecmp(subkey, "-structure") == 0) + { + puts(FASTFETCH_DATATEXT_STRUCTURE); + exit(0); + } + else if(strcasecmp(subkey, "-logos") == 0) + { + ffLogoBuiltinPrint(instance); + exit(0); + } + else + goto error; } - else if(strcasecmp(key, "--print-config-user") == 0) + else if(startsWith(key, "--list")) { - puts(FASTFETCH_DATATEXT_CONFIG_USER); - exit(0); - } - else if(strcasecmp(key, "--print-structure") == 0) - { - puts(FASTFETCH_DATATEXT_STRUCTURE); - exit(0); - } - else if(strcasecmp(key, "--list-modules") == 0) - { - puts(FASTFETCH_DATATEXT_MODULES); - exit(0); - } - else if(strcasecmp(key, "--list-presets") == 0) - { - listAvailablePresets(instance); - exit(0); - } - else if(strcasecmp(key, "--list-features") == 0) - { - ffListFeatures(); - exit(0); - } - else if(strcasecmp(key, "--list-logos") == 0) - { - ffLogoBuiltinList(); - exit(0); - } - else if(strcasecmp(key, "--list-logos-autocompletion") == 0) - { - ffLogoBuiltinListAutocompletion(); - exit(0); - } - else if(strcasecmp(key, "--print-logos") == 0) - { - ffLogoBuiltinPrint(instance); - exit(0); + const char* subkey = key + strlen("--list"); + if(strcasecmp(subkey, "-modules") == 0) + { + puts(FASTFETCH_DATATEXT_MODULES); + exit(0); + } + else if(strcasecmp(subkey, "-presets") == 0) + { + listAvailablePresets(instance); + exit(0); + } + else if(strcasecmp(subkey, "-features") == 0) + { + ffListFeatures(); + exit(0); + } + else if(strcasecmp(subkey, "-logos") == 0) + { + ffLogoBuiltinList(); + exit(0); + } + else if(strcasecmp(subkey, "-logos-autocompletion") == 0) + { + ffLogoBuiltinListAutocompletion(); + exit(0); + } + else + goto error; } /////////////////// @@ -919,7 +888,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con } else if(strcasecmp(key, "--load-config") == 0) optionParseConfigFile(instance, data, key, value); - else if(strcasecmp(key, "--multithreading") == 0) + else if(strcasecmp(key, "--thread") == 0 || strcasecmp(key, "--multithreading") == 0) instance->config.multithreading = optionParseBoolean(value); else if(strcasecmp(key, "--allow-slow-operations") == 0) instance->config.allowSlowOperations = optionParseBoolean(value); @@ -945,49 +914,55 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.logo.paddingLeft = 0; } } - else if(strcasecmp(key, "--logo-type") == 0) + else if(startsWith(key, "--logo")) { - optionParseEnum(key, value, &instance->config.logo.type, - "auto", FF_LOGO_TYPE_AUTO, - "builtin", FF_LOGO_TYPE_BUILTIN, - "file", FF_LOGO_TYPE_FILE, - "raw", FF_LOGO_TYPE_RAW, - "sixel", FF_LOGO_TYPE_SIXEL, - "kitty", FF_LOGO_TYPE_KITTY, - "chafa", FF_LOGO_TYPE_CHAFA, - NULL - ); - } - else if(strncasecmp(key, "--logo-color-", 13) == 0 && key[13] != '\0' && key[14] == '\0') // matches "--logo-color-*" - { - //Map the number to an array index, so that '1' -> 0, '2' -> 1, etc. - int index = (int)key[13] - 49; - - //Match only --logo-color-[1-9] - if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS) + const char* subkey = key + strlen("--logo"); + if(strcasecmp(subkey, "-type") == 0) { - fprintf(stderr, "Error: invalid --color-[1-9] index: %c\n", key[13]); - exit(472); + optionParseEnum(key, value, &instance->config.logo.type, + "auto", FF_LOGO_TYPE_AUTO, + "builtin", FF_LOGO_TYPE_BUILTIN, + "file", FF_LOGO_TYPE_FILE, + "raw", FF_LOGO_TYPE_RAW, + "sixel", FF_LOGO_TYPE_SIXEL, + "kitty", FF_LOGO_TYPE_KITTY, + "chafa", FF_LOGO_TYPE_CHAFA, + NULL + ); } + else if(startsWith(subkey, "-color-") && key[13] != '\0' && key[14] == '\0') // matches "--logo-color-*" + { + //Map the number to an array index, so that '1' -> 0, '2' -> 1, etc. + int index = (int)key[13] - 49; - optionParseColor(key, value, &instance->config.logo.colors[index]); + //Match only --logo-color-[1-9] + if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS) + { + fprintf(stderr, "Error: invalid --color-[1-9] index: %c\n", key[13]); + exit(472); + } + + optionParseColor(key, value, &instance->config.logo.colors[index]); + } + else if(strcasecmp(subkey, "-width") == 0) + instance->config.logo.width = optionParseUInt32(key, value); + else if(strcasecmp(subkey, "-height") == 0) + instance->config.logo.height = optionParseUInt32(key, value); + else if(strcasecmp(subkey, "-padding") == 0) + { + uint32_t padding = optionParseUInt32(key, value); + instance->config.logo.paddingLeft = padding; + instance->config.logo.paddingRight = padding; + } + else if(strcasecmp(subkey, "-padding-left") == 0) + instance->config.logo.paddingLeft = optionParseUInt32(key, value); + else if(strcasecmp(subkey, "-padding-right") == 0) + instance->config.logo.paddingRight = optionParseUInt32(key, value); + else if(strcasecmp(subkey, "-print-remaining") == 0) + instance->config.logo.printRemaining = optionParseBoolean(value); + else + goto error; } - else if(strcasecmp(key, "--logo-width") == 0) - instance->config.logo.width = optionParseUInt32(key, value); - else if(strcasecmp(key, "--logo-height") == 0) - instance->config.logo.height = optionParseUInt32(key, value); - else if(strcasecmp(key, "--logo-padding") == 0) - { - uint32_t padding = optionParseUInt32(key, value); - instance->config.logo.paddingLeft = padding; - instance->config.logo.paddingRight = padding; - } - else if(strcasecmp(key, "--logo-padding-left") == 0) - instance->config.logo.paddingLeft = optionParseUInt32(key, value); - else if(strcasecmp(key, "--logo-padding-right") == 0) - instance->config.logo.paddingRight = optionParseUInt32(key, value); - else if(strcasecmp(key, "--logo-print-remaining") == 0) - instance->config.logo.printRemaining = optionParseBoolean(value); else if(strcasecmp(key, "--sixel") == 0) { optionParseString(key, value, &instance->config.logo.source); @@ -1100,50 +1075,56 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con //Library options// /////////////////// - else if(strcasecmp(key, "--lib-PCI") == 0) - optionParseString(key, value, &instance->config.libPCI); - else if(strcasecmp(key, "--lib-vulkan") == 0) - optionParseString(key, value, &instance->config.libVulkan); - else if(strcasecmp(key, "--lib-freetype") == 0) - optionParseString(key, value, &instance->config.libfreetype); - else if(strcasecmp(key, "--lib-wayland") == 0) - optionParseString(key, value, &instance->config.libWayland); - else if(strcasecmp(key, "--lib-xcb-randr") == 0) - optionParseString(key, value, &instance->config.libXcbRandr); - else if(strcasecmp(key, "--lib-xcb") == 0) - optionParseString(key, value, &instance->config.libXcb); - else if(strcasecmp(key, "--lib-Xrandr") == 0) - optionParseString(key, value, &instance->config.libXrandr); - else if(strcasecmp(key, "--lib-X11") == 0) - optionParseString(key, value, &instance->config.libX11); - else if(strcasecmp(key, "--lib-gio") == 0) - optionParseString(key, value, &instance->config.libGIO); - else if(strcasecmp(key, "--lib-DConf") == 0) - optionParseString(key, value, &instance->config.libDConf); - else if(strcasecmp(key, "--lib-dbus") == 0) - optionParseString(key, value, &instance->config.libDBus); - else if(strcasecmp(key, "--lib-XFConf") == 0) - optionParseString(key, value, &instance->config.libXFConf); - else if(strcasecmp(key, "--lib-sqlite") == 0 || strcasecmp(key, "--lib-sqlite3") == 0) - optionParseString(key, value, &instance->config.libSQLite3); - else if(strcasecmp(key, "--lib-rpm") == 0) - optionParseString(key, value, &instance->config.librpm); - else if(strcasecmp(key, "--lib-imagemagick") == 0) - optionParseString(key, value, &instance->config.libImageMagick); - else if(strcasecmp(key, "--lib-z") == 0) - optionParseString(key, value, &instance->config.libZ); - else if(strcasecmp(key, "--lib-chafa") == 0) - optionParseString(key, value, &instance->config.libChafa); - else if(strcasecmp(key, "--lib-egl") == 0) - optionParseString(key, value, &instance->config.libEGL); - else if(strcasecmp(key, "--lib-glx") == 0) - optionParseString(key, value, &instance->config.libGLX); - else if(strcasecmp(key, "--lib-osmesa") == 0) - optionParseString(key, value, &instance->config.libOSMesa); - else if(strcasecmp(key, "--lib-opencl") == 0) - optionParseString(key, value, &instance->config.libOpenCL); - else if(strcasecmp(key, "--lib-cjson") == 0) - optionParseString(key, value, &instance->config.libcJSON); + else if(startsWith(key, "--lib")) + { + const char* subkey = key + strlen("--lib"); + if(strcasecmp(subkey, "-PCI") == 0) + optionParseString(key, value, &instance->config.libPCI); + else if(strcasecmp(subkey, "-vulkan") == 0) + optionParseString(key, value, &instance->config.libVulkan); + else if(strcasecmp(subkey, "-freetype") == 0) + optionParseString(key, value, &instance->config.libfreetype); + else if(strcasecmp(subkey, "-wayland") == 0) + optionParseString(key, value, &instance->config.libWayland); + else if(strcasecmp(subkey, "-xcb-randr") == 0) + optionParseString(key, value, &instance->config.libXcbRandr); + else if(strcasecmp(subkey, "-xcb") == 0) + optionParseString(key, value, &instance->config.libXcb); + else if(strcasecmp(subkey, "-Xrandr") == 0) + optionParseString(key, value, &instance->config.libXrandr); + else if(strcasecmp(subkey, "-X11") == 0) + optionParseString(key, value, &instance->config.libX11); + else if(strcasecmp(subkey, "-gio") == 0) + optionParseString(key, value, &instance->config.libGIO); + else if(strcasecmp(subkey, "-DConf") == 0) + optionParseString(key, value, &instance->config.libDConf); + else if(strcasecmp(subkey, "-dbus") == 0) + optionParseString(key, value, &instance->config.libDBus); + else if(strcasecmp(subkey, "-XFConf") == 0) + optionParseString(key, value, &instance->config.libXFConf); + else if(strcasecmp(subkey, "-sqlite") == 0 || strcasecmp(subkey, "-sqlite3") == 0) + optionParseString(key, value, &instance->config.libSQLite3); + else if(strcasecmp(subkey, "-rpm") == 0) + optionParseString(key, value, &instance->config.librpm); + else if(strcasecmp(subkey, "-imagemagick") == 0) + optionParseString(key, value, &instance->config.libImageMagick); + else if(strcasecmp(subkey, "-z") == 0) + optionParseString(key, value, &instance->config.libZ); + else if(strcasecmp(subkey, "-chafa") == 0) + optionParseString(key, value, &instance->config.libChafa); + else if(strcasecmp(subkey, "-egl") == 0) + optionParseString(key, value, &instance->config.libEGL); + else if(strcasecmp(subkey, "-glx") == 0) + optionParseString(key, value, &instance->config.libGLX); + else if(strcasecmp(subkey, "-osmesa") == 0) + optionParseString(key, value, &instance->config.libOSMesa); + else if(strcasecmp(subkey, "-opencl") == 0) + optionParseString(key, value, &instance->config.libOpenCL); + else if(strcasecmp(subkey, "-cjson") == 0) + optionParseString(key, value, &instance->config.libcJSON); + else + goto error; + } ////////////////// //Module options// @@ -1206,6 +1187,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else { +error: fprintf(stderr, "Error: unknown option: %s\n", key); exit(400); } From 688a16c9410c05bb4810b62ad7df2e94b2eed027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 22 Oct 2022 13:07:38 +0800 Subject: [PATCH 120/311] Disk: fix `--disk-folder` parsing on Windows --- src/modules/disk.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/disk.c b/src/modules/disk.c index 159acb471..eb6baeb47 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -101,14 +101,20 @@ static void printMountpoint(FFinstance* instance, const FFlist* disks, const cha static void printMountpoints(FFinstance* instance, const FFlist* disks) { + #ifdef _WIN32 + const char separator = ';'; + #else + const char separator = ':'; + #endif + FFstrbuf mountpoints; ffStrbufInitCopy(&mountpoints, &instance->config.diskFolders); - ffStrbufTrim(&mountpoints, ':'); + ffStrbufTrim(&mountpoints, separator); uint32_t startIndex = 0; while(startIndex < mountpoints.length) { - uint32_t colonIndex = ffStrbufNextIndexC(&mountpoints, startIndex, ':'); + uint32_t colonIndex = ffStrbufNextIndexC(&mountpoints, startIndex, separator); mountpoints.chars[colonIndex] = '\0'; printMountpoint(instance, disks, mountpoints.chars + startIndex); From 1588f587268b0eb1e0d2d1012be1ae6b83cf76f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 22 Oct 2022 13:10:36 +0800 Subject: [PATCH 121/311] Windows: silence warnings when building with clang --- src/util/windows/wmi.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 0fec1ee64..7b27c7590 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -19,7 +19,7 @@ struct FFWmiRecord if(!pEnumerator) return; ULONG ret; - bool ok = SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &obj, &ret)) && ret; + bool ok = SUCCEEDED(pEnumerator->Next((LONG)WBEM_INFINITE, 1, &obj, &ret)) && ret; if(!ok) obj = nullptr; } FFWmiRecord(const FFWmiRecord&) = delete; From 62ab0913505400f96c35a16c596ddee10abe4bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 23 Oct 2022 10:44:42 +0800 Subject: [PATCH 122/311] Printing: improve performace of ffPrintCharTimes --- src/common/printing.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/common/printing.c b/src/common/printing.c index 148266d26..38d5f9619 100644 --- a/src/common/printing.c +++ b/src/common/printing.c @@ -129,8 +129,13 @@ void ffPrintColor(const FFstrbuf* colorValue) void ffPrintCharTimes(char c, uint32_t times) { - for(uint32_t i = 0; i < times; i++) - putchar(c); + char str[32]; + memset(str, c, sizeof(str)); //2 instructions when compiling with AVX2 enabled + for(uint32_t i = sizeof(str); i <= times; i += sizeof(str)) + fwrite(str, 1, sizeof(str), stdout); + uint32_t remaining = times % sizeof(str); + if(remaining > 0) + fwrite(str, 1, remaining, stdout); } void ffPrintUserString(const char* value) From ed85b8249a3d52e5f551099e3a553260f7a024a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 23 Oct 2022 17:54:02 +0800 Subject: [PATCH 123/311] Init: enable buffering on Windows --- src/common/init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/init.c b/src/common/init.c index 2340afcda..7f986818e 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -125,6 +125,7 @@ static void initState(FFstate* state) #ifdef WIN32 //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support setlocale(LC_ALL, ".UTF8"); + setvbuf(stdout, NULL, _IOFBF, 4096); #endif state->logoWidth = 0; From e59d64513f71e7f738a690cc15835a61b3ee6645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 23 Oct 2022 17:54:19 +0800 Subject: [PATCH 124/311] Silence warnings --- src/common/bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/bar.c b/src/common/bar.c index 4b8ae00a3..a8f7c7b62 100644 --- a/src/common/bar.c +++ b/src/common/bar.c @@ -11,7 +11,7 @@ void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, // ... // [85%, 95%) prints 9 blocks; // [95%,100%] prints 10 blocks - percent = (percent + 5) / 10; + percent = (uint8_t)(percent + 5) / 10; assert(percent <= 10); if(!instance->config.pipe) From 1395abcf0952b240b54f0643fdba5b45aedde870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 23 Oct 2022 18:42:06 +0800 Subject: [PATCH 125/311] TerminalFont: improve Windows Terminal terminal font detection on Windows --- src/detection/terminalfont/terminalfont.c | 115 ++++++++++++++++------ 1 file changed, 86 insertions(+), 29 deletions(-) diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 4d33bb78b..3cc33bd59 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -181,25 +181,73 @@ exit: return error; } -static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +#ifdef _WIN32 + #include "common/io.h" + + #include +#endif + +static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont) { //https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file FFstrbuf json; ffStrbufInit(&json); - const char* error; - error = ffProcessAppendStdOut(&json, (char* const[]) { - "cmd.exe", - "/c", - //print the file content directly, so we don't need to handle the difference of Windows and POSIX path - "if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json " - "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json ) " - "else if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json " - "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json ) " - "else if exist \"%LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json\" " - "( type %LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json ) " - "else ( call )", - NULL - }); + const char* error = NULL; + + #ifdef _WIN32 + if(terminalExe && terminalExe->length > 0) + { + char jsonPath[MAX_PATH + 1]; + if(SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, jsonPath))) + { + size_t remaining = sizeof(jsonPath) - strlen(jsonPath) - 1; + if(ffStrbufContainIgnCaseS(terminalExe, "_8wekyb3d8bbwe\\")) + { + // Microsoft Store version + if(ffStrbufContainIgnCaseS(terminalExe, ".WindowsTerminalPreview_")) + { + // Preview version + strncat(jsonPath, "\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json", remaining); + if(!ffAppendFileBuffer(jsonPath, &json)) + error = "Error reading Windows Terminal Preview settings JSON file"; + } + else + { + // Stable version + strncat(jsonPath, "\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json", remaining); + if(!ffAppendFileBuffer(jsonPath, &json)) + error = "Error reading Windows Terminal settings JSON file"; + } + } + else + { + strncat(jsonPath, "\\Microsoft\\Windows Terminal\\settings.json", remaining); + if(!ffAppendFileBuffer(jsonPath, &json)) + error = "Error reading Windows Terminal settings JSON file"; + } + } + } + #else + FF_UNUSED(terminalExe); + #endif + + if(!error && json.length == 0) + { + error = ffProcessAppendStdOut(&json, (char* const[]) { + "cmd.exe", + "/c", + //print the file content directly, so we don't need to handle the difference of Windows and POSIX path + "if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json " + "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json ) " + "else if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json " + "( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json ) " + "else if exist \"%LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json\" " + "( type %LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json ) " + "else ( call )", + NULL + }); + } + if(error) { ffStrbufAppendS(&terminalFont->error, error); @@ -234,9 +282,9 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFon #else -static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont) { - FF_UNUSED(instance, terminalFont); + FF_UNUSED(instance, terminalExe, terminalFont); ffStrbufAppendS(&terminalFont->error, "fastfetch is built without libcjson support"); } @@ -245,6 +293,26 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFon void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); +static bool detectTerminalFontCommon(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +{ + if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "alacritty") == 0) + detectAlacritty(instance, terminalFont); + else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) + detectTTY(terminalFont); + + #if defined(_WIN32) || defined(__linux__) + //Used by both Linux (WSL) and Windows + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || + ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) + detectFromWindowsTeriminal(instance, &terminalShell->terminalExe, terminalFont); + #endif + + else + return false; + + return true; +} + const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) { FF_DETECTION_INTERNAL_GUARD(FFTerminalFontResult, @@ -254,19 +322,8 @@ const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) if(terminalShell->terminalProcessName.length == 0) ffStrbufAppendS(&result.error, "Terminal font needs successfull terminal detection"); - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "alacritty") == 0) - detectAlacritty(instance, &result); - else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) - detectTTY(&result); - #if defined(_WIN32) || defined(__linux__) - //Used by both Linux (WSL) and Windows - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || - ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) - detectFromWindowsTeriminal(instance, &result); - #endif - - else + else if(detectTerminalFontCommon(instance, terminalShell, &result)) ffDetectTerminalFontPlatform(instance, terminalShell, &result); if(result.error.length == 0 && result.font.pretty.length == 0) From 883a5354412aea695a75473ffe635085ebbbe2c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 23 Oct 2022 22:16:12 +0800 Subject: [PATCH 126/311] Packages: support Chocolatey (Windows) --- src/detection/packages/packages.c | 20 +++---------- src/detection/packages/packages.h | 5 ++-- src/detection/packages/packages_windows.c | 35 +++++++++++++++++------ src/modules/packages.c | 1 + 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index 08d79e054..2404f74e3 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -1,6 +1,8 @@ #include "packages.h" #include "detection/internal.h" +#include + void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result); const FFPackagesResult* ffDetectPackages(const FFinstance* instance) @@ -11,21 +13,7 @@ const FFPackagesResult* ffDetectPackages(const FFinstance* instance) ffDetectPackagesImpl(instance, &result); - result.all = 0 - + result.pacman - + result.dpkg - + result.rpm - + result.emerge - + result.xbps - + result.nixSystem - + result.nixUser - + result.nixDefault - + result.apk - + result.pkg - + result.flatpak - + result.snap - + result.brew - + result.port - + result.scoop; + for(uint32_t i = 0; i < offsetof(FFPackagesResult, all) / sizeof(uint32_t); ++i) + result.all += ((uint32_t *)&result)[i]; ); } diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index 92bd26d63..1992b8d8d 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -7,10 +7,9 @@ typedef struct FFPackagesResult { - uint32_t all; - uint32_t apk; uint32_t brew; + uint32_t choco; uint32_t dpkg; uint32_t emerge; uint32_t flatpak; @@ -25,6 +24,8 @@ typedef struct FFPackagesResult uint32_t snap; uint32_t xbps; + uint32_t all; //Make sure this goes last + FFstrbuf pacmanBranch; } FFPackagesResult; diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 1a9fe2ade..93739e9bf 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -25,15 +25,34 @@ static uint32_t getNumElements(const char* searchPath /* including `\*` suffix * return counter; } -void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) +static void detectScoop(const FFinstance* instance, FFPackagesResult* result) +{ + char scoopPath[MAX_PATH + 3]; + strcpy(scoopPath, instance->state.passwd->pw_dir); + strncat(scoopPath, "/scoop/apps/*", sizeof(scoopPath) - 1 - strlen(scoopPath)); + result->scoop = getNumElements(scoopPath, FILE_ATTRIBUTE_DIRECTORY); + if(result->scoop > 0) + result->scoop--; // scoop +} + +static void detectChoco(const FFinstance* instance, FFPackagesResult* result) { FF_UNUSED(instance); - FFstrbuf scoopPath; - ffStrbufInitS(&scoopPath, instance->state.passwd->pw_dir); - ffStrbufAppendS(&scoopPath, "/scoop/apps/*"); - result->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); - if(result->scoop > 0) - result->scoop--; // scoop - ffStrbufDestroy(&scoopPath); + const char* chocoInstall = getenv("ChocolateyInstall"); + if(!chocoInstall || chocoInstall[0] == '\0') + return; + + char chocoPath[MAX_PATH + 3]; + strcpy(chocoPath, chocoInstall); + strncat(chocoPath, "/lib/*", sizeof(chocoPath) - 1 - strlen(chocoPath)); + result->choco = getNumElements(chocoPath, FILE_ATTRIBUTE_DIRECTORY); + if(result->choco > 0) + result->choco--; // choco +} + +void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) +{ + detectScoop(instance, result); + detectChoco(instance, result); } diff --git a/src/modules/packages.c b/src/modules/packages.c index 488334bb1..3f9d6d990 100644 --- a/src/modules/packages.c +++ b/src/modules/packages.c @@ -53,6 +53,7 @@ void ffPrintPackages(FFinstance* instance) FF_PRINT_PACKAGE(brew) FF_PRINT_PACKAGE(port) FF_PRINT_PACKAGE(scoop) + FF_PRINT_PACKAGE(choco) //Fix linter warning of unused value of all (void) all; From 42fec6e61ffaf126e946578042043c3af82d87b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 24 Oct 2022 22:20:59 +0800 Subject: [PATCH 127/311] Logo: add new Windows 11 logo Ref: https://github.com/dylanaraps/neofetch/pull/2187 --- src/logo/builtin.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index cbc16ae4b..4bdeaf4ff 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1300,6 +1300,38 @@ static const FFlogo* getLogoWindows11() { FF_LOGO_INIT 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" + "((((((((((((((((( (((((((((((((((()" + ) + FF_LOGO_COLORS( + "34" //blue + ) + FF_LOGO_COLOR_KEYS("33"); //yellow + FF_LOGO_COLOR_TITLE("36"); //cyan + FF_LOGO_RETURN +} + +static const FFlogo* getLogoWindows11Old() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("Windows 11_old") FF_LOGO_LINES( "$1\n" "################ ################\n" @@ -1354,7 +1386,7 @@ static const FFlogo* getLogoWindows8() FF_LOGO_COLORS( "36" //cyan ) - FF_LOGO_COLOR_KEYS("36"); //cyan + FF_LOGO_COLOR_KEYS("33"); //yellow FF_LOGO_COLOR_TITLE("37"); //white FF_LOGO_RETURN } @@ -2133,6 +2165,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoMintOld, getLogoMsys2, getLogoWindows11, + getLogoWindows11Old, getLogoWindows8, getLogoWindows, getLogoNixOS, From f470744e4406c3940fc35eb21b25eaac9a38da7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 25 Oct 2022 17:29:52 +0800 Subject: [PATCH 128/311] Kernel: improve performance, detect code name (Windows) --- CMakeLists.txt | 2 +- src/modules/kernel.c | 10 ++- src/util/windows/utsname.c | 114 +++++++++++++++++++++++++++++++++++ src/util/windows/utsname.cpp | 35 ----------- 4 files changed, 124 insertions(+), 37 deletions(-) create mode 100644 src/util/windows/utsname.c delete mode 100644 src/util/windows/utsname.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e348e275b..e5cdca90d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -378,7 +378,7 @@ if(WIN32) src/util/windows/wmi.cpp src/util/windows/getline.c src/util/windows/pwd.c - src/util/windows/utsname.cpp + src/util/windows/utsname.c src/detection/poweradapter/poweradapter_nosupport.c src/detection/media/media_nosupport.c diff --git a/src/modules/kernel.c b/src/modules/kernel.c index 062b04f42..72096ce55 100644 --- a/src/modules/kernel.c +++ b/src/modules/kernel.c @@ -9,7 +9,15 @@ void ffPrintKernel(FFinstance* instance) if(instance->config.kernel.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel.key); - puts(instance->state.utsname.release); + + #ifdef _WIN32 + if(instance->state.utsname.version[0] != '\0') + printf("%s (%s)\n", instance->state.utsname.release, instance->state.utsname.version); + else + puts(instance->state.utsname.release); + #else + puts(instance->state.utsname.release); + #endif } else { diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c new file mode 100644 index 000000000..07f6e52e8 --- /dev/null +++ b/src/util/windows/utsname.c @@ -0,0 +1,114 @@ +#include "fastfetch.h" +#include "utsname.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +static int detectSysname(struct utsname *name) +{ + strncpy(name->sysname, "Windows_NT", UTSNAME_MAXLENGTH); + return 0; +} + +static int detectNodename(struct utsname *name) +{ + DWORD bufSize = UTSNAME_MAXLENGTH - 1; + if(!GetComputerNameA(name->nodename, &bufSize)) + return 1; + name->nodename[bufSize] = '\0'; + return 0; +} + +static int detectVersion(struct utsname *name) +{ + HKEY hKey; + if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) + return 1; + + 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; + } + + DWORD currentMinorVersionNumber; + bufSize = sizeof(currentMinorVersionNumber); + if(RegGetValueA(hKey, NULL, "CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMinorVersionNumber, &bufSize) != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return 1; + } + + char currentBuildNumber[32]; + bufSize = sizeof(currentBuildNumber); + if(RegGetValueA(hKey, NULL, "CurrentBuildNumber", RRF_RT_REG_SZ, NULL, currentBuildNumber, &bufSize) != ERROR_SUCCESS) + strcpy(currentBuildNumber, "0"); + + DWORD ubr; + bufSize = sizeof(ubr); + 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); + + bufSize = sizeof(name->version); + RegGetValueA(hKey, NULL, "DisplayVersion", RRF_RT_REG_SZ, NULL, name->version, &bufSize); + + RegCloseKey(hKey); + return 0; +} + +static int detectMachine(struct utsname *name) +{ + // Get hardware info + SYSTEM_INFO sysInfo = {0}; + GetNativeSystemInfo(&sysInfo); + + // Set processor architecture + switch(sysInfo.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64: + strcpy(name->machine, "x86_64"); + break; + case PROCESSOR_ARCHITECTURE_IA64: + strcpy(name->machine, "ia64"); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + strcpy(name->machine, "x86"); + break; + case PROCESSOR_ARCHITECTURE_ARM64: + strcpy(name->machine, "aarch64"); + break; + case PROCESSOR_ARCHITECTURE_ARM: + strcpy(name->machine, "arm"); + break; + case PROCESSOR_ARCHITECTURE_PPC: + strcpy(name->machine, "ppc"); + break; + case PROCESSOR_ARCHITECTURE_MIPS: + strcpy(name->machine, "mips"); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN: + default: + strcpy(name->machine, "unknown"); + break; + } + + return 0; +} + +int uname(struct utsname *name) +{ + memset(name, 0, sizeof(*name)); + + int sysnameResult = detectSysname(name); + int nodenameResult = detectNodename(name); + int versionResult = detectVersion(name); + int machineResult = detectMachine(name); + + return sysnameResult || nodenameResult || versionResult || machineResult; +} diff --git a/src/util/windows/utsname.cpp b/src/util/windows/utsname.cpp deleted file mode 100644 index 10c0f7b68..000000000 --- a/src/util/windows/utsname.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "util/windows/wmi.hpp" -extern "C" { - #include "utsname.h" -} - -int uname(struct utsname *name) -{ - memset(name, 0, sizeof(*name)); - - strncpy(name->sysname, "Windows_NT", UTSNAME_MAXLENGTH); - - FFWmiQuery query(L"SELECT Version, CSName, OSArchitecture FROM Win32_OperatingSystem"); - if(!query) - return -1; - - if(FFWmiRecord record = query.next()) - { - FFstrbuf value; - ffStrbufInit(&value); - record.getString(L"Version", &value); - strncpy(name->release, value.chars, UTSNAME_MAXLENGTH); - - ffStrbufClear(&value); - record.getString(L"CSName", &value); - strncpy(name->nodename, value.chars, UTSNAME_MAXLENGTH); - - ffStrbufClear(&value); - record.getString(L"OSArchitecture", &value); - strncpy(name->machine, value.chars, UTSNAME_MAXLENGTH); - - ffStrbufDestroy(&value); - } - - return 0; -} From e225b496b1b856811ab3ed42f51209a2a798f231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 25 Oct 2022 17:51:17 +0800 Subject: [PATCH 129/311] Disk: don't print hidden removable volumes (macOS) --- src/detection/disk/disk_apple.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index a267d1177..42c2e6a26 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -35,12 +35,12 @@ void ffDetectDisksImpl(FFDiskResult* disks) NSError* error; NSNumber* isBrowsable; - if(removable) - disk->type = FF_DISK_TYPE_EXTERNAL; - else if([url getResourceValue:&isBrowsable forKey:NSURLVolumeIsBrowsableKey error:&error] == YES && isBrowsable.boolValue) - disk->type = FF_DISK_TYPE_REGULAR; - else + if([url getResourceValue:&isBrowsable forKey:NSURLVolumeIsBrowsableKey error:&error] == YES && !isBrowsable.boolValue) disk->type = FF_DISK_TYPE_HIDDEN; + else if(removable) + disk->type = FF_DISK_TYPE_EXTERNAL; + else + disk->type = FF_DISK_TYPE_REGULAR; NSString* volumeName; if([url getResourceValue:&volumeName forKey:NSURLVolumeNameKey error:&error] == YES) From 470d160346671966a5b869f214b1d4c6ef015505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 26 Oct 2022 17:03:46 +0800 Subject: [PATCH 130/311] Uptime: support freebsd --- CMakeLists.txt | 4 ++-- src/detection/uptime/{uptime_apple.c => uptime_bsd.c} | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) rename src/detection/uptime/{uptime_apple.c => uptime_bsd.c} (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e5cdca90d..24830728a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,6 +302,7 @@ endif() if(BSD OR APPLE) list(APPEND LIBFASTFETCH_SRC src/common/sysctl.c + src/detection/uptime/uptime_bsd.c ) endif() @@ -310,6 +311,7 @@ if(LINUX OR ANDROID) src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c src/detection/swap/swap_linux.c + src/detection/uptime/uptime_linux.c ) endif() @@ -320,7 +322,6 @@ if(LINUX OR ANDROID OR BSD) src/detection/temps/temps_linux.c src/detection/opengl/opengl_linux.c src/detection/processes/processes_linux.c - src/detection/uptime/uptime_linux.c src/detection/packages/packages_linux.c src/detection/poweradapter/poweradapter_nosupport.c @@ -407,7 +408,6 @@ if(APPLE) src/detection/font/font_apple.m src/detection/opengl/opengl_apple.c src/detection/processes/processes_apple.c - src/detection/uptime/uptime_apple.c src/detection/packages/packages_apple.c src/detection/bios/bios_nosupport.c diff --git a/src/detection/uptime/uptime_apple.c b/src/detection/uptime/uptime_bsd.c similarity index 95% rename from src/detection/uptime/uptime_apple.c rename to src/detection/uptime/uptime_bsd.c index c32496ef3..e21eb4183 100644 --- a/src/detection/uptime/uptime_apple.c +++ b/src/detection/uptime/uptime_bsd.c @@ -2,6 +2,7 @@ #include #include +#include uint64_t ffDetectUptime(const FFinstance* instance) { From aca2c01c9e261eb54ac8de250694b4024cbc103c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 26 Oct 2022 17:20:39 +0800 Subject: [PATCH 131/311] Processes: support freebsd --- CMakeLists.txt | 4 ++-- .../processes/{processes_apple.c => processes_bsd.c} | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) rename src/detection/processes/{processes_apple.c => processes_bsd.c} (85%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24830728a..d59a68ecf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -303,6 +303,7 @@ if(BSD OR APPLE) list(APPEND LIBFASTFETCH_SRC src/common/sysctl.c src/detection/uptime/uptime_bsd.c + src/detection/processes/processes_bsd.c ) endif() @@ -310,6 +311,7 @@ if(LINUX OR ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c + src/detection/processes/processes_linux.c src/detection/swap/swap_linux.c src/detection/uptime/uptime_linux.c ) @@ -321,7 +323,6 @@ if(LINUX OR ANDROID OR BSD) src/detection/disk/disk_linux.c src/detection/temps/temps_linux.c src/detection/opengl/opengl_linux.c - src/detection/processes/processes_linux.c src/detection/packages/packages_linux.c src/detection/poweradapter/poweradapter_nosupport.c @@ -407,7 +408,6 @@ if(APPLE) src/detection/temps/temps_apple.c src/detection/font/font_apple.m src/detection/opengl/opengl_apple.c - src/detection/processes/processes_apple.c src/detection/packages/packages_apple.c src/detection/bios/bios_nosupport.c diff --git a/src/detection/processes/processes_apple.c b/src/detection/processes/processes_bsd.c similarity index 85% rename from src/detection/processes/processes_apple.c rename to src/detection/processes/processes_bsd.c index bbed0db2d..a09b05a96 100644 --- a/src/detection/processes/processes_apple.c +++ b/src/detection/processes/processes_bsd.c @@ -1,6 +1,10 @@ #include "processes.h" #include +#ifdef __FreeBSD__ + #include + #include +#endif uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) { From 64b9f69fb147f093c8b37b17ce8597f92abbc1cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 26 Oct 2022 17:29:53 +0800 Subject: [PATCH 132/311] Swap: support freebsd --- src/detection/swap/swap_bsd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/detection/swap/swap_bsd.c b/src/detection/swap/swap_bsd.c index 8af98a16f..8e8089600 100644 --- a/src/detection/swap/swap_bsd.c +++ b/src/detection/swap/swap_bsd.c @@ -1,6 +1,8 @@ #include "swap.h" +#include "common/sysctl.h" void ffDetectSwapImpl(FFMemoryStorage* swap) { - ffStrbufAppendS(&swap->error, "Not implemented"); + swap->bytesTotal = (uint64_t)ffSysctlGetInt64("vm.swap_total", 0); + swap->bytesUsed = (uint64_t)ffSysctlGetInt64("vm.swap_reserved", 0); } From 9c73f6b7879d7b0c4bca7bb3093f47255af9918e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 26 Oct 2022 19:49:25 +0800 Subject: [PATCH 133/311] TerminalShell: support freebsd --- .../terminalshell/terminalshell_linux.c | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index e04f41f66..5040cede5 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -13,6 +13,10 @@ #ifdef __APPLE__ #include +#elif defined(__FreeBSD__) + #include + #include + #include #endif static void setExeName(FFstrbuf* exe, const char** exeName) @@ -47,7 +51,13 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex #else - //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) + size_t size = exe->allocated; + if(!sysctl( + (int[]){CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid}, 4, + exe->chars, &size, + NULL, 0 + )) + exe->length = (uint32_t)size; #endif @@ -92,8 +102,19 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid) #else - //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) - error = "unimplemented"; + struct kinfo_proc proc; + size_t size = sizeof(proc); + if(sysctl( + (int[]){CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}, 4, + &proc, &size, + NULL, 0 + )) + error = "sysctl(KERN_PROC_PID) failed"; + else + { + *ppid = (pid_t)proc.ki_ppid; + strncpy(name, proc.ki_comm, COMMLEN); + } #endif From f93bd9e28ba267dcaa819cba97a3bd5067346e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 26 Oct 2022 19:59:15 +0800 Subject: [PATCH 134/311] TerminalFont: fix platform font detection my bad... --- src/detection/terminalfont/terminalfont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 3cc33bd59..b673ff4fd 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -323,7 +323,7 @@ const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) if(terminalShell->terminalProcessName.length == 0) ffStrbufAppendS(&result.error, "Terminal font needs successfull terminal detection"); - else if(detectTerminalFontCommon(instance, terminalShell, &result)) + else if(!detectTerminalFontCommon(instance, terminalShell, &result)) ffDetectTerminalFontPlatform(instance, terminalShell, &result); if(result.error.length == 0 && result.font.pretty.length == 0) From 60ad6792ba88ae6158647373530e3a2cce2b487c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 10:08:22 +0800 Subject: [PATCH 135/311] CpuUsage: support freebsd --- CMakeLists.txt | 3 ++- src/detection/cpuUsage/cpuUsage_bsd.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/detection/cpuUsage/cpuUsage_bsd.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d59a68ecf..86a271a70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,6 +310,7 @@ endif() if(LINUX OR ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c + src/detection/cpuUsage/cpuUsage_linux.c src/detection/memory/memory_linux.c src/detection/processes/processes_linux.c src/detection/swap/swap_linux.c @@ -319,7 +320,6 @@ endif() if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC - src/detection/cpuUsage/cpuUsage_linux.c src/detection/disk/disk_linux.c src/detection/temps/temps_linux.c src/detection/opengl/opengl_linux.c @@ -418,6 +418,7 @@ endif() if(BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_bsd.c + src/detection/cpuUsage/cpuUsage_bsd.c src/detection/memory/memory_bsd.c src/detection/swap/swap_bsd.c ) diff --git a/src/detection/cpuUsage/cpuUsage_bsd.c b/src/detection/cpuUsage/cpuUsage_bsd.c new file mode 100644 index 000000000..d96064fd4 --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage_bsd.c @@ -0,0 +1,19 @@ +#include "cpuUsage.h" + +#include +#include +#include + +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) +{ + // interrupt processing, user processes, system processing, lock spinning, and idling + uint64_t cpTime[5]; + size_t neededLength = sizeof(cpTime); + if(sysctlbyname("kern.cp_time", cpTime, &neededLength, NULL, 0) != 0) + return "sysctlbyname(kern.cp_time) failed"; + + *inUseAll = cpTime[0] + cpTime[1] + cpTime[2] + cpTime[3]; + *totalAll = *inUseAll + cpTime[4]; + + return NULL; +} From 3ee15d04010f507a495535d258c644fd9c5282a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 10:10:00 +0800 Subject: [PATCH 136/311] CpuUsage: add to presets/all --- presets/all | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/presets/all b/presets/all index a1706f3b1..f68223bb8 100644 --- a/presets/all +++ b/presets/all @@ -1 +1 @@ ---structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors +--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors From 895d151e2eb8cc975ab11f6a545d93749cca26d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 10:46:33 +0800 Subject: [PATCH 137/311] Host: support freebsd --- CMakeLists.txt | 18 ++++++++++++++---- src/common/sysctl.c | 6 ++++-- src/common/sysctl.h | 10 ++++++---- src/detection/host/host_bsd.c | 19 +++++++++++++++++++ 4 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 src/detection/host/host_bsd.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 86a271a70..850a72a63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,12 +331,8 @@ endif() if(LINUX OR BSD) list(APPEND LIBFASTFETCH_SRC - src/detection/host/host_linux.c - src/detection/bios/bios_linux.c - src/detection/board/board_linux.c src/detection/os/os_linux.c src/detection/gpu/gpu_linux.c - src/detection/battery/battery_linux.c src/detection/displayserver/linux/displayserver_linux.c src/detection/displayserver/linux/wayland.c src/detection/displayserver/linux/xcb.c @@ -351,6 +347,15 @@ if(LINUX OR BSD) ) endif() +if(LINUX) + list(APPEND LIBFASTFETCH_SRC + src/detection/host/host_linux.c + src/detection/bios/bios_linux.c + src/detection/board/board_linux.c + src/detection/battery/battery_linux.c + ) +endif() + if(WIN32) list(APPEND LIBFASTFETCH_SRC src/common/processing_windows.c @@ -421,6 +426,11 @@ if(BSD) src/detection/cpuUsage/cpuUsage_bsd.c src/detection/memory/memory_bsd.c src/detection/swap/swap_bsd.c + src/detection/host/host_bsd.c + + src/detection/battery/battery_nosupport.c + src/detection/bios/bios_nosupport.c + src/detection/board/board_nosupport.c ) endif() diff --git a/src/common/sysctl.c b/src/common/sysctl.c index 30e92383a..4f0f3b65c 100644 --- a/src/common/sysctl.c +++ b/src/common/sysctl.c @@ -2,11 +2,11 @@ #include -void ffSysctlGetString(const char* propName, FFstrbuf* result) +const char* ffSysctlGetString(const char* propName, FFstrbuf* result) { size_t neededLength; if(sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator - return; + return "sysctlbyname() failed"; ffStrbufEnsureFree(result, (uint32_t) neededLength - 1); @@ -14,6 +14,8 @@ void ffSysctlGetString(const char* propName, FFstrbuf* result) result->length += (uint32_t) neededLength - 1; result->chars[result->length] = '\0'; + + return NULL; } int ffSysctlGetInt(const char* propName, int defaultValue) diff --git a/src/common/sysctl.h b/src/common/sysctl.h index 91e4ad8b6..562e625d5 100644 --- a/src/common/sysctl.h +++ b/src/common/sysctl.h @@ -4,12 +4,14 @@ #define FF_INCLUDED_common_sysctl #include "fastfetch.h" +#include "util/FFcheckmacros.h" + #include #include -void ffSysctlGetString(const char* propName, FFstrbuf* result); -int ffSysctlGetInt(const char* propName, int defaultValue); -int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue); -void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength); +const char* ffSysctlGetString(const char* propName, FFstrbuf* result); +FF_C_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue); +FF_C_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue); +FF_C_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength); #endif diff --git a/src/detection/host/host_bsd.c b/src/detection/host/host_bsd.c new file mode 100644 index 000000000..13a43acda --- /dev/null +++ b/src/detection/host/host_bsd.c @@ -0,0 +1,19 @@ +#include "host.h" +#include "common/sysctl.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); + + ffStrbufAppendS(&host->error, ffSysctlGetString("hw.fdt.model", &host->productName)); +} From 9ad7ba714427c0b63b650ba49365f8783a47e533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 11:06:43 +0800 Subject: [PATCH 138/311] CpuTemp: support freebsd Untested --- src/detection/cpu/cpu_bsd.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 46f60b4e6..6f71f1ef6 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -5,7 +5,17 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) { FF_UNUSED(instance); - cpu->temperature = FF_CPU_TEMP_UNSET; + if (instance->config.cpuTemp) + { + FFstrbuf cpuTemp; + ffStrbufInit(&cpuTemp); + if(ffSysctlGetString("temperature", &cpuTemp)) + cpu->temperature = FF_CPU_TEMP_UNSET; + else + cpu->temperature = ffStrbufToDouble(&cpuTemp); + } + else + cpu->temperature = FF_CPU_TEMP_UNSET; if(cached) return; From 5472621ac0f4cb5296ef7acfb8443827c659215d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 14:58:29 +0800 Subject: [PATCH 139/311] Disk: support freebsd Also rewrite macOS detection to share code with bsd --- CMakeLists.txt | 3 +- src/detection/disk/disk_apple.m | 64 ++++++--------------------------- src/detection/disk/disk_bsd.c | 56 +++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 55 deletions(-) create mode 100644 src/detection/disk/disk_bsd.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 850a72a63..79e059926 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,6 +302,7 @@ endif() if(BSD OR APPLE) list(APPEND LIBFASTFETCH_SRC src/common/sysctl.c + src/detection/disk/disk_bsd.c src/detection/uptime/uptime_bsd.c src/detection/processes/processes_bsd.c ) @@ -311,6 +312,7 @@ if(LINUX OR ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c src/detection/cpuUsage/cpuUsage_linux.c + src/detection/disk/disk_linux.c src/detection/memory/memory_linux.c src/detection/processes/processes_linux.c src/detection/swap/swap_linux.c @@ -320,7 +322,6 @@ endif() if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC - src/detection/disk/disk_linux.c src/detection/temps/temps_linux.c src/detection/opengl/opengl_linux.c src/detection/packages/packages_linux.c diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m index 42c2e6a26..b2f7cec08 100644 --- a/src/detection/disk/disk_apple.m +++ b/src/detection/disk/disk_apple.m @@ -1,61 +1,17 @@ #include "disk.h" -#include +#include #import -#import -void ffDetectDisksImpl(FFDiskResult* disks) +void detectFsInfo(struct statfs* fs, FFDisk* disk) { - NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil]; - NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys options:0]; + // FreeBSD doesn't support these flags + if(fs->f_flags & MNT_DONTBROWSE) + disk->type = FF_DISK_TYPE_HIDDEN; + else if(fs->f_flags & MNT_REMOVABLE) + disk->type = FF_DISK_TYPE_EXTERNAL; + else + disk->type = FF_DISK_TYPE_REGULAR; - if(urls == nil) - { - ffStrbufAppendS(&disks->error, "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed"); - return; - } - - for (NSURL *url in urls) - { - FFDisk* disk = ffListAdd(&disks->disks); - - ffStrbufInitS(&disk->mountpoint, [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]); - - NSString* filesystem; - BOOL removable; - [NSWorkspace.sharedWorkspace getFileSystemInfoForPath:url.relativePath - isRemovable:&removable - isWritable:nil - isUnmountable:nil - description:nil - type:&filesystem - ]; - ffStrbufInitS(&disk->filesystem, [filesystem cStringUsingEncoding:NSUTF8StringEncoding]); - - NSError* error; - - NSNumber* isBrowsable; - if([url getResourceValue:&isBrowsable forKey:NSURLVolumeIsBrowsableKey error:&error] == YES && !isBrowsable.boolValue) - disk->type = FF_DISK_TYPE_HIDDEN; - else if(removable) - disk->type = FF_DISK_TYPE_EXTERNAL; - else - disk->type = FF_DISK_TYPE_REGULAR; - - NSString* volumeName; - if([url getResourceValue:&volumeName forKey:NSURLVolumeNameKey error:&error] == YES) - ffStrbufInitS(&disk->name, [volumeName cStringUsingEncoding:NSUTF8StringEncoding]); - else - ffStrbufInit(&disk->name); - - 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 - - disk->bytesTotal = fs.f_blocks * fs.f_frsize; - disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize); - - disk->filesTotal = (uint32_t) fs.f_files; - disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); - } + ffStrbufInitS(&disk->name, [NSFileManager.defaultManager displayNameAtPath:@(fs->f_mntonname)].UTF8String); } diff --git a/src/detection/disk/disk_bsd.c b/src/detection/disk/disk_bsd.c new file mode 100644 index 000000000..0e14ef3f2 --- /dev/null +++ b/src/detection/disk/disk_bsd.c @@ -0,0 +1,56 @@ +#include "disk.h" + +#include + +#ifdef __FreeBSD__ +static void detectFsInfo(struct statfs* fs, FFDisk* disk) +{ + if( + ffStrbufStartsWithS(&disk->mountpoint, "/boot") || + ffStrbufStartsWithS(&disk->mountpoint, "/dev") || + ffStrbufStartsWithS(&disk->mountpoint, "/var") || + ffStrbufStartsWithS(&disk->mountpoint, "/tmp") || + ffStrbufStartsWithS(&disk->mountpoint, "/proc") || + ffStrbufStartsWithS(&disk->mountpoint, "/zroot") + ) + disk->type = FF_DISK_TYPE_HIDDEN; + else if((fs->f_flags & MNT_NOSUID) || !(fs->f_flags & MNT_LOCAL)) + disk->type = FF_DISK_TYPE_EXTERNAL; + else + disk->type = FF_DISK_TYPE_REGULAR; + + ffStrbufInit(&disk->name); +} +#else +void detectFsInfo(struct statfs* fs, FFDisk* disk); +#endif + +void ffDetectDisksImpl(FFDiskResult* disks) +{ + struct statfs* buf; + + int size = getmntinfo(&buf, MNT_WAIT); + if(size <= 0) + ffStrbufAppendS(&disks->error, "getmntinfo() failed"); + + for(struct statfs* fs = buf; fs < buf + size; ++fs) + { + FFDisk* disk = ffListAdd(&disks->disks); + + #ifdef __FreeBSD__ + // f_bavail and f_ffree are signed on FreeBSD... + if(fs->f_bavail < 0) fs->f_bavail = 0; + if(fs->f_ffree < 0) fs->f_ffree = 0; + #endif + + disk->bytesTotal = fs->f_blocks * fs->f_bsize; + disk->bytesUsed = disk->bytesTotal - ((uint64_t)fs->f_bavail * fs->f_bsize); + + disk->filesTotal = (uint32_t) fs->f_files; + disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree); + + ffStrbufInitS(&disk->mountpoint, fs->f_mntonname); + ffStrbufInitS(&disk->filesystem, fs->f_fstypename); + detectFsInfo(fs, disk); + } +} From 2a1330dea3a1ec34ee69598a56f504705373fdf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 15:12:50 +0800 Subject: [PATCH 140/311] README: clearify we support FreeBSD only, not OpenBSD or NetBSD --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index df0d96a52..845a64a64 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, BSD, 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 are supported. @@ -26,7 +26,7 @@ Fastfetch dynamically loads needed libraries if they are available. On Linux, it The following libraries are used if present at runtime: -### Linux and BSD +### Linux and FreeBSD * [`libpci`](https://github.com/pciutils/pciutils): GPU output. * [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output. @@ -48,7 +48,7 @@ The following libraries are used if present at runtime: * [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font. * [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count. * [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE. -* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( Windows, WSL ). +* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( WSL ). ### macOS From 302a58881237f142bd4e1295e30f3a5008ad836a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 16:29:52 +0800 Subject: [PATCH 141/311] TerminalShell: fix shellExe detection on macOS `proc_pidpath()` works only if bufsize >= PROC_PIDPATHINFO_MAXSIZE --- src/detection/terminalshell/terminalshell_linux.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 5040cede5..79e383bd4 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -313,13 +313,21 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) } init = true; + #ifdef __APPLE__ + const uint32_t exePathLen = PROC_PIDPATHINFO_MAXSIZE; + #elif defined(MAXPATH) + const uint32_t exePathLen = MAXPATH; + #else + const uint32_t exePathLen = 260; + #endif + ffStrbufInit(&result.shellProcessName); - ffStrbufInitA(&result.shellExe, 128); + ffStrbufInitA(&result.shellExe, exePathLen); result.shellExeName = result.shellExe.chars; ffStrbufInit(&result.shellVersion); ffStrbufInit(&result.terminalProcessName); - ffStrbufInitA(&result.terminalExe, 128); + ffStrbufInitA(&result.terminalExe, exePathLen); result.terminalExeName = result.terminalExe.chars; ffStrbufInit(&result.userShellExe); From 2ee5b3b7a505e17b1d2ff6193c1c0ca8ba8ef761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 16:30:49 +0800 Subject: [PATCH 142/311] TerminalShell: add support for tcsh which is the default shell for freebsd --- src/detection/terminalshell/terminalshell.c | 13 +++++++++++++ src/detection/terminalshell/terminalshell_linux.c | 12 +++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index f4141a6b2..a99c498e4 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -71,6 +71,17 @@ static void getShellVersionFish(FFstrbuf* exe, FFstrbuf* version) ffStrbufSubstrAfterLastC(version, ' '); } +static void getShellVersionTcsh(FFstrbuf* exe, FFstrbuf* version) +{ + ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "--version", + NULL + }); // tcsh 6.24.01 (Astron) 2022-05-12 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec + ffStrbufSubstrAfterFirstC(version, ' '); // 6.24.01 (Astron) 2022-05-12 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec + ffStrbufSubstrBeforeFirstC(version, ' '); // 6.24.01 +} + static void getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version) { #ifdef _WIN32 @@ -128,6 +139,8 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) getShellVersionFish(exe, version); else if(strcasecmp(exeName, "pwsh") == 0) getShellVersionPwsh(exe, version); + else if(strcasecmp(exeName, "csh") == 0 || strcasecmp(exeName, "tcsh") == 0) + getShellVersionTcsh(exe, version); else if(strcasecmp(exeName, "nu") == 0) getShellVersionNu(exe, version); diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 79e383bd4..57867fdb6 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -153,6 +153,8 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) strcasecmp(name, "sh") == 0 || strcasecmp(name, "zsh") == 0 || strcasecmp(name, "ksh") == 0 || + strcasecmp(name, "csh") == 0 || + strcasecmp(name, "tcsh") == 0 || strcasecmp(name, "fish") == 0 || strcasecmp(name, "dash") == 0 || strcasecmp(name, "pwsh") == 0 || @@ -251,11 +253,15 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) } } -static void getUserShellFromEnv(FFTerminalShellResult* result) +static void getUserShellFromEnv(const FFinstance* instance, FFTerminalShellResult* result) { - ffStrbufAppendS(&result->userShellExe, getenv("SHELL")); + if(instance->state.passwd->pw_shell[0] != '\0') + ffStrbufAppendS(&result->userShellExe, instance->state.passwd->pw_shell); + else + ffStrbufAppendS(&result->userShellExe, getenv("SHELL")); if(result->userShellExe.length == 0) return; + setExeName(&result->userShellExe, &result->userShellExeName); //If shell detection via processes failed @@ -337,7 +343,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) getTerminalShell(&result, getppid()); getTerminalFromEnv(&result); - getUserShellFromEnv(&result); + getUserShellFromEnv(instance, &result); getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion); if(strcasecmp(result.shellExeName, result.userShellExeName) != 0) From 8b43605abf5a9cb75c26abe41495c619ec3690c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 17:03:53 +0800 Subject: [PATCH 143/311] README: document Chocolatey support --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 845a64a64..52f99c321 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal ##### Package managers ``` -Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop +Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop, Chocolatey ``` ##### WM themes From 5d306ed9f310f445777d98b1194dafeecc93679b Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 27 Oct 2022 13:23:24 +0200 Subject: [PATCH 144/311] Don't print vulkan driver info, if it contains new lines #316 --- src/detection/vulkan.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 9c348b74b..685de47b8 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -24,7 +24,11 @@ static void applyDriverName(VkPhysicalDeviceDriverProperties* properties, FFstrb ffStrbufAppendS(result, properties->driverName); - if(!ffStrSet(properties->driverInfo)) + /* + * Some drivers (android for example) expose a multiline string as driver info. + * It contains too much info anyways, so we just don't append it. + */ + if(!ffStrSet(properties->driverInfo) || strchr(properties->driverInfo, '\n') != NULL) return; ffStrbufAppendS(result, " ["); From 4634606a36771afc1e4cfcb0604f99f8b37ee9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 22:31:57 +0800 Subject: [PATCH 145/311] CpuUsage: clearify the restriction on Android --- src/detection/cpuUsage/cpuUsage_linux.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/detection/cpuUsage/cpuUsage_linux.c b/src/detection/cpuUsage/cpuUsage_linux.c index 8667fd526..1888b2b13 100644 --- a/src/detection/cpuUsage/cpuUsage_linux.c +++ b/src/detection/cpuUsage/cpuUsage_linux.c @@ -10,7 +10,13 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) FILE* procStat = fopen("/proc/stat", "r"); if(procStat == NULL) + { + #ifdef __ANDROID__ + return "Accessing \"/proc/stat\" is restricted on Android O+"; + #else return "fopen(\"""/proc/stat\", \"r\") == NULL"; + #endif + } if (fscanf(procStat, "cpu%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) { From de964d3e775b1563864912e8b34b67b5fbb8aabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 27 Oct 2022 22:48:23 +0800 Subject: [PATCH 146/311] Disk: only prints useful mount points on Android fix #322 --- src/detection/disk/disk_linux.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 2ff4395a9..5a9e7713f 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -55,12 +55,21 @@ void ffDetectDisksImpl(FFDiskResult* disks) while(isspace(*currentPos)) ++currentPos; + #ifdef __ANDROID__ + if(ffStrbufEqualS(&disk->mountpoint, "/") || ffStrbufEqualS(&disk->mountpoint, "/storage/emulated")) + disk->type = FF_DISK_TYPE_REGULAR; + else if(ffStrbufStartsWithS(&disk->mountpoint, "/mnt/media_rw/")) + disk->type = FF_DISK_TYPE_EXTERNAL; + else + disk->type = FF_DISK_TYPE_HIDDEN; + #else if(strstr(currentPos, "nosuid") != NULL || strstr(currentPos, "nodev") != NULL) disk->type = FF_DISK_TYPE_EXTERNAL; else if(ffStrbufStartsWithS(&disk->mountpoint, "/boot") || ffStrbufStartsWithS(&disk->mountpoint, "/efi")) disk->type = FF_DISK_TYPE_HIDDEN; else disk->type = FF_DISK_TYPE_REGULAR; + #endif //Detects stats struct statvfs fs; From b8f14c964afd584cf6e7adeb6fa77fe4a0d30375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 28 Oct 2022 01:02:00 +0800 Subject: [PATCH 147/311] Disk: detect Windows volumes on WSL --- src/detection/disk/disk_linux.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 5a9e7713f..93dee0f7d 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -20,8 +20,9 @@ void ffDetectDisksImpl(FFDiskResult* disks) //Format of the file: " ..." (Same as fstab) char* currentPos = line; - //Non pseudo filesystems have their device in /dev/, we only add those - if(strncasecmp(currentPos, "/dev/", 5) != 0) + //Non pseudo filesystems have their device in /dev/ + //DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem. + if(strncmp(currentPos, "/dev/", 5) != 0 && strncmp(currentPos, "drvfs", 5) != 0) continue; //Skip /dev/ From 45f8b86f13bd5f1561d9f122bf6c3b01790407de Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Tue, 1 Nov 2022 14:54:27 +0100 Subject: [PATCH 148/311] Don't segfault if 0 is given as argument index #326 --- src/common/format.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common/format.c b/src/common/format.c index 136b053d2..70f24e38e 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -38,6 +38,14 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) } } +/** + * @brief parses a string to a uint32_t + * + * If the string can't be parsed, or is < 1, uint32_t max is returned. + * + * @param placeholderValue the string to parse + * @return uint32_t the parsed value + */ static inline uint32_t getArgumentIndex(const FFstrbuf* placeholderValue) { uint32_t result = UINT32_MAX; @@ -45,7 +53,7 @@ static inline uint32_t getArgumentIndex(const FFstrbuf* placeholderValue) if(placeholderValue->chars[0] != '-') sscanf(placeholderValue->chars, "%u", &result); - return result; + return result == 0 ? UINT32_MAX : result; } static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start, const FFstrbuf* placeholderValue, uint32_t index, uint32_t formatStringLength) From 54c649e76eb2bf69c97651d87c1e7184397b26d4 Mon Sep 17 00:00:00 2001 From: jumps Date: Tue, 1 Nov 2022 17:53:59 +0300 Subject: [PATCH 149/311] Add Parabola GNU/Linux-libre logo --- src/logo/builtin.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 4bdeaf4ff..c35d83721 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1669,6 +1669,56 @@ static const FFlogo* getLogoPop() FF_LOGO_RETURN } +static const FFlogo* getLogoParabola() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("parabola", "parabola-gnulinux") + FF_LOGO_LINES( + " `.-. `.\n" + " `.` `:++. `-+o+.\n" + " `` `:+/. `:+/. `-+oooo+\n" + " ``-::-.:+/. `:+/. `-+oooooo+\n" + " `.-:///- ..` .-. `-+oooooooo-\n" + " `..-..` `+ooooooooo:\n" + "`` :oooooooo/\n" + " `ooooooo:\n" + " `oooooo:\n" + " -oooo+.\n" + " +ooo/`\n" + " -ooo-\n" + " `+o/.\n" + " /+-\n" + " //`\n" + " -." + ) + FF_LOGO_COLORS( + "35" //magenta + ) + FF_LOGO_COLOR_KEYS("35"); //magenta + FF_LOGO_COLOR_TITLE("35"); //magenta + FF_LOGO_RETURN +} + +static const FFlogo* getLogoParabolaSmall() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("parabola_small", "parabola-gnulinux_small") + FF_LOGO_LINES( + " __ __ __ _\n" + ".`_//_//_/ / `.\n" + " / .`\n" + " / .`\n" + " /.`\n" + " /`" + ) + FF_LOGO_COLORS( + "35" //magenta + ) + FF_LOGO_COLOR_KEYS("35"); //magenta + FF_LOGO_COLOR_TITLE("35"); //magenta + FF_LOGO_RETURN +} + static const FFlogo* getLogoPopSmall() { FF_LOGO_INIT @@ -2177,6 +2227,8 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoOpenSuseTumbleweed, getLogoPop, getLogoPopSmall, + getLogoParabola, + getLogoParabolaSmall, getLogoReborn, getLogoRebornSmall, getLogoRedHatEnterpriseLinux, From 0e92fc2289b373a5349cd98986af65f5b5c9dafe Mon Sep 17 00:00:00 2001 From: jumps Date: Tue, 1 Nov 2022 18:08:06 +0300 Subject: [PATCH 150/311] README: Add Parabola to logos sections --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52f99c321..e62584a86 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. From 449d121f1990949323d8992e9f8aff2559c2594c Mon Sep 17 00:00:00 2001 From: jumps Date: Tue, 1 Nov 2022 18:25:42 +0300 Subject: [PATCH 151/311] Fix setting `cpu-format` `--cpu-format` set `terminal-format` instead of `cpu-format` because of a typo in fastfetch.c --- src/fastfetch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fastfetch.c b/src/fastfetch.c index 4a7cf7406..0db0e3619 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1049,7 +1049,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else if(optionParseModuleArgs(key, value, "cursor", &instance->config.cursor)) {} else if(optionParseModuleArgs(key, value, "terminal", &instance->config.terminal)) {} else if(optionParseModuleArgs(key, value, "terminal-font", &instance->config.terminalFont)) {} - else if(optionParseModuleArgs(key, value, "cpu", &instance->config.terminal)) {} + else if(optionParseModuleArgs(key, value, "cpu", &instance->config.cpu)) {} else if(optionParseModuleArgs(key, value, "cpu-usage", &instance->config.cpuUsage)) {} else if(optionParseModuleArgs(key, value, "gpu", &instance->config.gpu)) {} else if(optionParseModuleArgs(key, value, "memory", &instance->config.memory)) {} From c455718adaf7e0637c1b463b84f1b5cb2d547b1a Mon Sep 17 00:00:00 2001 From: WVlab <89403101+wvlab@users.noreply.github.com> Date: Wed, 2 Nov 2022 16:00:00 +0000 Subject: [PATCH 152/311] add nobara logo --- src/logo/builtin.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index c35d83721..7c435a570 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1523,6 +1523,37 @@ static const FFlogo* getLogoNixOsSmall() FF_LOGO_RETURN } +static const FFlogo* getLogoNobara() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("nobara", "nobara-linux"); + FF_LOGO_LINES( + "⢀⣤⣴⣶⣶⣶⣦⣤⡀⠀⣀⣠⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣤⣤⣀⡀\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⡀\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠉⠁⠀⠀⠉⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⢀⣀⣀⡀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⢠⣾⣿⣿⣿⣿⣷⡄⠀⠀⠀⠻⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⣀⣀⣬⣽⣿⣿⣿⣿⣿⣿\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠈⠻⢿⣿⣿⡿⠟⠁⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠉⠉⠛⠛⢿⣿⣿⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿\n" + "⠘⢿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⠟⠁\n" + "⠈⠙⠛⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠛⠛⠉⠁\n" + ) + FF_LOGO_COLORS( + "37" // white + ) + FF_LOGO_COLOR_KEYS("37"); // white + FF_LOGO_COLOR_TITLE("37"); // white + FF_LOGO_RETURN +} + static const FFlogo* getLogoOpenSuse() { FF_LOGO_INIT @@ -2221,6 +2252,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoNixOS, getLogoNixOsOld, getLogoNixOsSmall, + getLogoNobara, getLogoOpenSuse, getLogoOpenSuseSmall, getLogoOpenSuseLeap, From 8224f8c4c6418088a7a7f19dbc9c62c95276087e Mon Sep 17 00:00:00 2001 From: WVlab <89403101+wvlab@users.noreply.github.com> Date: Wed, 2 Nov 2022 16:27:03 +0000 Subject: [PATCH 153/311] README: Add Nobara to avaliable logos section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e62584a86..f6ce7efba 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. From 4f97692245112ef27b80d2cfe99ed8b125a4db8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 2 Nov 2022 01:03:01 +0800 Subject: [PATCH 154/311] Networking: support nowait connection (Windows) --- CMakeLists.txt | 3 +- src/common/networking.c | 115 ----------------------------- src/common/networking.h | 30 +++++--- src/common/networking_linux.c | 77 +++++++++++++++++++ src/common/networking_windows.c | 127 ++++++++++++++++++++++++++++++++ src/modules/publicip.c | 13 ++-- src/modules/weather.c | 11 +-- 7 files changed, 239 insertions(+), 137 deletions(-) delete mode 100644 src/common/networking.c create mode 100644 src/common/networking_linux.c create mode 100644 src/common/networking_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 79e059926..91649c043 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,7 +220,6 @@ set(LIBFASTFETCH_SRC src/common/parsing.c src/common/settings.c src/common/library.c - src/common/networking.c src/common/bar.c src/logo/logo.c src/logo/builtin.c @@ -293,6 +292,7 @@ set(LIBFASTFETCH_SRC if(LINUX OR APPLE OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/common/processing_linux.c + src/common/networking_linux.c src/detection/users/users_linux.c src/detection/terminalshell/terminalshell_linux.c src/detection/localip/localip_linux.c @@ -360,6 +360,7 @@ endif() if(WIN32) list(APPEND LIBFASTFETCH_SRC src/common/processing_windows.c + src/common/networking_windows.c src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp diff --git a/src/common/networking.c b/src/common/networking.c deleted file mode 100644 index a5c8ed629..000000000 --- a/src/common/networking.c +++ /dev/null @@ -1,115 +0,0 @@ -#ifdef _WIN32 - #include - #include - #include - - static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context) - { - (void)once; - (void)param; - static WSADATA wsaData; - *context = &wsaData; - return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0; - } - - //Types of winsock2 are full of mess. Disable warnings for them and keep clean for posix - #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wsign-conversion" -#else - #include - #include - #include - #include - - #define closesocket close -#endif - -//Must be included after -#include "fastfetch.h" -#include "common/networking.h" - -FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout) -{ - #ifdef _WIN32 - static INIT_ONCE once = INIT_ONCE_STATIC_INIT; - WSADATA* pData; - if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData)) - return INVALID_SOCKET; - #endif - - struct addrinfo hints = { - .ai_family = AF_INET, - .ai_socktype = SOCK_STREAM, - }; - - struct addrinfo* addr; - - if(getaddrinfo(host, "80", &hints, &addr) != 0) - return INVALID_SOCKET; - - FFSockType sockfd = (FFSockType)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if(sockfd == INVALID_SOCKET) - { - freeaddrinfo(addr); - return INVALID_SOCKET; - } - - if(timeout > 0) - { - struct timeval timev; - timev.tv_sec = 0; - timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds - setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev)); - } - - if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1) - { - closesocket(sockfd); - freeaddrinfo(addr); - return INVALID_SOCKET; - } - - freeaddrinfo(addr); - - FFstrbuf command; - ffStrbufInitA(&command, 64); - ffStrbufAppendS(&command, "GET "); - ffStrbufAppendS(&command, path); - ffStrbufAppendS(&command, " HTTP/1.1\nHost: "); - ffStrbufAppendS(&command, host); - ffStrbufAppendS(&command, "\r\n"); - ffStrbufAppendS(&command, headers); - ffStrbufAppendS(&command, "\r\n"); - - if(send(sockfd, command.chars, command.length, 0) == -1) - { - ffStrbufDestroy(&command); - closesocket(sockfd); - return INVALID_SOCKET; - } - ffStrbufDestroy(&command); - return sockfd; -} - -bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer) -{ - ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0); - - if(received > 0) - { - buffer->length += (uint32_t) received; - buffer->chars[buffer->length] = '\0'; - } - - closesocket(sockfd); - return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n"); -} - -bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer) -{ - FFSockType sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout); - if(sockfd != INVALID_SOCKET) - return ffNetworkingRecvHttpResponse(sockfd, buffer); - return false; -} diff --git a/src/common/networking.h b/src/common/networking.h index 0a1b36e5d..aaad894c9 100644 --- a/src/common/networking.h +++ b/src/common/networking.h @@ -6,17 +6,27 @@ #include "util/FFstrbuf.h" #ifdef _WIN32 - typedef uintptr_t FFSockType; //SOCKET, unsigned - #ifndef INVALID_SOCKET //Don't conflict with - #define INVALID_SOCKET ((uintptr_t)~0) + #include +#endif + +typedef struct FFNetworkingState { + #ifdef _WIN32 + uintptr_t sockfd; + OVERLAPPED overlapped; + #else + int sockfd; #endif -#else - typedef int FFSockType; // signed - #define INVALID_SOCKET (-1) -#endif +} FFNetworkingState; -FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout); -bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer); -bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer); +bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers); +bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout); + +static inline bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer) +{ + FFNetworkingState state; + if(ffNetworkingSendHttpRequest(&state, host, path, headers)) + return ffNetworkingRecvHttpResponse(&state, buffer, timeout); + return false; +} #endif diff --git a/src/common/networking_linux.c b/src/common/networking_linux.c new file mode 100644 index 000000000..22e5311fa --- /dev/null +++ b/src/common/networking_linux.c @@ -0,0 +1,77 @@ +#include "fastfetch.h" +#include "common/networking.h" + +#include +#include +#include +#include + +bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers) +{ + struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM, + }; + + struct addrinfo* addr; + + if(getaddrinfo(host, "80", &hints, &addr) != 0) + return false; + + state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if(state->sockfd == -1) + { + freeaddrinfo(addr); + return false; + } + + if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1) + { + close(state->sockfd); + freeaddrinfo(addr); + return false; + } + + freeaddrinfo(addr); + + FFstrbuf command; + ffStrbufInitA(&command, 64); + ffStrbufAppendS(&command, "GET "); + ffStrbufAppendS(&command, path); + ffStrbufAppendS(&command, " HTTP/1.1\nHost: "); + ffStrbufAppendS(&command, host); + ffStrbufAppendS(&command, "\r\n"); + ffStrbufAppendS(&command, headers); + ffStrbufAppendS(&command, "\r\n"); + + if(send(state->sockfd, command.chars, command.length, 0) < 0) + { + ffStrbufDestroy(&command); + close(state->sockfd); + return false; + } + ffStrbufDestroy(&command); + return true; +} + +bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout) +{ + if(timeout > 0) + { + struct timeval timev; + timev.tv_sec = 0; + timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds + setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev)); + } + + ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0); + + if(received > 0) + { + buffer->length += (uint32_t) received; + buffer->chars[buffer->length] = '\0'; + } + + close(state->sockfd); + return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n"); +} diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c new file mode 100644 index 000000000..dd32fac16 --- /dev/null +++ b/src/common/networking_windows.c @@ -0,0 +1,127 @@ +#include +#include + +//Must be included after +#include "fastfetch.h" +#include "common/networking.h" + +static LPFN_CONNECTEX ConnectEx; + +static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context) +{ + (void)once; + (void)param; + static WSADATA wsaData; + *context = &wsaData; + if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + return FALSE; + + if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) + return FALSE; + + //Dummy socket needed for WSAIoctl + SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd == INVALID_SOCKET) + return FALSE; + + DWORD dwBytes; + GUID guid = WSAID_CONNECTEX; + if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER, + &guid, sizeof(guid), + &ConnectEx, sizeof(ConnectEx), + &dwBytes, NULL, NULL) != 0) + return FALSE; + + return closesocket(sockfd) == 0; +} + +bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers) +{ + static INIT_ONCE once = INIT_ONCE_STATIC_INIT; + WSADATA* pData; + if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData)) + return false; + + memset(state, 0, sizeof(*state)); + + struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM, + }; + + struct addrinfo* addr; + + if(getaddrinfo(host, "80", &hints, &addr) != 0) + return false; + + state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if(state->sockfd == INVALID_SOCKET) + { + freeaddrinfo(addr); + return false; + } + + { + //ConnectEx requires the socket to be initially bound + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = INADDR_ANY, + .sin_port = 0, + }; + if(bind(state->sockfd, (SOCKADDR *)&addr, sizeof(addr)) != 0) + { + printf("bind %d\n", WSAGetLastError()); + return false; + } + } + + FFstrbuf command; + ffStrbufInitA(&command, 64); + ffStrbufAppendS(&command, "GET "); + ffStrbufAppendS(&command, path); + ffStrbufAppendS(&command, " HTTP/1.1\nHost: "); + ffStrbufAppendS(&command, host); + ffStrbufAppendS(&command, "\r\n"); + ffStrbufAppendS(&command, headers); + ffStrbufAppendS(&command, "\r\n"); + + 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) + { + closesocket(state->sockfd); + return false; + } + + ffStrbufDestroy(&command); + return true; +} + +bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout) +{ + DWORD transfer, flags; + if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags)) + { + closesocket(state->sockfd); + return false; + } + + if(timeout > 0) + { + //https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt + setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)); + } + + ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int)ffStrbufGetFree(buffer), 0); + + if(received > 0) + { + buffer->length += (uint32_t) received; + buffer->chars[buffer->length] = '\0'; + } + + closesocket(state->sockfd); + return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n"); +} diff --git a/src/modules/publicip.c b/src/modules/publicip.c index 019f13dfb..61c85698e 100644 --- a/src/modules/publicip.c +++ b/src/modules/publicip.c @@ -5,12 +5,13 @@ #define FF_PUBLICIP_MODULE_NAME "Public IP" #define FF_PUBLICIP_NUM_FORMAT_ARGS 1 -static FFSockType sockfd; +static FFNetworkingState state; +static int status = -1; void ffPreparePublicIp(FFinstance* instance) { if(instance->config.publicIpUrl.length == 0) - sockfd = ffNetworkingSendHttpRequest("ipinfo.io", "/ip", NULL, instance->config.publicIpTimeout); + status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/ip", NULL); else { FFstrbuf host; @@ -27,7 +28,7 @@ void ffPreparePublicIp(FFinstance* instance) host.chars[pathStartIndex] = '\0'; } - sockfd = ffNetworkingSendHttpRequest(host.chars, path.length == 0 ? "/" : path.chars, NULL, instance->config.publicIpTimeout); + status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL); ffStrbufDestroy(&path); ffStrbufDestroy(&host); @@ -36,10 +37,10 @@ void ffPreparePublicIp(FFinstance* instance) void ffPrintPublicIp(FFinstance* instance) { - if(sockfd == 0) + if(status == -1) ffPreparePublicIp(instance); - if(sockfd == INVALID_SOCKET) + if(status == 0) { ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to connect to an IP detection server"); return; @@ -47,7 +48,7 @@ void ffPrintPublicIp(FFinstance* instance) FFstrbuf result; ffStrbufInitA(&result, 4096); - bool success = ffNetworkingRecvHttpResponse(sockfd, &result); + bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.publicIpTimeout); if(success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); if(!success || result.length == 0) diff --git a/src/modules/weather.c b/src/modules/weather.c index 11dc9748e..a6bc63ce9 100644 --- a/src/modules/weather.c +++ b/src/modules/weather.c @@ -5,23 +5,24 @@ #define FF_WEATHER_MODULE_NAME "Weather" #define FF_WEATHER_NUM_FORMAT_ARGS 1 -static FFSockType sockfd; +static FFNetworkingState state; +static int status = -1; void ffPrepareWeather(FFinstance* instance) { FFstrbuf path; ffStrbufInitS(&path, "/?format="); ffStrbufAppend(&path, &instance->config.weatherOutputFormat); - sockfd = ffNetworkingSendHttpRequest("wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n", instance->config.weatherTimeout); + status = ffNetworkingSendHttpRequest(&state, "wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n"); ffStrbufDestroy(&path); } void ffPrintWeather(FFinstance* instance) { - if(sockfd == 0) + if(status == -1) ffPrepareWeather(instance); - if(sockfd == INVALID_SOCKET) + if(status == 0) { ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to connect to 'wttr.in'"); return; @@ -29,7 +30,7 @@ void ffPrintWeather(FFinstance* instance) FFstrbuf result; ffStrbufInitA(&result, 4096); - bool success = ffNetworkingRecvHttpResponse(sockfd, &result); + bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.weatherTimeout); if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); if(!success || result.length == 0) From 46ebb52afaf53410d884ece65669556a6181af9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 2 Nov 2022 16:10:12 +0800 Subject: [PATCH 155/311] Thread: split `ffThreadCreateAndDetach`; add `ffThreadJoin` --- src/common/init.c | 10 +++++----- src/common/thread.h | 23 ++++++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 7f986818e..962bde9fe 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -305,13 +305,13 @@ FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK4, FFinstance*) void startDetectionThreads(FFinstance* instance) { #ifdef FF_HAVE_THREADS - ffThreadCreateAndDetach(ffConnectDisplayServerThreadMain, instance); + ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, instance)); #ifdef FF_DETECT_QT_GTK - ffThreadCreateAndDetach(ffDetectQtThreadMain, instance); - ffThreadCreateAndDetach(ffDetectGTK2ThreadMain, instance); - ffThreadCreateAndDetach(ffDetectGTK3ThreadMain, instance); - ffThreadCreateAndDetach(ffDetectGTK4ThreadMain, instance); + ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, instance)); + ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, instance)); + ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, instance)); + ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, instance)); #endif #else diff --git a/src/common/thread.h b/src/common/thread.h index 035ff9350..74c536cf2 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -9,35 +9,40 @@ #if defined(_WIN32) #include #include - #include // Win32 isn't available on MSYS2 + #include #define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT typedef SRWLOCK FFThreadMutex; + typedef HANDLE FFThreadType; static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); } static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); } - static inline void ffThreadCreateAndDetach(unsigned (__stdcall* func)(void*), void* data) { - uintptr_t newThread = _beginthreadex(NULL, 0, func, data, 0, NULL); - if(newThread) - CloseHandle((HANDLE)newThread); + static inline FFThreadType ffThreadCreate(unsigned (__stdcall* func)(void*), void* data) { + return (FFThreadType)_beginthreadex(NULL, 0, func, data, 0, NULL); } #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; } + static inline void ffThreadDetach(FFThreadType thread) { CloseHandle(thread); } + static inline void ffThreadJoin(FFThreadType thread) { WaitForSingleObject(thread, INFINITE); } #else #include #define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER typedef pthread_mutex_t FFThreadMutex; + typedef pthread_t FFThreadType; static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); } static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); } - static inline void ffThreadCreateAndDetach(void* (* func)(void*), void* data) { - pthread_t newThread; - if(pthread_create(&newThread, NULL, func, data) == 0) - pthread_detach(newThread); + static inline FFThreadType ffThreadCreate(void* (* func)(void*), void* data) { + FFThreadType newThread = NULL; + pthread_create(&newThread, NULL, func, data); + return newThread; } #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; } + static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); } + static inline void ffThreadJoin(FFThreadType thread) { pthread_join(thread, NULL); } #endif #else //FF_HAVE_THREADS #define FF_THREAD_MUTEX_INITIALIZER 0 typedef char FFThreadMutex; static inline void ffThreadMutexLock(FFThreadMutex* mutex) { FF_UNUSED(mutex) } static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) } + #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) #endif //FF_HAVE_THREADS #endif From 9da7bb3f30a8a99bdb8564636e599babdcd883b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 2 Nov 2022 17:29:43 +0800 Subject: [PATCH 156/311] Networking: support nowait connection (Posix) Thread was used for now. It's possible to do nonblocking connect & send with io_uring on Linux, but it requires newer kernel and linking to liburing. I don't think it is worth the effort. --- src/common/networking.h | 13 +++++-- src/common/networking_linux.c | 66 ++++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/common/networking.h b/src/common/networking.h index aaad894c9..f27850477 100644 --- a/src/common/networking.h +++ b/src/common/networking.h @@ -3,6 +3,7 @@ #ifndef FF_INCLUDED_common_networking #define FF_INCLUDED_common_networking +#include "common/thread.h" #include "util/FFstrbuf.h" #ifdef _WIN32 @@ -11,10 +12,16 @@ typedef struct FFNetworkingState { #ifdef _WIN32 - uintptr_t sockfd; - OVERLAPPED overlapped; + uintptr_t sockfd; + OVERLAPPED overlapped; #else - int sockfd; + int sockfd; + FFstrbuf host; + FFstrbuf command; + + #ifdef FF_HAVE_THREADS + FFThreadType thread; + #endif #endif } FFNetworkingState; diff --git a/src/common/networking_linux.c b/src/common/networking_linux.c index 22e5311fa..5d656fddd 100644 --- a/src/common/networking_linux.c +++ b/src/common/networking_linux.c @@ -6,7 +6,7 @@ #include #include -bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers) +static void connectAndSend(FFNetworkingState* state) { struct addrinfo hints = { .ai_family = AF_INET, @@ -15,47 +15,73 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con struct addrinfo* addr; - if(getaddrinfo(host, "80", &hints, &addr) != 0) - return false; + if(getaddrinfo(state->host.chars, "80", &hints, &addr) != 0) + goto error; state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if(state->sockfd == -1) { freeaddrinfo(addr); - return false; + goto error; } if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1) { close(state->sockfd); freeaddrinfo(addr); - return false; + goto error; } freeaddrinfo(addr); - FFstrbuf command; - ffStrbufInitA(&command, 64); - ffStrbufAppendS(&command, "GET "); - ffStrbufAppendS(&command, path); - ffStrbufAppendS(&command, " HTTP/1.1\nHost: "); - ffStrbufAppendS(&command, host); - ffStrbufAppendS(&command, "\r\n"); - ffStrbufAppendS(&command, headers); - ffStrbufAppendS(&command, "\r\n"); - - if(send(state->sockfd, command.chars, command.length, 0) < 0) + if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0) { - ffStrbufDestroy(&command); close(state->sockfd); - return false; + goto error; } - ffStrbufDestroy(&command); - return true; + + goto exit; + +error: + state->sockfd = -1; + +exit: + ffStrbufDestroy(&state->host); + ffStrbufDestroy(&state->command); +} + +FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*); + +bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers) +{ + ffStrbufInitS(&state->host, host); + + ffStrbufInitA(&state->command, 64); + ffStrbufAppendS(&state->command, "GET "); + ffStrbufAppendS(&state->command, path); + ffStrbufAppendS(&state->command, " HTTP/1.1\nHost: "); + ffStrbufAppendS(&state->command, host); + ffStrbufAppendS(&state->command, "\r\n"); + ffStrbufAppendS(&state->command, headers); + ffStrbufAppendS(&state->command, "\r\n"); + + #ifdef FF_HAVE_THREADS + state->thread = ffThreadCreate(connectAndSendThreadMain, state); + return state->thread != NULL; + #else + connectAndSend(state); + return state->sockfd != -1; + #endif } bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout) { + #ifdef FF_HAVE_THREADS + ffThreadJoin(state->thread); + #endif + if(state->sockfd == -1) + return false; + if(timeout > 0) { struct timeval timev; From 67feba6171ebcf40acae4c1c0d098df6f9e1255b Mon Sep 17 00:00:00 2001 From: "K.B.Dharun Krishna" Date: Tue, 8 Nov 2022 10:50:04 +0530 Subject: [PATCH 157/311] Add Vanilla OSlogo Adding logo for Vanilla OS a new and upcoming Ubuntu based distribution that uses Vanilla GNOME and uses on-demand immutability. Signed-off-by: K.B.Dharun Krishna --- README.md | 2 +- src/logo/builtin.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f6ce7efba..646e4277e 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Vanilla, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 7c435a570..78a528153 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2113,6 +2113,39 @@ static const FFlogo* getLogoUbuntuSmall() FF_LOGO_RETURN } +static const FFlogo* getLogoVanilla() +{ + + FF_LOGO_INIT + FF_LOGO_NAMES("vanilla", "vanilla-os","vanilla-linux"); + FF_LOGO_LINES( +" .----: \n" +" .-------.\n" +" :---::----:\n" +" .----::-----.\n" +" ......... :----::-----: ..:::-::::..\n" +".-----------------::------------------:\n" +" ----::-----------::----------::::---:\n" +" -----:::--------::-------:::-------\n" +" :------::::--::...:::::---------:\n" +" .---------::.. ..:---------.\n" +" .::-----::.. .::----::.\n" +" .:------:.......:-------:\n" +" .--------::::::::-:::-------.\n" +" .-------::-----.:-----::------.\n" +" -----::------: :------::-----\n" +" :--::--------: .-------::---:\n" +" :----------:: .:----------\n" +" :--------: :--------:" + ) + FF_LOGO_COLORS( + "33" //yellow + ) + FF_LOGO_COLOR_KEYS("33"); // yellow + FF_LOGO_COLOR_TITLE("33"); // yellow + FF_LOGO_RETURN +} + static const FFlogo* getLogoVoid() { FF_LOGO_INIT @@ -2272,6 +2305,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoUbuntu, getLogoUbuntuOld, getLogoUbuntuSmall, + getLogoVanilla, getLogoVoid, getLogoVoidSmall, getLogoZorin, From d670a9a584279b982e5f1adc74a93795612f8b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 6 Nov 2022 01:29:00 +0800 Subject: [PATCH 158/311] Kernel: support Windows 7 --- src/util/windows/utsname.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c index 07f6e52e8..a1f68021d 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); From f889d919f818dbd41f90962135ebaae7ef3c3497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 6 Nov 2022 14:41:44 +0800 Subject: [PATCH 159/311] TerminalShell: add basic support for ConEmu --- src/detection/terminalshell/terminalshell_windows.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 770e043eb..6f0139a2e 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; } From 0605cb754ba2ecdae7a8560e86e75363c38a8a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 6 Nov 2022 14:55:41 +0800 Subject: [PATCH 160/311] OS: fix Windows 7 detection --- src/detection/os/os_windows.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index e28607c9c..5bd9d11c5 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"); From 1ea44417d054beae28f566caa4c93cfc3e5983ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 6 Nov 2022 15:48:12 +0800 Subject: [PATCH 161/311] TerminalFont: add support for ConEmu --- .../terminalfont/terminalfont_windows.c | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index 6a68bb6a5..7e1d5c8cb 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" @@ -73,10 +74,64 @@ exit: RegCloseKey(hKey); } +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"); + + if(fontSize.length > 0) + ffStrbufSubstrBeforeLastC(&fontSize, '"'); + else + ffStrbufAppendS(&fontSize, "14"); + + ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&fontSize); +} + void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0) detectMintty(instance, terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0) detectConhost(instance, terminalFont); + else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "ConEmuC")) + detectConEmu(instance, terminalFont); } From 85a554b60de4e9bd620e80304788ebf2e4a99747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 6 Nov 2022 17:04:34 +0800 Subject: [PATCH 162/311] CPU: support Windows 7 --- src/detection/cpu/cpu_windows.cpp | 17 +++++++++++++---- src/util/windows/wmi.hpp | 22 ++++++++++++++-------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/detection/cpu/cpu_windows.cpp b/src/detection/cpu/cpu_windows.cpp index 8740fa4b9..e5939cd60 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/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 7b27c7590..6f7d214cb 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) { - obj = other.obj; - other.obj = nullptr; - } + 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; + } 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); From f4666fcb0a083486c32fa82f362992e8bb927bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 6 Nov 2022 16:01:10 +0800 Subject: [PATCH 163/311] README: document Windows 10- support --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 646e4277e..c9a0a1776 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, TTY, Windows Terminal, Termux, mintty, ConEmu ``` ## Building From e3de39d3ab56d54679dd8480074a10d12f02c474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 6 Nov 2022 01:33:06 +0800 Subject: [PATCH 164/311] Windows: add version info in binaries --- CMakeLists.txt | 22 ++++++++++++++++ src/util/windows/version.rc.in | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/util/windows/version.rc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 91649c043..1edbb9bc1 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/src/util/windows/version.rc.in b/src/util/windows/version.rc.in new file mode 100644 index 000000000..3e1833eec --- /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 From a5306d60eec383f0c697bd16ac308254dc1dce45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 12 Nov 2022 23:30:34 +0800 Subject: [PATCH 165/311] Windows: enable console processing, disable output buffer UCRT doesn't support line buffering, which makes modules being not printed ASAP --- src/common/init.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 962bde9fe..8a424a483 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -125,7 +125,6 @@ static void initState(FFstate* state) #ifdef WIN32 //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support setlocale(LC_ALL, ".UTF8"); - setvbuf(stdout, NULL, _IOFBF, 4096); #endif state->logoWidth = 0; @@ -334,12 +333,9 @@ static void resetConsole() #ifdef _WIN32 BOOL WINAPI consoleHandler(DWORD signal) { - if(signal == CTRL_C_EVENT) - { - resetConsole(); - return TRUE; - } - return false; + FF_UNUSED(signal); + resetConsole(); + exit(0); } #else static void exitSignalHandler(int signal) @@ -360,6 +356,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); From 227eb707d2cada6b79f4b976f3b0901922c07ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Nov 2022 17:30:16 +0800 Subject: [PATCH 166/311] CpuUsage: fix calucation on Windows --- src/detection/cpuUsage/cpuUsage_windows.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/detection/cpuUsage/cpuUsage_windows.c b/src/detection/cpuUsage/cpuUsage_windows.c index 1aa9ba3f6..bf4cc7644 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; } From 3f008c4b6d10ea8ec54e6591cbef41c92786f959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Nov 2022 17:48:57 +0800 Subject: [PATCH 167/311] CpuUsage: improve performance --- src/detection/cpuUsage/cpuUsage.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuUsage/cpuUsage.c index 7470236dc..82bf1f7d4 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; + while(true) + { + uint64_t inUseAll2, totalAll2; + error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2); + if(error) + return error; - *result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100; - - return NULL; + if(inUseAll2 != inUseAll1) + { + *result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100; + return NULL; + } + else + ffTimeSleep(250); + } } #endif //FF_DETECTION_CPUUSAGE_NOWAIT From 0bbecb3b3348420925443487d5fefcf9561111d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 17 Nov 2022 00:13:25 +0800 Subject: [PATCH 168/311] Thread: silence compiler warnings --- src/common/thread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/thread.h b/src/common/thread.h index 74c536cf2..c4d223084 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; } From 8aca8a22298f1396327895a521f0885131dd08ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Nov 2022 14:57:45 +0800 Subject: [PATCH 169/311] Temps: silence compiler warnings --- src/detection/temps/temps_apple.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c index 015546ecf..9daee1c91 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) From d0c18c46796f05189aafd75da85bacd232c162b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Nov 2022 18:19:23 +0800 Subject: [PATCH 170/311] DisplayServer: don't use private API (macOS) --- .../displayserver/displayserver_apple.c | 56 ++++++------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index 80211fb38..96bdf3d2e 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) From 0361a30c401389f06ac76d7658e83df6cef5f810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Nov 2022 18:20:28 +0800 Subject: [PATCH 171/311] Font: simplify code; fix memleaks (macOS) --- src/detection/font/font.h | 8 ++++---- src/detection/font/font_apple.m | 19 +++++-------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/detection/font/font.h b/src/detection/font/font.h index 63d19e2ee..80bed7a39 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 91689f6e9..773c7705b 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); } From d0d6f48751f2a56e05e0308f1fa5cdb3f577e710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Nov 2022 18:21:20 +0800 Subject: [PATCH 172/311] osascript: simplify code (macOS) --- src/util/apple/osascript.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/apple/osascript.m b/src/util/apple/osascript.m index 363a50d12..8b01ba069 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; } From a498e9e14230c09c00d1f89409f609fa551c1e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 17 Nov 2022 10:33:50 +0800 Subject: [PATCH 173/311] CPU: don't remove `(R)` in CPU name to be consistant with GPU name --- src/detection/cpu/cpu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/detection/cpu/cpu.c b/src/detection/cpu/cpu.c index 3a304606e..3bfe92e87 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", From fb78d9bbb9140ad62a1abf6a349ecdd093e013ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 17 Nov 2022 18:14:14 +0800 Subject: [PATCH 174/311] TerminalFont: support Warp; improve performance of Apple Terminal (macOS) --- README.md | 2 +- .../terminalfont/terminalfont_apple.m | 45 ++++++++++++++----- .../terminalshell/terminalshell_linux.c | 19 ++++++-- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index c9a0a1776..6a5f0b770 100644 --- a/README.md +++ b/README.md @@ -103,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, ConEmu +Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu ``` ## Building diff --git a/src/detection/terminalfont/terminalfont_apple.m b/src/detection/terminalfont/terminalfont_apple.m index fb8c2769b..72e4c09cc 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,44 @@ 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); + FFstrbuf 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); + ffStrbufDestroy(&font); return; } - FFstrbuf fontSize; - ffStrbufInit(&fontSize); - ffOsascript("tell application \"Terminal\" to font size of window frontmost", &fontSize); + ffFontInitWithSpace(&terminalFont->font, font.chars); + ffStrbufDestroy(&font); +} - ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.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; + } - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); + NSString* fontName = [dict valueForKey:@"FontName"]; + if(!fontName) + fontName = @"Hack"; + else + fontName = [fontName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]]; + + NSString* fontSize = [dict valueForKey:@"FontSize"]; + if(!fontSize) + fontSize = @"13"; + + ffFontInitValues(&terminalFont->font, fontName.UTF8String, fontSize.UTF8String); } void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) @@ -73,4 +92,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/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 57867fdb6..0dfc40a10 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -180,10 +180,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 +200,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) && ( @@ -365,6 +374,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 From e8e586ce7ce8f589eb8d095e82bb1001f5c19caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 13 Nov 2022 00:04:34 +0800 Subject: [PATCH 175/311] Windows / macOS: simplify code 1. simplify resource management by using C++ RAII like GCC attribute extension `cleanup` 2. simplify HEKY reading Actually `__attribute__((__cleanup__(cleanupFn)))` is supported on all major C compiler ( gcc, clang and icc ) except MSVC I only used it on Windows and macOS for now. Let's see if the project author like it. --- src/common/networking_windows.c | 4 +- src/common/processing_windows.c | 41 ++++++++++--------- src/detection/battery/battery_apple.c | 3 +- src/detection/cpu/cpu_apple.c | 3 +- src/detection/font/font_windows.cpp | 4 +- src/detection/gpu/gpu_apple.c | 3 +- src/detection/packages/packages_apple.c | 10 ++--- .../terminalfont/terminalfont_apple.m | 4 +- .../terminalfont/terminalfont_windows.c | 41 ++++++++----------- src/detection/wmtheme/wmtheme_windows.c | 25 ++++++----- src/util/FFlist.h | 4 ++ src/util/FFstrbuf.h | 5 +++ 12 files changed, 72 insertions(+), 75 deletions(-) diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c index dd32fac16..5814acc16 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 cd091ac6c..30e515734 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -27,28 +27,31 @@ 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) + BOOL success; + { - ffStrbufAppendC(&cmdline, ' '); - ffStrbufAppendS(&cmdline, *parg); + FF_STRBUF_AUTO_DESTROY cmdline; + ffStrbufInitF(&cmdline, "\"%s\"", argv[0]); + for(char* const* parg = &argv[1]; *parg; ++parg) + { + ffStrbufAppendC(&cmdline, ' '); + ffStrbufAppendS(&cmdline, *parg); + } + + 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 + ); } - 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 - - ffStrbufDestroy(&cmdline); - CloseHandle(hChildStdoutWrite); if(!success) { diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index 88499aaa7..7244a89a1 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_apple.c b/src/detection/cpu/cpu_apple.c index dc0c1a3eb..5f1b35494 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/font/font_windows.cpp b/src/detection/font/font_windows.cpp index 3d883bd58..fd400fb71 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 bad6747d3..52292d83e 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/packages/packages_apple.c b/src/detection/packages/packages_apple.c index 3966240fd..e1323e1e5 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/terminalfont/terminalfont_apple.m b/src/detection/terminalfont/terminalfont_apple.m index 72e4c09cc..1ee387aa2 100644 --- a/src/detection/terminalfont/terminalfont_apple.m +++ b/src/detection/terminalfont/terminalfont_apple.m @@ -46,19 +46,17 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi static void detectAppleTerminal(FFTerminalFontResult* terminalFont) { - FFstrbuf font; + FF_STRBUF_AUTO_DESTROY font; ffStrbufInit(&font); ffOsascript("tell application \"Terminal\" to font name of window frontmost & \" \" & font size of window frontmost", &font); if(font.length == 0) { ffStrbufAppendS(&terminalFont->error, "executing osascript failed"); - ffStrbufDestroy(&font); return; } ffFontInitWithSpace(&terminalFont->font, font.chars); - ffStrbufDestroy(&font); } static void detectWarpTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index 7e1d5c8cb..e6ea456be 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -8,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[]) { @@ -24,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) @@ -35,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"); @@ -44,34 +47,26 @@ 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, fontNameA, fontSize); - -exit: - RegCloseKey(hKey); + ffFontInitValues(&terminalFont->font, fontName, fontSize); } static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* terminalFont) diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 7611f05da..308893e1f 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -4,38 +4,41 @@ #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; + 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; } - bool result = true; int SystemUsesLightTheme = 1; DWORD bufSize = sizeof(SystemUsesLightTheme); - if(RegQueryValueExW(hKey, L"SystemUsesLightTheme", NULL, NULL, (LPBYTE)&SystemUsesLightTheme, &bufSize) != ERROR_SUCCESS) + if(RegGetValueW(hKey, NULL, L"SystemUsesLightTheme", RRF_RT_DWORD, NULL, &SystemUsesLightTheme, &bufSize) != ERROR_SUCCESS) { - ffStrbufAppendS(themeOrError, "RegOpenKeyExW(SystemUsesLightTheme) failed"); - goto exit; + ffStrbufAppendS(themeOrError, "RegGetValueW(SystemUsesLightTheme) failed"); + return false; } int AppsUsesLightTheme = 1; bufSize = sizeof(AppsUsesLightTheme); - if(RegQueryValueExW(hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&AppsUsesLightTheme, &bufSize) != ERROR_SUCCESS) + if(RegGetValueW(hKey, NULL, L"AppsUseLightTheme", RRF_RT_DWORD, NULL, &AppsUsesLightTheme, &bufSize) != ERROR_SUCCESS) { - ffStrbufAppendS(themeOrError, "RegOpenKeyExW(AppsUseLightTheme) failed"); - goto exit; + ffStrbufAppendS(themeOrError, "RegGetValueW(AppsUseLightTheme) failed"); + return false; } ffStrbufAppendF(themeOrError, "System - %s, Apps - %s", SystemUsesLightTheme ? "Light" : "Dark", AppsUsesLightTheme ? "Light" : "Dark"); -exit: - RegCloseKey(hKey); - return result; + return true; } diff --git a/src/util/FFlist.h b/src/util/FFlist.h index d9d516792..fd7a0f5ca 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 736e1d26d..80503e55d 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 From fde9379bb285a6d6894deabb37c47a12f428835c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 17 Nov 2022 20:19:27 +0800 Subject: [PATCH 176/311] Android: simplify code; fix mistakes in terminal font detection code --- src/detection/os/os_android.c | 21 +++++++------------ .../terminalfont/terminalfont_android.c | 4 ++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/detection/os/os_android.c b/src/detection/os/os_android.c index bb3b6c9da..eb4bf97d5 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/terminalfont/terminalfont_android.c b/src/detection/terminalfont/terminalfont_android.c index 8dd1ff2fe..eaa4fa52d 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 @@ exit: #else FF_UNUSED(terminalFont); - ffStrbufSetS(&terminalFont->error, "fastfetch is built without freetype2 support"); + return "fastfetch is built without freetype2 support"; #endif } From 2a349784878e03f1a4e31af5414af990f0ef3032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 17 Nov 2022 00:13:25 +0800 Subject: [PATCH 177/311] Thread: silence compiler warnings --- src/common/networking_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/networking_linux.c b/src/common/networking_linux.c index 5d656fddd..7fb6fade5 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; From 70847857f75a355411df344c00a548a621f238f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 17 Nov 2022 22:34:58 +0800 Subject: [PATCH 178/311] GPU: remove special handling for WSL WSL2 is VM, which can only provide virtual GPUs, like other VMs do. We should honor it. As of WSL 1.0, it prints `Microsoft Corporation Basic Render Driver` --- src/modules/gpu.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/modules/gpu.c b/src/modules/gpu.c index 11507191a..905fd9774 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) From f1cc94207efd389277c60947bc1cef9e04aeb310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 17 Nov 2022 22:35:40 +0800 Subject: [PATCH 179/311] Host: detect WSL version --- src/detection/host/host.h | 3 --- src/detection/host/host_linux.c | 24 ++++++++++++++++++- .../terminalshell/terminalshell_linux.c | 7 ++---- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/detection/host/host.h b/src/detection/host/host.h index e66af41fb..e49e8faad 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 ef9cfbf5e..483313103 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/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 0dfc40a10..2c3e7319d 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" @@ -239,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 From 859f645fe59ac3915046a0c47c45d95333167434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 18 Nov 2022 00:10:16 +0800 Subject: [PATCH 180/311] Disk: fix size detection on 32bit Linux Ref: #337 --- src/detection/disk/disk_linux.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 93dee0f7d..941c77957 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -73,9 +73,9 @@ 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 + 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 disk->bytesTotal = fs.f_blocks * fs.f_frsize; disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize); From 0a658679377427fb722c73b458ac5b75cf803f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 20 Nov 2022 00:52:52 +0800 Subject: [PATCH 181/311] Windows: fix memleaks --- src/detection/host/host_windows.cpp | 2 +- src/util/windows/wmi.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp index 5d0333db8..cbdd440ad 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/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 6a273f86a..cba0c07c5 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; } From 55c6374949329b168e456e5a541801098da6f6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 20 Nov 2022 00:53:14 +0800 Subject: [PATCH 182/311] WmTheme: support Windows 7 --- src/detection/wmtheme/wmtheme_windows.c | 72 +++++++++++++++++-------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 308893e1f..00303300d 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -15,30 +15,56 @@ 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) + if(RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { - ffStrbufAppendS(themeOrError, "RegOpenKeyExW() failed"); + 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; + } + + 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) + { + 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; + } + + 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; + } + + 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; } - - 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; - } - - 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; } From b6b95581cd1db5fd27b339468a3deb100e5a512e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 20 Nov 2022 02:18:06 +0800 Subject: [PATCH 183/311] Windows: partially revert a5306d60eec383f0c697bd16ac308254dc1dce45 to fix crashes on Windows 7 Very strange behavior. Needs further investigation --- src/common/init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 8a424a483..e8dc44940 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -125,6 +125,7 @@ static void initState(FFstate* state) #ifdef WIN32 //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support setlocale(LC_ALL, ".UTF8"); + setvbuf(stdout, NULL, _IOFBF, 4096); #endif state->logoWidth = 0; @@ -334,7 +335,7 @@ static void resetConsole() BOOL WINAPI consoleHandler(DWORD signal) { FF_UNUSED(signal); - resetConsole(); + resetConsole(); exit(0); } #else @@ -360,7 +361,7 @@ void ffStart(FFinstance* instance) DWORD mode = 0; GetConsoleMode(hStdout, &mode); SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); - SetConsoleOutputCP(CP_UTF8); + // SetConsoleOutputCP(CP_UTF8); #else struct sigaction action = { .sa_handler = exitSignalHandler }; sigaction(SIGINT, &action, NULL); From 1c69d6c78836dbd961c703e2f9df6104be4295f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 20 Nov 2022 19:43:02 +0800 Subject: [PATCH 184/311] Disk: use statvfs64 only when __USE_LARGEFILE64 is defined --- src/detection/disk/disk_linux.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 941c77957..8abfbdf20 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 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 + #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); From c0037c99e4aef906f1ca5700e4eda7d18ea5b074 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Sun, 20 Nov 2022 18:14:32 +0100 Subject: [PATCH 185/311] Refactor CMakeLists.txt --- CMakeLists.txt | 412 ++++++++++++++++++++++++------------------------- 1 file changed, 205 insertions(+), 207 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1edbb9bc1..01dec2e8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,249 +209,247 @@ configure_file(src/fastfetch_config.h.in fastfetch_config.h) ####################### set(LIBFASTFETCH_SRC - src/util/FFstrbuf.c - src/util/FFlist.c - src/util/FFvaluestore.c - src/common/init.c - src/common/io.c - src/common/printing.c + src/common/bar.c src/common/caching.c - src/common/properties.c src/common/font.c src/common/format.c - src/common/parsing.c - src/common/settings.c + src/common/init.c + src/common/io.c src/common/library.c - src/common/bar.c - src/logo/logo.c - src/logo/builtin.c - src/logo/image/image.c - src/logo/image/im7.c - src/logo/image/im6.c - src/detection/vulkan.c - src/detection/datetime.c - src/detection/title.c - src/detection/host/host.c - src/detection/os/os.c + src/common/parsing.c + src/common/printing.c + src/common/properties.c + src/common/settings.c src/detection/cpu/cpu.c src/detection/cpuUsage/cpuUsage.c - src/detection/gpu/gpu.c - src/detection/memory/memory.c - src/detection/swap/swap.c - src/detection/font/font.c + src/detection/datetime.c + src/detection/disk/disk.c src/detection/displayserver/displayserver.c + src/detection/font/font.c + src/detection/gpu/gpu.c + src/detection/host/host.c + src/detection/media/media.c + src/detection/memory/memory.c + src/detection/os/os.c + src/detection/packages/packages.c + src/detection/swap/swap.c src/detection/terminalfont/terminalfont.c src/detection/terminalshell/terminalshell.c - src/detection/media/media.c - src/detection/packages/packages.c - src/detection/disk/disk.c - src/modules/break.c - src/modules/custom.c - src/modules/title.c - src/modules/separator.c - src/modules/os.c - src/modules/host.c + src/detection/title.c + src/detection/vulkan.c + src/logo/builtin.c + src/logo/image/im6.c + src/logo/image/im7.c + src/logo/image/image.c + src/logo/logo.c + src/modules/battery.c src/modules/bios.c src/modules/board.c - src/modules/kernel.c - src/modules/uptime.c - src/modules/processes.c - src/modules/packages.c - src/modules/shell.c - src/modules/resolution.c - src/modules/de.c - src/modules/wm.c - src/modules/wmtheme.c - src/modules/theme.c - src/modules/icons.c - src/modules/font.c - src/modules/cursor.c - src/modules/terminal.c - src/modules/terminalfont.c + src/modules/break.c + src/modules/colors.c src/modules/cpu.c src/modules/cpuUsage.c - src/modules/gpu.c - src/modules/memory.c - src/modules/disk.c - src/modules/battery.c - src/modules/poweradapter.c - src/modules/locale.c - src/modules/vulkan.c - src/modules/localip.c - src/modules/publicip.c - src/modules/weather.c - src/modules/player.c - src/modules/song.c - src/modules/datetime.c + src/modules/cursor.c + src/modules/custom.c src/modules/date.c - src/modules/time.c - src/modules/colors.c - src/modules/opengl.c + src/modules/datetime.c + src/modules/de.c + src/modules/disk.c + src/modules/font.c + src/modules/gpu.c + src/modules/host.c + src/modules/icons.c + src/modules/kernel.c + src/modules/locale.c + src/modules/localip.c + src/modules/memory.c src/modules/opencl.c + src/modules/opengl.c + src/modules/os.c + src/modules/packages.c + src/modules/player.c + src/modules/poweradapter.c + src/modules/processes.c + src/modules/publicip.c + src/modules/resolution.c + src/modules/separator.c + src/modules/shell.c + src/modules/song.c + src/modules/terminal.c + src/modules/terminalfont.c + src/modules/theme.c + src/modules/time.c + src/modules/title.c + src/modules/uptime.c src/modules/users.c + src/modules/vulkan.c + src/modules/weather.c + src/modules/wm.c + src/modules/wmtheme.c + src/util/FFlist.c + src/util/FFstrbuf.c + src/util/FFvaluestore.c ) -if(LINUX OR APPLE OR ANDROID OR BSD) - list(APPEND LIBFASTFETCH_SRC - src/common/processing_linux.c - src/common/networking_linux.c - src/detection/users/users_linux.c - src/detection/terminalshell/terminalshell_linux.c - src/detection/localip/localip_linux.c - ) -endif() - -if(BSD OR APPLE) - list(APPEND LIBFASTFETCH_SRC - src/common/sysctl.c - src/detection/disk/disk_bsd.c - src/detection/uptime/uptime_bsd.c - src/detection/processes/processes_bsd.c - ) -endif() - -if(LINUX OR ANDROID) - list(APPEND LIBFASTFETCH_SRC - src/detection/cpu/cpu_linux.c - src/detection/cpuUsage/cpuUsage_linux.c - src/detection/disk/disk_linux.c - src/detection/memory/memory_linux.c - src/detection/processes/processes_linux.c - src/detection/swap/swap_linux.c - src/detection/uptime/uptime_linux.c - ) -endif() - -if(LINUX OR ANDROID OR BSD) - list(APPEND LIBFASTFETCH_SRC - src/detection/temps/temps_linux.c - src/detection/opengl/opengl_linux.c - src/detection/packages/packages_linux.c - - src/detection/poweradapter/poweradapter_nosupport.c - ) -endif() - -if(LINUX OR BSD) - list(APPEND LIBFASTFETCH_SRC - src/detection/os/os_linux.c - src/detection/gpu/gpu_linux.c - src/detection/displayserver/linux/displayserver_linux.c - src/detection/displayserver/linux/wayland.c - src/detection/displayserver/linux/xcb.c - src/detection/displayserver/linux/xlib.c - src/detection/displayserver/linux/wmde.c - src/detection/terminalfont/terminalfont_linux.c - src/detection/media/media_linux.c - src/detection/wmtheme/wmtheme_linux.c - src/detection/font/font_linux.c - src/detection/qt.c - src/detection/gtk.c - ) -endif() - if(LINUX) list(APPEND LIBFASTFETCH_SRC - src/detection/host/host_linux.c + src/common/networking_linux.c + src/common/processing_linux.c + src/detection/battery/battery_linux.c src/detection/bios/bios_linux.c src/detection/board/board_linux.c - src/detection/battery/battery_linux.c + src/detection/cpu/cpu_linux.c + src/detection/cpuUsage/cpuUsage_linux.c + src/detection/disk/disk_linux.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_linux.c + src/detection/localip/localip_linux.c + src/detection/media/media_linux.c + src/detection/memory/memory_linux.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_linux.c + src/detection/qt.c + src/detection/swap/swap_linux.c + src/detection/temps/temps_linux.c + src/detection/terminalfont/terminalfont_linux.c + src/detection/terminalshell/terminalshell_linux.c + src/detection/uptime/uptime_linux.c + src/detection/users/users_linux.c + src/detection/wmtheme/wmtheme_linux.c ) -endif() - -if(WIN32) +elseif(ANDROID) + list(APPEND LIBFASTFETCH_SRC + src/common/networking_linux.c + src/common/processing_linux.c + src/detection/battery/battery_nosupport.c + src/detection/bios/bios_nosupport.c + src/detection/board/board_nosupport.c + src/detection/cpu/cpu_linux.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 + src/detection/memory/memory_linux.c + src/detection/opengl/opengl_linux.c + src/detection/os/os_android.c + 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 + src/detection/terminalshell/terminalshell_linux.c + src/detection/uptime/uptime_linux.c + src/detection/users/users_linux.c + src/detection/wmtheme/wmtheme_nosupport.c + ) +elseif(BSD) + list(APPEND LIBFASTFETCH_SRC + src/common/networking_linux.c + src/common/processing_linux.c + src/common/sysctl.c + src/detection/battery/battery_nosupport.c + src/detection/bios/bios_nosupport.c + src/detection/board/board_nosupport.c + src/detection/cpu/cpu_bsd.c + src/detection/cpuUsage/cpuUsage_bsd.c + src/detection/disk/disk_bsd.c + src/detection/host/host_bsd.c + src/detection/localip/localip_linux.c + src/detection/memory/memory_bsd.c + src/detection/opengl/opengl_linux.c + src/detection/packages/packages_linux.c + src/detection/poweradapter/poweradapter_nosupport.c + src/detection/processes/processes_bsd.c + src/detection/swap/swap_bsd.c + src/detection/temps/temps_linux.c + src/detection/terminalshell/terminalshell_linux.c + src/detection/uptime/uptime_bsd.c + src/detection/users/users_linux.c + ) +elseif(APPLE) + list(APPEND LIBFASTFETCH_SRC + src/common/networking_linux.c + src/common/processing_linux.c + src/common/sysctl.c + src/detection/battery/battery_apple.c + src/detection/bios/bios_nosupport.c + src/detection/board/board_nosupport.c + src/detection/cpu/cpu_apple.c + src/detection/cpuUsage/cpuUsage_apple.c + src/detection/disk/disk_apple.m + src/detection/disk/disk_bsd.c + src/detection/displayserver/displayserver_apple.c + src/detection/font/font_apple.m + src/detection/gpu/gpu_apple.c + src/detection/host/host_apple.c + src/detection/localip/localip_linux.c + src/detection/media/media_apple.m + src/detection/memory/memory_apple.c + src/detection/opengl/opengl_apple.c + src/detection/os/os_apple.m + src/detection/packages/packages_apple.c + src/detection/poweradapter/poweradapter_apple.c + src/detection/processes/processes_bsd.c + src/detection/swap/swap_apple.c + src/detection/temps/temps_apple.c + src/detection/terminalfont/terminalfont_apple.m + src/detection/terminalshell/terminalshell_linux.c + src/detection/uptime/uptime_bsd.c + src/detection/users/users_linux.c + src/detection/wmtheme/wmtheme_apple.m + src/util/apple/cf_helpers.c + src/util/apple/osascript.m + ) +elseif(WIN32) list(APPEND LIBFASTFETCH_SRC - src/common/processing_windows.c src/common/networking_windows.c - src/detection/host/host_windows.cpp + 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/gpu/gpu_windows.cpp - src/detection/battery/battery_windows.cpp - src/detection/displayserver/displayserver_windows.c - src/detection/wmtheme/wmtheme_windows.c - src/detection/opengl/opengl_windows.c - src/detection/users/users_windows.cpp - src/detection/os/os_windows.cpp - src/detection/processes/processes_windows.cpp - src/detection/disk/disk_windows.c - src/detection/cpuUsage/cpuUsage_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp - src/detection/memory/memory_windows.cpp - src/detection/swap/swap_windows.cpp + src/detection/cpuUsage/cpuUsage_windows.c + src/detection/disk/disk_windows.c + src/detection/displayserver/displayserver_windows.c src/detection/font/font_windows.cpp - src/detection/terminalfont/terminalfont_windows.c + src/detection/gpu/gpu_windows.cpp + src/detection/host/host_windows.cpp src/detection/localip/localip_windows.c - src/detection/uptime/uptime_windows.c + src/detection/media/media_nosupport.c + src/detection/memory/memory_windows.cpp + 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/terminalfont/terminalfont_windows.c src/detection/terminalshell/terminalshell_windows.cpp - src/util/windows/wmi.cpp + src/detection/uptime/uptime_windows.c + src/detection/users/users_windows.cpp + src/detection/wmtheme/wmtheme_windows.c src/util/windows/getline.c src/util/windows/pwd.c src/util/windows/utsname.c - - src/detection/poweradapter/poweradapter_nosupport.c - src/detection/media/media_nosupport.c - ) -endif() - -if(APPLE) - list(APPEND LIBFASTFETCH_SRC - src/detection/cpuUsage/cpuUsage_apple.c - src/util/apple/cf_helpers.c - src/util/apple/osascript.m - src/detection/host/host_apple.c - src/detection/os/os_apple.m - src/detection/cpu/cpu_apple.c - src/detection/gpu/gpu_apple.c - src/detection/battery/battery_apple.c - src/detection/poweradapter/poweradapter_apple.c - src/detection/memory/memory_apple.c - src/detection/swap/swap_apple.c - src/detection/displayserver/displayserver_apple.c - src/detection/terminalfont/terminalfont_apple.m - src/detection/media/media_apple.m - src/detection/disk/disk_apple.m - src/detection/wmtheme/wmtheme_apple.m - src/detection/temps/temps_apple.c - src/detection/font/font_apple.m - src/detection/opengl/opengl_apple.c - src/detection/packages/packages_apple.c - - src/detection/bios/bios_nosupport.c - src/detection/board/board_nosupport.c - ) -endif() - -if(BSD) - list(APPEND LIBFASTFETCH_SRC - src/detection/cpu/cpu_bsd.c - src/detection/cpuUsage/cpuUsage_bsd.c - src/detection/memory/memory_bsd.c - src/detection/swap/swap_bsd.c - src/detection/host/host_bsd.c - - src/detection/battery/battery_nosupport.c - src/detection/bios/bios_nosupport.c - src/detection/board/board_nosupport.c - ) -endif() - -if(ANDROID) - list(APPEND LIBFASTFETCH_SRC - src/detection/host/host_android.c - src/detection/os/os_android.c - src/detection/terminalfont/terminalfont_android.c - - src/detection/bios/bios_nosupport.c - src/detection/board/board_nosupport.c - src/detection/displayserver/displayserver_nosupport.c - src/detection/battery/battery_nosupport.c - src/detection/gpu/gpu_nosupport.c - src/detection/font/font_nosupport.c - src/detection/media/media_nosupport.c - src/detection/wmtheme/wmtheme_nosupport.c + src/util/windows/wmi.cpp ) endif() From 19c5904561b59081846836be605108ba711832c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 12:18:36 +0800 Subject: [PATCH 186/311] Memory: improve performance by not querying WMI (Windows) --- CMakeLists.txt | 4 ++-- src/detection/memory/memory_windows.c | 11 +++++++++++ src/detection/memory/memory_windows.cpp | 25 ------------------------- src/detection/swap/swap_windows.c | 11 +++++++++++ src/detection/swap/swap_windows.cpp | 23 ----------------------- 5 files changed, 24 insertions(+), 50 deletions(-) create mode 100644 src/detection/memory/memory_windows.c delete mode 100644 src/detection/memory/memory_windows.cpp create mode 100644 src/detection/swap/swap_windows.c delete mode 100644 src/detection/swap/swap_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 01dec2e8e..21e412f6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -434,13 +434,13 @@ elseif(WIN32) src/detection/host/host_windows.cpp 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 diff --git a/src/detection/memory/memory_windows.c b/src/detection/memory/memory_windows.c new file mode 100644 index 000000000..2072d7232 --- /dev/null +++ b/src/detection/memory/memory_windows.c @@ -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; +} diff --git a/src/detection/memory/memory_windows.cpp b/src/detection/memory/memory_windows.cpp deleted file mode 100644 index 122e28d26..000000000 --- a/src/detection/memory/memory_windows.cpp +++ /dev/null @@ -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"); -} diff --git a/src/detection/swap/swap_windows.c b/src/detection/swap/swap_windows.c new file mode 100644 index 000000000..9fc1d86a4 --- /dev/null +++ b/src/detection/swap/swap_windows.c @@ -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; +} diff --git a/src/detection/swap/swap_windows.cpp b/src/detection/swap/swap_windows.cpp deleted file mode 100644 index 6e82cccab..000000000 --- a/src/detection/swap/swap_windows.cpp +++ /dev/null @@ -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"); -} From 308408a96296fc0f1b06f1ab9b2eea4e6bc5aa33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 13:05:53 +0800 Subject: [PATCH 187/311] Processes: improve performance (Windows) --- CMakeLists.txt | 6 +-- src/detection/processes/processes_windows.cpp | 46 ++++++++++++++++++- .../terminalshell/terminalshell_windows.cpp | 2 +- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 21e412f6e..283c47298 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ 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) 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 @@ -546,8 +546,8 @@ elseif(WIN32) PRIVATE "ntdll" PRIVATE "version" ) - 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() endif() diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp index 68de794a6..052162d2b 100644 --- a/src/detection/processes/processes_windows.cpp +++ b/src/detection/processes/processes_windows.cpp @@ -1,12 +1,54 @@ extern "C" { #include "processes.h" } -#include "util/windows/wmi.hpp" + +#ifdef FF_USE_WIN_NTAPI + +#include + +static inline void wrapFree(SYSTEM_PROCESS_INFORMATION** ptr) +{ + free(*ptr); +} 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* __attribute__((__cleanup__(wrapFree))) 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 +65,5 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) return 0; } } + +#endif diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 6f0139a2e..3aca7e7b4 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -10,7 +10,7 @@ extern "C" { #include -#ifdef FF_USE_WIN_FAST_PPID_DETECTION +#ifdef FF_USE_WIN_NTAPI #include From 04c9d16c1640545460b02958f52c49391a18f54b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 17:26:43 +0800 Subject: [PATCH 188/311] util: introduce register helpers and use them (Windows) --- CMakeLists.txt | 1 + .../terminalfont/terminalfont_windows.c | 36 +++-------- src/detection/wmtheme/wmtheme_windows.c | 47 +++------------ src/util/windows/register.c | 59 +++++++++++++++++++ src/util/windows/register.h | 23 ++++++++ 5 files changed, 100 insertions(+), 66 deletions(-) create mode 100644 src/util/windows/register.c create mode 100644 src/util/windows/register.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 283c47298..e60ff1e40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -448,6 +448,7 @@ elseif(WIN32) src/detection/wmtheme/wmtheme_windows.c src/util/windows/getline.c src/util/windows/pwd.c + src/util/windows/register.c src/util/windows/utsname.c src/util/windows/wmi.cpp ) diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index e6ea456be..420419648 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -2,9 +2,7 @@ #include "common/io.h" #include "detection/terminalshell/terminalshell.h" #include "terminalfont.h" - -#define WIN32_LEAN_AND_MEAN 1 -#include +#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, "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, "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, "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) diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 00303300d..c84a2c923 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -1,60 +1,31 @@ #include "fastfetch.h" #include "wmtheme.h" - -#define WIN32_LEAN_AND_MEAN 1 -#include - -static inline void wrapRegCloseKey(HKEY* phKey) -{ - if(*phKey) - RegCloseKey(*phKey); -} +#include "util/windows/register.h" 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) + FF_HKEY_AUTO_DESTROY hKey = NULL; + if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL)) { - 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"); + uint32_t SystemUsesLightTheme = 1; + if(!ffRegReadUint(hKey, "SystemUsesLightTheme", &SystemUsesLightTheme, themeOrError)) return false; - } - 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"); + uint32_t AppsUsesLightTheme = 1; + if(!ffRegReadUint(hKey, "AppsUseLightTheme", &AppsUsesLightTheme, themeOrError)) 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) + else if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL)) { - DWORD length = 0; - if(RegGetValueA(hKey, NULL, "CurrentTheme", RRF_RT_REG_SZ, NULL, NULL, &length) != ERROR_SUCCESS) - { - ffStrbufAppendS(themeOrError, "RegGetValueA(CurrentTheme, NULL) failed"); + if(!ffRegReadStrbuf(hKey, "CurrentTheme", themeOrError, themeOrError)) return false; - } - 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; - } - - themeOrError->length = length; ffStrbufSubstrBeforeLastC(themeOrError, '.'); ffStrbufSubstrAfterLastC(themeOrError, '\\'); if (isalpha(themeOrError->chars[0])) diff --git a/src/util/windows/register.c b/src/util/windows/register.c new file mode 100644 index 000000000..1e477f2e0 --- /dev/null +++ b/src/util/windows/register.c @@ -0,0 +1,59 @@ +#include "register.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 char* lpSubKey, HKEY* result, FFstrbuf* error) +{ + if(RegOpenKeyExA(hKey, lpSubKey, 0, KEY_READ, result) != ERROR_SUCCESS) + { + if(error) + ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), lpSubKey); + return false; + } + return true; +} + +bool ffRegReadStrbuf(HKEY hKey, const char* valueName, FFstrbuf* result, FFstrbuf* error) +{ + DWORD bufSize; //with tailing '\0' + if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS) + { + if(error) ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueName); + return false; + } + ffStrbufEnsureFree(result, bufSize - 1); + if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, result->chars, &bufSize) != ERROR_SUCCESS) + { + if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueName); + return false; + } + result->length = bufSize - 1; + return true; +} + +bool ffRegReadUint(HKEY hKey, const char* valueName, uint32_t* result, FFstrbuf* error) +{ + DWORD bufSize = sizeof(*result); + if(RegGetValueA(hKey, NULL, valueName, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS) + { + if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueName); + return false; + } + return true; +} diff --git a/src/util/windows/register.h b/src/util/windows/register.h new file mode 100644 index 000000000..25746c1f6 --- /dev/null +++ b/src/util/windows/register.h @@ -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 + +static inline void wrapRegCloseKey(HKEY* phKey) +{ + if(*phKey) + RegCloseKey(*phKey); +} + +#define FF_HKEY_AUTO_DESTROY HKEY __attribute__((__cleanup__(wrapRegCloseKey))) + +bool ffRegOpenKeyForRead(HKEY hKey, const char* lpSubKey, HKEY* result, FFstrbuf* error); +bool ffRegReadStrbuf(HKEY hKey, const char* valueName, FFstrbuf* result, FFstrbuf* error); +bool ffRegReadUint(HKEY hKey, const char* valueName, uint32_t* result, FFstrbuf* error); + +#endif From fbd8c0237f9244b8f9ffa13d9986b5ab0018cf7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 17:27:37 +0800 Subject: [PATCH 189/311] BIOS: improve performance (Windows) --- CMakeLists.txt | 2 +- src/detection/bios/bios_windows.c | 28 ++++++++++++++++++++++++++++ src/detection/bios/bios_windows.cpp | 28 ---------------------------- 3 files changed, 29 insertions(+), 29 deletions(-) create mode 100644 src/detection/bios/bios_windows.c delete mode 100644 src/detection/bios/bios_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e60ff1e40..30d071f29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -422,7 +422,7 @@ elseif(WIN32) src/common/networking_windows.c src/common/processing_windows.c src/detection/battery/battery_windows.cpp - src/detection/bios/bios_windows.cpp + src/detection/bios/bios_windows.c src/detection/board/board_windows.cpp src/detection/cpu/cpu_windows.cpp src/detection/cpuUsage/cpuUsage_nowait_windows.cpp diff --git a/src/detection/bios/bios_windows.c b/src/detection/bios/bios_windows.c new file mode 100644 index 000000000..68e51a904 --- /dev/null +++ b/src/detection/bios/bios_windows.c @@ -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, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error)) + return; + + if(!ffRegReadStrbuf(hKey, "BIOSVersion", &bios->biosRelease, &bios->error)) + return; + ffRegReadStrbuf(hKey, "BIOSVendor", &bios->biosVendor, NULL); + ffRegReadStrbuf(hKey, "BIOSReleaseDate", &bios->biosDate, NULL); + + uint32_t major, minor; + if( + ffRegReadUint(hKey, "BiosMajorRelease", &major, NULL) && + ffRegReadUint(hKey, "BiosMinorRelease", &minor, NULL) + ) + ffStrbufAppendF(&bios->biosVersion, "%u.%u", (unsigned)major, (unsigned)minor); +} diff --git a/src/detection/bios/bios_windows.cpp b/src/detection/bios/bios_windows.cpp deleted file mode 100644 index a48d5d538..000000000 --- a/src/detection/bios/bios_windows.cpp +++ /dev/null @@ -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"); -} From 5aebb400dabef5cbe5f2cd0b0ec8692a1af4bb94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 17:34:54 +0800 Subject: [PATCH 190/311] Board: improve performance (Windows) --- CMakeLists.txt | 2 +- src/detection/board/board_windows.c | 21 +++++++++++++++++++++ src/detection/board/board_windows.cpp | 26 -------------------------- 3 files changed, 22 insertions(+), 27 deletions(-) create mode 100644 src/detection/board/board_windows.c delete mode 100644 src/detection/board/board_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 30d071f29..2ae66aa0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -423,7 +423,7 @@ elseif(WIN32) src/common/processing_windows.c src/detection/battery/battery_windows.cpp src/detection/bios/bios_windows.c - src/detection/board/board_windows.cpp + src/detection/board/board_windows.c src/detection/cpu/cpu_windows.cpp src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/cpuUsage/cpuUsage_windows.c diff --git a/src/detection/board/board_windows.c b/src/detection/board/board_windows.c new file mode 100644 index 000000000..b2464a8b6 --- /dev/null +++ b/src/detection/board/board_windows.c @@ -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, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error)) + return; + + if(!ffRegReadStrbuf(hKey, "BaseBoardProduct", &board->boardName, &board->error)) + return; + ffRegReadStrbuf(hKey, "BaseBoardManufacturer", &board->boardVendor, NULL); + ffRegReadStrbuf(hKey, "BaseBoardVersion", &board->boardVersion, NULL); +} diff --git a/src/detection/board/board_windows.cpp b/src/detection/board/board_windows.cpp deleted file mode 100644 index e0f92bcf5..000000000 --- a/src/detection/board/board_windows.cpp +++ /dev/null @@ -1,26 +0,0 @@ -extern "C" { -#include "board.h" -} -#include "util/windows/wmi.hpp" - -extern "C" void ffDetectBoard(FFBoardResult* board) -{ - ffStrbufInit(&board->error); - - ffStrbufInit(&board->boardName); - ffStrbufInit(&board->boardVendor); - ffStrbufInit(&board->boardVersion); - - FFWmiQuery query(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error); - if(!query) - return; - - if(FFWmiRecord record = query.next()) - { - record.getString(L"Product", &board->boardName); - record.getString(L"Manufacturer", &board->boardVendor); - record.getString(L"Version", &board->boardVersion); - } - else - ffStrbufInitS(&board->error, "No Wmi result returned"); -} From 43550393294e63c21b3c78e720dde2241300f31f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 17:45:47 +0800 Subject: [PATCH 191/311] Host: improve performance (Windows) --- CMakeLists.txt | 2 +- src/detection/host/host_windows.c | 27 ++++++++++++++++++++++++ src/detection/host/host_windows.cpp | 32 ----------------------------- src/modules/host.c | 3 +-- 4 files changed, 29 insertions(+), 35 deletions(-) create mode 100644 src/detection/host/host_windows.c delete mode 100644 src/detection/host/host_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ae66aa0a..1811f0a72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -431,7 +431,7 @@ elseif(WIN32) src/detection/displayserver/displayserver_windows.c src/detection/font/font_windows.cpp 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.c diff --git a/src/detection/host/host_windows.c b/src/detection/host/host_windows.c new file mode 100644 index 000000000..abb84a169 --- /dev/null +++ b/src/detection/host/host_windows.c @@ -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, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error)) + return; + + ffRegReadStrbuf(hKey, "SystemProductName", &host->productName, NULL); + ffRegReadStrbuf(hKey, "SystemFamily", &host->productFamily, NULL); + ffRegReadStrbuf(hKey, "SystemVersion", &host->productVersion, NULL); + ffRegReadStrbuf(hKey, "SystemSKU", &host->productSku, NULL); + ffRegReadStrbuf(hKey, "SystemManufacturer", &host->sysVendor, NULL); +} diff --git a/src/detection/host/host_windows.cpp b/src/detection/host/host_windows.cpp deleted file mode 100644 index cbdd440ad..000000000 --- a/src/detection/host/host_windows.cpp +++ /dev/null @@ -1,32 +0,0 @@ -extern "C" { -#include "host.h" -} -#include "util/windows/wmi.hpp" - -extern "C" void ffDetectHostImpl(FFHostResult* host) -{ - ffStrbufInit(&host->error); - - ffStrbufInit(&host->productName); - ffStrbufInit(&host->productFamily); - ffStrbufInit(&host->productVersion); - ffStrbufInit(&host->productSku); - ffStrbufInit(&host->sysVendor); - ffStrbufInit(&host->chassisType); - ffStrbufInit(&host->chassisVendor); - ffStrbufInit(&host->chassisVersion); - - FFWmiQuery query(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error); - if(!query) - return; - - if(FFWmiRecord record = query.next()) - { - record.getString(L"Name", &host->productName); - record.getString(L"Version", &host->productVersion); - record.getString(L"SKUNumber", &host->productSku); - record.getString(L"Vendor", &host->sysVendor); - } - else - ffStrbufAppendS(&host->error, "No Wmi result returned"); -} diff --git a/src/modules/host.c b/src/modules/host.c index 8c3ec65d7..cd4f50106 100644 --- a/src/modules/host.c +++ b/src/modules/host.c @@ -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[]) { From 6a304dbb4d098f7f67dbd8d6c30b237c6e9b20f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 18:51:46 +0800 Subject: [PATCH 192/311] OS: improve performance (Windows) --- src/detection/os/os_windows.cpp | 130 +++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 44 deletions(-) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 5bd9d11c5..bc0e57dca 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -3,6 +3,50 @@ extern "C" { } #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%"); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, rawName, -1, nullptr, 0, nullptr, nullptr); + ffStrbufEnsureFree(osName, (uint32_t)size_needed); + WideCharToMultiByte(CP_UTF8, 0, rawName, -1, osName->chars, size_needed, nullptr, nullptr); + osName->length = (uint32_t)size_needed; + osName->chars[size_needed] = '\0'; + GlobalFree((HGLOBAL)rawName); + return NULL; + } + return "LoadLibraryW(winbrand.dll) failed"; +} + extern "C" void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) { @@ -19,56 +63,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); } From 9ef95e43a3fea645ed03129d53c3ab83435167fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 21 Nov 2022 22:26:50 +0800 Subject: [PATCH 193/311] CPU: improve performance (Windows) --- CMakeLists.txt | 2 +- src/detection/cpu/cpu_windows.c | 57 +++++++++++++++++++++++++++++++ src/detection/cpu/cpu_windows.cpp | 51 --------------------------- 3 files changed, 58 insertions(+), 52 deletions(-) create mode 100644 src/detection/cpu/cpu_windows.c delete mode 100644 src/detection/cpu/cpu_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1811f0a72..add970e57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -424,7 +424,7 @@ elseif(WIN32) src/detection/battery/battery_windows.cpp src/detection/bios/bios_windows.c src/detection/board/board_windows.c - src/detection/cpu/cpu_windows.cpp + src/detection/cpu/cpu_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/cpuUsage/cpuUsage_windows.c src/detection/disk/disk_windows.c diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c new file mode 100644 index 000000000..c7db11aad --- /dev/null +++ b/src/detection/cpu/cpu_windows.c @@ -0,0 +1,57 @@ +#include "cpu.h" +#include "util/windows/register.h" + +static inline void wrapFree(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX** ptr) +{ + free(*ptr); +} + +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* __attribute__((__cleanup__(wrapFree))) + 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, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL)) + return; + + { + uint32_t mhz; + if(ffRegReadUint(hKey, "~MHz", &mhz, NULL)) + cpu->frequencyMax = mhz / 1000.0; + } + + ffRegReadStrbuf(hKey, "ProcessorNameString", &cpu->name, NULL); + ffRegReadStrbuf(hKey, "VendorIdentifier", &cpu->vendor, NULL); +} diff --git a/src/detection/cpu/cpu_windows.cpp b/src/detection/cpu/cpu_windows.cpp deleted file mode 100644 index e5939cd60..000000000 --- a/src/detection/cpu/cpu_windows.cpp +++ /dev/null @@ -1,51 +0,0 @@ -extern "C" { -#include "cpu.h" -} -#include "util/windows/wmi.hpp" - -extern "C" -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) -{ - FF_UNUSED(instance); - - cpu->temperature = FF_CPU_TEMP_UNSET; - - if(cached) - return; - - cpu->coresPhysical = cpu->coresLogical = cpu->coresOnline = 0; - ffStrbufInit(&cpu->name); - ffStrbufInit(&cpu->vendor); - - FFWmiQuery query(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, NumberOfEnabledCore, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3"); - if(!query) - return; - - FFWmiRecord record = query.next(); - if(!record) - { - //NumberOfEnabledCore is not supported on Windows 10- - query = FFWmiQuery(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3"); - if(!query) - return; - record = query.next(); - } - - if(record) - { - record.getString(L"Name", &cpu->name); - record.getString(L"Manufacturer", &cpu->vendor); - - uint64_t value; - - record.getUnsigned(L"NumberOfCores", &value); - cpu->coresPhysical = (uint16_t)value; - record.getUnsigned(L"NumberOfLogicalProcessors", &value); - cpu->coresLogical = (uint16_t)value; - cpu->coresOnline = record.getUnsigned(L"NumberOfEnabledCore", &value) ? (uint16_t)value : cpu->coresPhysical; - record.getUnsigned(L"CurrentClockSpeed", &value); //There's no MinClockSpeed in Win32_Processor - cpu->frequencyMin = (double)value / 1000.0; - record.getUnsigned(L"MaxClockSpeed", &value); - cpu->frequencyMax = (double)value / 1000.0; - } -} From 629c2de2535504d4a43c5f314dbc3c3d582710b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 22 Nov 2022 01:33:22 +0800 Subject: [PATCH 194/311] util: add a helper function to convert wide strings (Windows) --- CMakeLists.txt | 2 ++ src/detection/os/os_windows.cpp | 7 ++----- src/util/windows/unicode.c | 17 +++++++++++++++++ src/util/windows/unicode.h | 10 ++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 src/util/windows/unicode.c create mode 100644 src/util/windows/unicode.h diff --git a/CMakeLists.txt b/CMakeLists.txt index add970e57..1c670ff65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -449,6 +449,7 @@ elseif(WIN32) 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 ) @@ -546,6 +547,7 @@ elseif(WIN32) PRIVATE "ws2_32" PRIVATE "ntdll" PRIVATE "version" + PRIVATE "setupapi" ) if(USE_WIN_NTAPI) target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index bc0e57dca..9f8c2570c 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -1,5 +1,6 @@ extern "C" { #include "os.h" +#include "util/windows/unicode.h" } #include "util/windows/wmi.hpp" @@ -36,11 +37,7 @@ static const char* getOsNameByWinbrand(FFstrbuf* osName) return "GetProcAddress(BrandingFormatString) failed"; const wchar_t* rawName = BrandingFormatString(L"%WINDOWS_LONG%"); - int size_needed = WideCharToMultiByte(CP_UTF8, 0, rawName, -1, nullptr, 0, nullptr, nullptr); - ffStrbufEnsureFree(osName, (uint32_t)size_needed); - WideCharToMultiByte(CP_UTF8, 0, rawName, -1, osName->chars, size_needed, nullptr, nullptr); - osName->length = (uint32_t)size_needed; - osName->chars[size_needed] = '\0'; + ffWcharToUtf8(rawName, osName); GlobalFree((HGLOBAL)rawName); return NULL; } diff --git a/src/util/windows/unicode.c b/src/util/windows/unicode.c new file mode 100644 index 000000000..4f69b5474 --- /dev/null +++ b/src/util/windows/unicode.c @@ -0,0 +1,17 @@ +#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'; +} diff --git a/src/util/windows/unicode.h b/src/util/windows/unicode.h new file mode 100644 index 000000000..d7bd50914 --- /dev/null +++ b/src/util/windows/unicode.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UNICODE_H +#define FASTFETCH_INCLUDED_UNICODE_H + +#include "fastfetch.h" + +void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result); + +#endif From 27212e8b98e8d79d9c5948f68d6aadb76188b07e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 22 Nov 2022 01:42:26 +0800 Subject: [PATCH 195/311] Battery: improve performance (Windows) --- CMakeLists.txt | 2 +- src/detection/battery/battery_windows.c | 136 ++++++++++++++++++++++ src/detection/battery/battery_windows.cpp | 65 ----------- 3 files changed, 137 insertions(+), 66 deletions(-) create mode 100644 src/detection/battery/battery_windows.c delete mode 100644 src/detection/battery/battery_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c670ff65..4726809e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -421,7 +421,7 @@ elseif(WIN32) list(APPEND LIBFASTFETCH_SRC src/common/networking_windows.c src/common/processing_windows.c - src/detection/battery/battery_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 diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c new file mode 100644 index 000000000..2c48ed964 --- /dev/null +++ b/src/detection/battery/battery_windows.c @@ -0,0 +1,136 @@ +#include "battery.h" +#include "util/windows/unicode.h" + +#include +#include +#include + +static inline void wrapFree(SP_DEVICE_INTERFACE_DETAIL_DATA_W** ptr) +{ + free(*ptr); +} +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* __attribute__((__cleanup__(wrapFree))) 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; +} diff --git a/src/detection/battery/battery_windows.cpp b/src/detection/battery/battery_windows.cpp deleted file mode 100644 index 9cf53ee28..000000000 --- a/src/detection/battery/battery_windows.cpp +++ /dev/null @@ -1,65 +0,0 @@ -extern "C" { -#include "battery.h" -} -#include "util/windows/wmi.hpp" - -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) -{ - FF_UNUSED(instance); - - //https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery - FFWmiQuery query(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery"); - - if(!query) - return "Query WMI service failed"; - - while(FFWmiRecord record = query.next()) - { - BatteryResult* battery = (BatteryResult*)ffListAdd(results); - - ffStrbufInit(&battery->manufacturer); - record.getString(L"SystemName", &battery->manufacturer); - - ffStrbufInit(&battery->modelName); - record.getString(L"Name", &battery->modelName); - - uint64_t chemistry = 0; - record.getUnsigned(L"Chemistry", &chemistry); - switch(chemistry) - { - case 1: ffStrbufInitS(&battery->technology, "Other"); break; - case 2: ffStrbufInitS(&battery->technology, "Unknown"); break; - case 3: ffStrbufInitS(&battery->technology, "Lead Acid"); break; - case 4: ffStrbufInitS(&battery->technology, "Nickel Cadmium"); break; - case 5: ffStrbufInitS(&battery->technology, "Nickel Metal Hydride"); break; - case 6: ffStrbufInitS(&battery->technology, "Lithium-ion"); break; - case 7: ffStrbufInitS(&battery->technology, "Zinc air"); break; - case 8: ffStrbufInitS(&battery->technology, "Lithium Polymer"); break; - default: ffStrbufInit(&battery->technology); break; - } - - record.getReal(L"EstimatedChargeRemaining", &battery->capacity); - - uint64_t batteryStatus; - record.getUnsigned(L"BatteryStatus", &batteryStatus); - switch(batteryStatus) - { - case 1: ffStrbufInitS(&battery->status, "Discharging"); break; - case 2: ffStrbufInitS(&battery->status, "AC Connected"); break; - case 3: ffStrbufInitS(&battery->status, "Fully Charged"); break; - case 4: ffStrbufInitS(&battery->status, "Low"); break; - case 5: ffStrbufInitS(&battery->status, "Critical"); break; - case 6: ffStrbufInitS(&battery->status, "Charging"); break; - case 7: ffStrbufInitS(&battery->status, "Charging and High"); break; - case 8: ffStrbufInitS(&battery->status, "Charging and Low"); break; - case 9: ffStrbufInitS(&battery->status, "Charging and Critical"); break; - case 10: ffStrbufInitS(&battery->status, "Undefined"); break; - case 11: ffStrbufInitS(&battery->status, "Partially Charged"); break; - default: ffStrbufInit(&battery->status); break; - } - - battery->temperature = FF_BATTERY_TEMP_UNSET; - } - - return nullptr; -} From 772dd1e2943f44bb713929108ef7226ede3e58e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 22 Nov 2022 19:25:49 +0800 Subject: [PATCH 196/311] GPU: improve performance (Windows) --- CMakeLists.txt | 5 +++ src/detection/gpu/gpu.h | 4 ++ src/detection/gpu/gpu_linux.c | 4 -- src/detection/gpu/gpu_windows.cpp | 71 +++++++++++++++++++++++++++++-- src/detection/vulkan.c | 2 +- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4726809e7..d5cd54240 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ 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_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 @@ -548,10 +549,14 @@ elseif(WIN32) PRIVATE "ntdll" PRIVATE "version" PRIVATE "setupapi" + PRIVATE "dxgi" ) 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() target_include_directories(libfastfetch diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index 08b90d3be..16bd2ff53 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -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; diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 8266357ed..17b40d28a 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -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" diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index 374c8e035..7254bc2b4 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -1,13 +1,62 @@ extern "C" { #include "gpu.h" +#include "util/windows/unicode.h" } + +#ifdef FF_USE_WIN_GPU_DXGI + +#include +#include + +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 +} diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 685de47b8..200785892 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -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; From ae562ac9627d1dd3f3cbbb139227783f8dbf42ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 12:10:45 +0800 Subject: [PATCH 197/311] Cursor: support Windows (not working yet) --- CMakeLists.txt | 5 + src/detection/cursor/cursor.h | 17 ++ src/detection/cursor/cursor_linux.c | 131 ++++++++++++ src/detection/cursor/cursor_nosupport.c | 6 + src/detection/cursor/cursor_windows.c | 12 ++ src/modules/cursor.c | 252 +++--------------------- src/util/windows/register.c | 6 +- 7 files changed, 200 insertions(+), 229 deletions(-) create mode 100644 src/detection/cursor/cursor.h create mode 100644 src/detection/cursor/cursor_linux.c create mode 100644 src/detection/cursor/cursor_nosupport.c create mode 100644 src/detection/cursor/cursor_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d5cd54240..6675f802b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -301,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 @@ -336,6 +337,7 @@ 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 @@ -370,6 +372,7 @@ 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/host/host_bsd.c src/detection/localip/localip_linux.c @@ -394,6 +397,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 @@ -428,6 +432,7 @@ elseif(WIN32) src/detection/cpu/cpu_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp 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 diff --git a/src/detection/cursor/cursor.h b/src/detection/cursor/cursor.h new file mode 100644 index 000000000..268631240 --- /dev/null +++ b/src/detection/cursor/cursor.h @@ -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 diff --git a/src/detection/cursor/cursor_linux.c b/src/detection/cursor/cursor_linux.c new file mode 100644 index 000000000..a8dfb8810 --- /dev/null +++ b/src/detection/cursor/cursor_linux.c @@ -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 + +static void detectCursorGTK(const FFinstance* instance, FFCursorResult* result) +{ + const FFGTKResult* gtk = ffDetectGTK4(instance); + + if(gtk->cursor.length == 0) + gtk = ffDetectGTK3(instance); + + if(gtk->cursor.length == 0) + gtk = ffDetectGTK2(instance); + + if(gtk->cursor.length == 0) + { + ffStrbufAppendS(&result->error, "Couldn't detect GTK Cursor"); + return; + } + + ffStrbufAppend(&result->theme, >k->cursor); + ffStrbufAppend(&result->size, >k->cursorSize); +} + +static void detectCursorXFCE(const FFinstance* instance, FFCursorResult* result) +{ + ffStrbufAppendS(&result->theme, ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue); + + if(result->theme.length == 0) + ffStrbufAppendS(&result->error, "Couldn't find xfce cursor in xfconf (xsettings::/Gtk/CursorThemeName)"); + + int cursorSizeVal = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue; + if(cursorSizeVal > 0) + ffStrbufAppendF(&result->size, "%i", cursorSizeVal); +} + +static void detectCursorFromConfigFile(const FFinstance* instance, const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault, FFCursorResult* result) +{ + if(ffParsePropFileConfigValues(instance, relativeFilePath, 2, (FFpropquery[]) { + {themeStart, &result->theme}, + {sizeStart, &result->size} + })) { + + if(result->theme.length == 0) + ffStrbufAppendS(&result->theme, themeDefault); + + if(result->size.length == 0) + ffStrbufAppendS(&result->size, sizeDefault); + } + + if(result->theme.length == 0) + ffStrbufAppendF(&result->error, "Couldn't find cursor in %s", relativeFilePath); +} + +static bool detectCursorFromXResources(const FFinstance* instance, FFCursorResult* result) +{ + ffParsePropFileHomeValues(instance, ".Xresources", 2, (FFpropquery[]) { + {"Xcursor.theme :", &result->theme}, + {"Xcursor.size :", &result->size} + }); + + return result->theme.length > 0; +} + +static bool detectCursorFromXDG(const FFinstance* instance, bool user, FFCursorResult* result) +{ + if(user) + ffParsePropFileHome(instance, ".icons/default/index.theme", "Inherits =", &result->theme); + else + ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/icons/default/index.theme", "Inherits =", &result->theme); + + return result->theme.length > 0; +} + +static bool detectCursorFromEnv(const FFinstance* instance, FFCursorResult* result) +{ + FF_UNUSED(instance); + const char* xcursor_theme = getenv("XCURSOR_THEME"); + + if(!ffStrSet(xcursor_theme)) + return false; + + ffStrbufAppendS(&result->theme, xcursor_theme); + ffStrbufAppendS(&result->size, getenv("XCURSOR_SIZE")); + + return true; +} + +void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) +{ + const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + + if(ffStrbufCompS(&wmde->wmPrettyName, "WSLg") == 0) + { + ffStrbufAppendS(&result->error, "WSLg uses native windows cursor"); + return; + } + + if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, "TTY") == 0) + { + ffStrbufAppendS(&result->error, "Cursor isn't supported in TTY"); + return; + } + + if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "KDE Plasma") == 0) + return detectCursorFromConfigFile(instance, "kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result); + + if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "XFCE")) + return detectCursorXFCE(instance, result); + + if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "LXQt")) + return detectCursorFromConfigFile(instance, "lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result); + + if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Gnome") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0) + return detectCursorGTK(instance, result); + + if( + detectCursorFromEnv(instance, result) || + detectCursorFromXDG(instance, true, result) || + detectCursorFromXResources(instance, result) || + detectCursorFromXDG(instance, false, result) + ) return; + + detectCursorGTK(instance, result); +} diff --git a/src/detection/cursor/cursor_nosupport.c b/src/detection/cursor/cursor_nosupport.c new file mode 100644 index 000000000..c548b2f6c --- /dev/null +++ b/src/detection/cursor/cursor_nosupport.c @@ -0,0 +1,6 @@ +#include "cursor.h" + +void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) +{ + ffStrbufInitS(&result->error, "Not supported on this platform"); +} diff --git a/src/detection/cursor/cursor_windows.c b/src/detection/cursor/cursor_windows.c new file mode 100644 index 000000000..fd3785637 --- /dev/null +++ b/src/detection/cursor/cursor_windows.c @@ -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, "Control Panel\\Cursors", &hKey, &result->error)) + ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error); +} diff --git a/src/modules/cursor.c b/src/modules/cursor.c index c7285427e..a5ddc90be 100644 --- a/src/modules/cursor.c +++ b/src/modules/cursor.c @@ -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 +#include "common/printing.h" +#include "detection/cursor/cursor.h" #define FF_CURSOR_MODULE_NAME "Cursor" #define FF_CURSOR_NUM_FORMAT_ARGS 2 -#if !(defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32)) - -static void printCursor(FFinstance* instance, FFstrbuf* cursorTheme, const FFstrbuf* cursorSize) +static void printCursor(FFinstance* instance, FFCursorResult* cursor) { - ffStrbufRemoveIgnCaseEndS(cursorTheme, "cursors"); - ffStrbufRemoveIgnCaseEndS(cursorTheme, "cursor"); - ffStrbufTrimRight(cursorTheme, '_'); - ffStrbufTrimRight(cursorTheme, '-'); - if(cursorTheme->length == 0) - ffStrbufAppendS(cursorTheme, "default"); + ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursors"); + ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursor"); + ffStrbufTrimRight(&cursor->theme, '_'); + ffStrbufTrimRight(&cursor->theme, '-'); + if(cursor->theme.length == 0) + ffStrbufAppendS(&cursor->theme, "default"); if(instance->config.cursor.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor.key); - ffStrbufWriteTo(cursorTheme, stdout); + ffStrbufWriteTo(&cursor->theme, stdout); - if(cursorSize != NULL && cursorSize->length > 0) - { - fputs(" (", stdout); - ffStrbufWriteTo(cursorSize, stdout); - fputs("px)", stdout); - } + if(cursor->size.length > 0) + printf(" (%spx)", cursor->size.chars); putchar('\n'); } else { ffPrintFormat(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, FF_CURSOR_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, cursorTheme}, - {FF_FORMAT_ARG_TYPE_STRBUF, cursorSize} + {FF_FORMAT_ARG_TYPE_STRBUF, &cursor->theme}, + {FF_FORMAT_ARG_TYPE_STRBUF, &cursor->size} }); } } -static void printCursorGTK(FFinstance* instance) -{ - const FFGTKResult* gtk = ffDetectGTK4(instance); - - if(gtk->cursor.length == 0) - gtk = ffDetectGTK3(instance); - - if(gtk->cursor.length == 0) - gtk = ffDetectGTK2(instance); - - if(gtk->cursor.length == 0) - { - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Couldn't detect GTK Cursor"); - return; - } - - //gtk->cursor is const, so we don't want to modify it - FFstrbuf theme; - ffStrbufInitCopy(&theme, >k->cursor); - - printCursor(instance, &theme, >k->cursorSize); - - ffStrbufDestroy(&theme); -} - -static void printCursorXFCE(FFinstance* instance) -{ - FFstrbuf cursorTheme; - ffStrbufInit(&cursorTheme); - - ffStrbufAppendS(&cursorTheme, ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue); - - if(cursorTheme.length == 0) - { - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Couldn't find xfce cursor in xfconf (xsettings::/Gtk/CursorThemeName)"); - return; - } - - FFstrbuf cursorSize; - ffStrbufInit(&cursorSize); - int cursorSizeVal = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue; - if(cursorSizeVal > 0) - ffStrbufAppendF(&cursorSize, "%i", cursorSizeVal); - - printCursor(instance, &cursorTheme, &cursorSize); - ffStrbufDestroy(&cursorTheme); - ffStrbufDestroy(&cursorSize); -} - -static void printCursorFromConfigFile(FFinstance* instance, const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault) -{ - FFstrbuf cursorTheme; - ffStrbufInit(&cursorTheme); - - FFstrbuf cursorSize; - ffStrbufInit(&cursorSize); - - if(ffParsePropFileConfigValues(instance, relativeFilePath, 2, (FFpropquery[]) { - {themeStart, &cursorTheme}, - {sizeStart, &cursorSize} - })) { - - if(cursorTheme.length == 0) - ffStrbufAppendS(&cursorTheme, themeDefault); - - if(cursorSize.length == 0) - ffStrbufAppendS(&cursorSize, sizeDefault); - } - - if(cursorTheme.length == 0) - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Couldn't find cursor in %s", relativeFilePath); - else - printCursor(instance, &cursorTheme, &cursorSize); - - ffStrbufDestroy(&cursorTheme); - ffStrbufDestroy(&cursorSize); -} - -static bool printCursorFromXResources(FFinstance* instance) -{ - FFstrbuf theme; - ffStrbufInit(&theme); - - FFstrbuf size; - ffStrbufInit(&size); - - ffParsePropFileHomeValues(instance, ".Xresources", 2, (FFpropquery[]) { - {"Xcursor.theme :", &theme}, - {"Xcursor.size :", &size} - }); - - if(theme.length == 0) - { - ffStrbufDestroy(&size); - ffStrbufDestroy(&theme); - return false; - } - - printCursor(instance, &theme, &size); - ffStrbufDestroy(&size); - ffStrbufDestroy(&theme); - return true; -} - -static bool printCursorFromXDG(FFinstance* instance, bool user) -{ - FFstrbuf theme; - ffStrbufInit(&theme); - - if(user) - ffParsePropFileHome(instance, ".icons/default/index.theme", "Inherits =", &theme); - else - ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/icons/default/index.theme", "Inherits =", &theme); - - if(theme.length == 0) - { - ffStrbufDestroy(&theme); - return false; - } - - printCursor(instance, &theme, NULL); - ffStrbufDestroy(&theme); - return true; -} - -static bool printCursorFromEnv(FFinstance* instance) -{ - const char* xcursor_theme = getenv("XCURSOR_THEME"); - - if(!ffStrSet(xcursor_theme)) - return false; - - FFstrbuf theme; - ffStrbufInit(&theme); - ffStrbufAppendS(&theme, xcursor_theme); - - FFstrbuf size; - ffStrbufInit(&size); - ffStrbufAppendS(&size, getenv("XCURSOR_SIZE")); - - printCursor(instance, &theme, &size); - - ffStrbufDestroy(&size); - ffStrbufDestroy(&theme); - return true; -} - -#endif void ffPrintCursor(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) + FFCursorResult result; + ffStrbufInit(&result.error); + ffStrbufInit(&result.theme); + ffStrbufInit(&result.size); - FF_UNUSED(instance); - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Cursor detection is not supported"); - return; + ffDetectCursor(instance, &result); - #else + if(result.error.length) + ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "%s", result.error.chars); + else + printCursor(instance, &result); - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); - - if(ffStrbufCompS(&wmde->wmPrettyName, "WSLg") == 0) - { - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "WSLg uses native windows cursor"); - return; - } - - if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, "TTY") == 0) - { - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Cursor isn't supported in TTY"); - return; - } - - if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "KDE Plasma") == 0) - { - printCursorFromConfigFile(instance, "kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24"); - return; - } - - if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "XFCE")) - { - printCursorXFCE(instance); - return; - } - - if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "LXQt")) - { - printCursorFromConfigFile(instance, "lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24"); - return; - } - - if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Gnome") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0) - { - printCursorGTK(instance); - return; - } - - if( - printCursorFromEnv(instance) || - printCursorFromXDG(instance, true) || - printCursorFromXResources(instance) || - printCursorFromXDG(instance, false) - ) return; - - printCursorGTK(instance); - - #endif + ffStrbufDestroy(&result.error); + ffStrbufDestroy(&result.theme); + ffStrbufDestroy(&result.size); } diff --git a/src/util/windows/register.c b/src/util/windows/register.c index 1e477f2e0..f8ea9e4b1 100644 --- a/src/util/windows/register.c +++ b/src/util/windows/register.c @@ -34,13 +34,13 @@ bool ffRegReadStrbuf(HKEY hKey, const char* valueName, FFstrbuf* result, FFstrbu DWORD bufSize; //with tailing '\0' if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS) { - if(error) ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueName); + if(error) ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueName ? valueName : "(default)"); return false; } ffStrbufEnsureFree(result, bufSize - 1); if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, result->chars, &bufSize) != ERROR_SUCCESS) { - if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueName); + if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueName ? valueName : "(default)"); return false; } result->length = bufSize - 1; @@ -52,7 +52,7 @@ bool ffRegReadUint(HKEY hKey, const char* valueName, uint32_t* result, FFstrbuf* DWORD bufSize = sizeof(*result); if(RegGetValueA(hKey, NULL, valueName, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS) { - if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueName); + if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueName ? valueName : "(default)"); return false; } return true; From 051423e75e89aa47cc3978c81a087e7937995060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 15:10:40 +0800 Subject: [PATCH 198/311] util: add mallocHelper and use it --- src/detection/battery/battery_windows.c | 7 ++----- src/detection/cpu/cpu_windows.c | 8 ++------ src/detection/processes/processes_windows.cpp | 8 ++------ src/util/mallocHelper.h | 9 +++++++++ 4 files changed, 15 insertions(+), 17 deletions(-) create mode 100644 src/util/mallocHelper.h diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c index 2c48ed964..ed4a1a813 100644 --- a/src/detection/battery/battery_windows.c +++ b/src/detection/battery/battery_windows.c @@ -1,14 +1,11 @@ #include "battery.h" #include "util/windows/unicode.h" +#include "util/mallocHelper.h" #include #include #include -static inline void wrapFree(SP_DEVICE_INTERFACE_DETAIL_DATA_W** ptr) -{ - free(*ptr); -} static inline void wrapCloseHandle(HANDLE* handle) { if(*handle) @@ -38,7 +35,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) DWORD cbRequired = 0; SetupDiGetDeviceInterfaceDetailW(hdev, &did, NULL, 0, &cbRequired, NULL); //Fail with not enough buffer - SP_DEVICE_INTERFACE_DETAIL_DATA_W* __attribute__((__cleanup__(wrapFree))) pdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(cbRequired); + SP_DEVICE_INTERFACE_DETAIL_DATA_W* FF_AUTO_FREE pdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(cbRequired); if(!pdidd) break; //Out of memory diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index c7db11aad..6fe9065e8 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -1,10 +1,6 @@ #include "cpu.h" #include "util/windows/register.h" - -static inline void wrapFree(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX** ptr) -{ - free(*ptr); -} +#include "util/mallocHelper.h" void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) { @@ -23,7 +19,7 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) { DWORD length = 0; GetLogicalProcessorInformationEx(RelationProcessorCore, NULL, &length); - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* __attribute__((__cleanup__(wrapFree))) + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE pLogicalInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length); if(pLogicalInfo && GetLogicalProcessorInformationEx(RelationProcessorCore, pLogicalInfo, &length)) diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp index 052162d2b..2b267c4a5 100644 --- a/src/detection/processes/processes_windows.cpp +++ b/src/detection/processes/processes_windows.cpp @@ -1,16 +1,12 @@ extern "C" { #include "processes.h" +#include "util/mallocHelper.h" } #ifdef FF_USE_WIN_NTAPI #include -static inline void wrapFree(SYSTEM_PROCESS_INFORMATION** ptr) -{ - free(*ptr); -} - uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) { FF_UNUSED(instance); @@ -23,7 +19,7 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) } size += sizeof(SystemProcessInformation) * 5; //What if new processes are created during two syscalls? - SYSTEM_PROCESS_INFORMATION* __attribute__((__cleanup__(wrapFree))) pstart = (SYSTEM_PROCESS_INFORMATION*)malloc(size); + SYSTEM_PROCESS_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PROCESS_INFORMATION*)malloc(size); if(!pstart) { ffStrbufAppendF(error, "malloc(%u) failed", (unsigned)size); diff --git a/src/util/mallocHelper.h b/src/util/mallocHelper.h new file mode 100644 index 000000000..a4fd8eb6e --- /dev/null +++ b/src/util/mallocHelper.h @@ -0,0 +1,9 @@ +#include + +static inline void ffWrapFree(void* pPtr) +{ + if(*(void**)pPtr) + free(*(void**)pPtr); +} + +#define FF_AUTO_FREE __attribute__((__cleanup__(ffWrapFree))) From 66f8a8cdd0d911754fe69b8e5a3f067d22a0edad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 15:35:45 +0800 Subject: [PATCH 199/311] TerminalFont: fix Windows Terminal font detection when running inside msys2 --- src/detection/terminalfont/terminalfont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index b673ff4fd..aeff09318 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -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))) From 4fa3ca98a249b030b8ce3a86081786f4bbb2daa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 15:42:19 +0800 Subject: [PATCH 200/311] util/register: fix crashing when value string contains non-ascii chars We can't use RegGetValueA because RegGetValueA converts wide string to non UTF-8 string, which results in crashing when printing --- src/detection/bios/bios_windows.c | 12 ++--- src/detection/board/board_windows.c | 8 +-- src/detection/cpu/cpu_windows.c | 8 +-- src/detection/cursor/cursor_windows.c | 2 +- src/detection/host/host_windows.c | 12 ++--- .../terminalfont/terminalfont_windows.c | 6 +-- src/detection/wmtheme/wmtheme_windows.c | 10 ++-- src/util/windows/register.c | 49 ++++++++++++++----- src/util/windows/register.h | 6 +-- src/util/windows/unicode.c | 19 +++++++ src/util/windows/unicode.h | 1 + 11 files changed, 88 insertions(+), 45 deletions(-) diff --git a/src/detection/bios/bios_windows.c b/src/detection/bios/bios_windows.c index 68e51a904..e29b1cc8c 100644 --- a/src/detection/bios/bios_windows.c +++ b/src/detection/bios/bios_windows.c @@ -11,18 +11,18 @@ void ffDetectBios(FFBiosResult* bios) ffStrbufInit(&bios->biosVersion); FF_HKEY_AUTO_DESTROY hKey = NULL; - if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error)) + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error)) return; - if(!ffRegReadStrbuf(hKey, "BIOSVersion", &bios->biosRelease, &bios->error)) + if(!ffRegReadStrbuf(hKey, L"BIOSVersion", &bios->biosRelease, &bios->error)) return; - ffRegReadStrbuf(hKey, "BIOSVendor", &bios->biosVendor, NULL); - ffRegReadStrbuf(hKey, "BIOSReleaseDate", &bios->biosDate, NULL); + ffRegReadStrbuf(hKey, L"BIOSVendor", &bios->biosVendor, NULL); + ffRegReadStrbuf(hKey, L"BIOSReleaseDate", &bios->biosDate, NULL); uint32_t major, minor; if( - ffRegReadUint(hKey, "BiosMajorRelease", &major, NULL) && - ffRegReadUint(hKey, "BiosMinorRelease", &minor, NULL) + ffRegReadUint(hKey, L"BiosMajorRelease", &major, NULL) && + ffRegReadUint(hKey, L"BiosMinorRelease", &minor, NULL) ) ffStrbufAppendF(&bios->biosVersion, "%u.%u", (unsigned)major, (unsigned)minor); } diff --git a/src/detection/board/board_windows.c b/src/detection/board/board_windows.c index b2464a8b6..adeae2251 100644 --- a/src/detection/board/board_windows.c +++ b/src/detection/board/board_windows.c @@ -11,11 +11,11 @@ void ffDetectBoard(FFBoardResult* board) FF_HKEY_AUTO_DESTROY hKey = NULL; - if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error)) + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error)) return; - if(!ffRegReadStrbuf(hKey, "BaseBoardProduct", &board->boardName, &board->error)) + if(!ffRegReadStrbuf(hKey, L"BaseBoardProduct", &board->boardName, &board->error)) return; - ffRegReadStrbuf(hKey, "BaseBoardManufacturer", &board->boardVendor, NULL); - ffRegReadStrbuf(hKey, "BaseBoardVersion", &board->boardVersion, NULL); + ffRegReadStrbuf(hKey, L"BaseBoardManufacturer", &board->boardVendor, NULL); + ffRegReadStrbuf(hKey, L"BaseBoardVersion", &board->boardVersion, NULL); } diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index 6fe9065e8..a0a86d169 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -39,15 +39,15 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) cpu->coresLogical = (uint16_t)GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS); FF_HKEY_AUTO_DESTROY hKey; - if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL)) + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL)) return; { uint32_t mhz; - if(ffRegReadUint(hKey, "~MHz", &mhz, NULL)) + if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL)) cpu->frequencyMax = mhz / 1000.0; } - ffRegReadStrbuf(hKey, "ProcessorNameString", &cpu->name, NULL); - ffRegReadStrbuf(hKey, "VendorIdentifier", &cpu->vendor, NULL); + ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL); + ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL); } diff --git a/src/detection/cursor/cursor_windows.c b/src/detection/cursor/cursor_windows.c index fd3785637..c820a33e7 100644 --- a/src/detection/cursor/cursor_windows.c +++ b/src/detection/cursor/cursor_windows.c @@ -7,6 +7,6 @@ void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) FF_UNUSED(instance); FF_HKEY_AUTO_DESTROY hKey; - if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "Control Panel\\Cursors", &hKey, &result->error)) + if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Cursors", &hKey, &result->error)) ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error); } diff --git a/src/detection/host/host_windows.c b/src/detection/host/host_windows.c index abb84a169..8c59eed11 100644 --- a/src/detection/host/host_windows.c +++ b/src/detection/host/host_windows.c @@ -16,12 +16,12 @@ void ffDetectHostImpl(FFHostResult* host) FF_HKEY_AUTO_DESTROY hKey = NULL; - if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error)) + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error)) return; - ffRegReadStrbuf(hKey, "SystemProductName", &host->productName, NULL); - ffRegReadStrbuf(hKey, "SystemFamily", &host->productFamily, NULL); - ffRegReadStrbuf(hKey, "SystemVersion", &host->productVersion, NULL); - ffRegReadStrbuf(hKey, "SystemSKU", &host->productSku, NULL); - ffRegReadStrbuf(hKey, "SystemManufacturer", &host->sysVendor, NULL); + 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); } diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index 420419648..55da491b3 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -31,16 +31,16 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term //Current font of conhost doesn't seem to be detectable, we detect default font instead FF_HKEY_AUTO_DESTROY hKey = NULL; - if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, "Console", &hKey, &terminalFont->error)) + if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Console", &hKey, &terminalFont->error)) return; FF_STRBUF_AUTO_DESTROY fontName; ffStrbufInit(&fontName); - if(!ffRegReadStrbuf(hKey, "FaceName", &fontName, &terminalFont->error)) + if(!ffRegReadStrbuf(hKey, L"FaceName", &fontName, &terminalFont->error)) return; uint32_t fontSizeNum = 0; - if(!ffRegReadUint(hKey, "FontSize", &fontSizeNum, &terminalFont->error)) + if(!ffRegReadUint(hKey, L"FontSize", &fontSizeNum, &terminalFont->error)) return; char fontSize[16]; diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index c84a2c923..4e47c067a 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -7,23 +7,23 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) FF_UNUSED(instance); FF_HKEY_AUTO_DESTROY hKey = NULL; - if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL)) + if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL)) { uint32_t SystemUsesLightTheme = 1; - if(!ffRegReadUint(hKey, "SystemUsesLightTheme", &SystemUsesLightTheme, themeOrError)) + if(!ffRegReadUint(hKey, L"SystemUsesLightTheme", &SystemUsesLightTheme, themeOrError)) return false; uint32_t AppsUsesLightTheme = 1; - if(!ffRegReadUint(hKey, "AppsUseLightTheme", &AppsUsesLightTheme, themeOrError)) + if(!ffRegReadUint(hKey, L"AppsUseLightTheme", &AppsUsesLightTheme, themeOrError)) return false; ffStrbufAppendF(themeOrError, "System - %s, Apps - %s", SystemUsesLightTheme ? "Light" : "Dark", AppsUsesLightTheme ? "Light" : "Dark"); return true; } - else if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL)) + else if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL)) { - if(!ffRegReadStrbuf(hKey, "CurrentTheme", themeOrError, themeOrError)) + if(!ffRegReadStrbuf(hKey, L"CurrentTheme", themeOrError, themeOrError)) return false; ffStrbufSubstrBeforeLastC(themeOrError, '.'); diff --git a/src/util/windows/register.c b/src/util/windows/register.c index f8ea9e4b1..9b0e916b0 100644 --- a/src/util/windows/register.c +++ b/src/util/windows/register.c @@ -1,4 +1,6 @@ #include "register.h" +#include "unicode.h" +#include "util/mallocHelper.h" static const char* hKey2Str(HKEY hKey) { @@ -18,41 +20,62 @@ static const char* hKey2Str(HKEY hKey) return "UNKNOWN"; } -bool ffRegOpenKeyForRead(HKEY hKey, const char* lpSubKey, HKEY* result, FFstrbuf* error) +bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error) { - if(RegOpenKeyExA(hKey, lpSubKey, 0, KEY_READ, result) != ERROR_SUCCESS) + if(RegOpenKeyExW(hKey, subKeyW, 0, KEY_READ, result) != ERROR_SUCCESS) { if(error) - ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), lpSubKey); + { + 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 char* valueName, FFstrbuf* result, FFstrbuf* error) +bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error) { DWORD bufSize; //with tailing '\0' - if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS) + if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS) { - if(error) ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueName ? valueName : "(default)"); + 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; } - ffStrbufEnsureFree(result, bufSize - 1); - if(RegGetValueA(hKey, NULL, valueName, RRF_RT_REG_SZ, NULL, result->chars, &bufSize) != ERROR_SUCCESS) + 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) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueName ? valueName : "(default)"); + 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; } - result->length = bufSize - 1; + ffWcharToUtf8(resultW, result); return true; } -bool ffRegReadUint(HKEY hKey, const char* valueName, uint32_t* result, FFstrbuf* error) +bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error) { DWORD bufSize = sizeof(*result); - if(RegGetValueA(hKey, NULL, valueName, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS) + if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS) { - if(error) ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueName ? valueName : "(default)"); + 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; diff --git a/src/util/windows/register.h b/src/util/windows/register.h index 25746c1f6..22aa6f9ce 100644 --- a/src/util/windows/register.h +++ b/src/util/windows/register.h @@ -16,8 +16,8 @@ static inline void wrapRegCloseKey(HKEY* phKey) #define FF_HKEY_AUTO_DESTROY HKEY __attribute__((__cleanup__(wrapRegCloseKey))) -bool ffRegOpenKeyForRead(HKEY hKey, const char* lpSubKey, HKEY* result, FFstrbuf* error); -bool ffRegReadStrbuf(HKEY hKey, const char* valueName, FFstrbuf* result, FFstrbuf* error); -bool ffRegReadUint(HKEY hKey, const char* valueName, uint32_t* result, FFstrbuf* error); +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 diff --git a/src/util/windows/unicode.c b/src/util/windows/unicode.c index 4f69b5474..f2ffa28cc 100644 --- a/src/util/windows/unicode.c +++ b/src/util/windows/unicode.c @@ -15,3 +15,22 @@ void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result) 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; +} diff --git a/src/util/windows/unicode.h b/src/util/windows/unicode.h index d7bd50914..d3926ff06 100644 --- a/src/util/windows/unicode.h +++ b/src/util/windows/unicode.h @@ -6,5 +6,6 @@ #include "fastfetch.h" void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result); +FFstrbuf ffStrbufFromWchar(const wchar_t* input); #endif From b28da1057c941f55ce3fe8687e7f841aaf3859f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 17:29:29 +0800 Subject: [PATCH 201/311] WmTheme: detect accent color (Windows) --- src/detection/wmtheme/wmtheme_windows.c | 52 +++++++++++++++---------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 4e47c067a..4713d7c92 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -6,36 +6,48 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) { FF_UNUSED(instance); + { + 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) + ffStrbufAppendF(themeOrError, "Accent Color - #%02X%02X%02X", bgrColor & 0xFF, (bgrColor >> 8) & 0xFF, (bgrColor >> 16) & 0xFF); + } + FF_HKEY_AUTO_DESTROY hKey = NULL; if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL)) { - uint32_t SystemUsesLightTheme = 1; - if(!ffRegReadUint(hKey, L"SystemUsesLightTheme", &SystemUsesLightTheme, themeOrError)) - return false; + uint32_t value = 1; + if(ffRegReadUint(hKey, L"SystemUsesLightTheme", &value, NULL)) + { + if(themeOrError->length > 0) ffStrbufAppendS(themeOrError, ", "); + ffStrbufAppendF(themeOrError, "System - %s", value ? "Light" : "Dark"); + } - uint32_t AppsUsesLightTheme = 1; - if(!ffRegReadUint(hKey, L"AppsUseLightTheme", &AppsUsesLightTheme, themeOrError)) - return false; - - ffStrbufAppendF(themeOrError, "System - %s, Apps - %s", SystemUsesLightTheme ? "Light" : "Dark", AppsUsesLightTheme ? "Light" : "Dark"); - - return true; + if(ffRegReadUint(hKey, L"AppsUseLightTheme", &value, NULL)) + { + if(themeOrError->length > 0) ffStrbufAppendS(themeOrError, ", "); + ffStrbufAppendF(themeOrError, "Apps - %s", value ? "Light" : "Dark"); + } } else if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL)) { - if(!ffRegReadStrbuf(hKey, L"CurrentTheme", themeOrError, themeOrError)) - return false; - - ffStrbufSubstrBeforeLastC(themeOrError, '.'); - ffStrbufSubstrAfterLastC(themeOrError, '\\'); - if (isalpha(themeOrError->chars[0])) - themeOrError->chars[0] = (char)toupper(themeOrError->chars[0]); - - return true; + 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); + } } - else + + if(themeOrError->length == 0) { ffStrbufAppendS(themeOrError, "Failed to find current theme"); return false; } + return true; } From 0f08233581e9688e91b89e8a171fb6e8ac95a2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 19:11:10 +0800 Subject: [PATCH 202/311] Users: improve performance (Windows) --- CMakeLists.txt | 3 +- src/detection/users/users_windows.c | 55 +++++++++++++++++++++++++++ src/detection/users/users_windows.cpp | 35 ----------------- 3 files changed, 57 insertions(+), 36 deletions(-) create mode 100644 src/detection/users/users_windows.c delete mode 100644 src/detection/users/users_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6675f802b..313d46e25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -450,7 +450,7 @@ elseif(WIN32) 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 @@ -555,6 +555,7 @@ elseif(WIN32) PRIVATE "version" PRIVATE "setupapi" PRIVATE "dxgi" + PRIVATE "wtsapi32" ) if(USE_WIN_NTAPI) target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI) diff --git a/src/detection/users/users_windows.c b/src/detection/users/users_windows.c new file mode 100644 index 000000000..46e5b4add --- /dev/null +++ b/src/detection/users/users_windows.c @@ -0,0 +1,55 @@ +#include "users.h" +#include "util/windows/unicode.h" + +#include + +//at the time of writing, 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"); +} diff --git a/src/detection/users/users_windows.cpp b/src/detection/users/users_windows.cpp deleted file mode 100644 index 9e50cd365..000000000 --- a/src/detection/users/users_windows.cpp +++ /dev/null @@ -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"); -} From 31863baee2bfb0bccc0e313b82ebf6a5cee997a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 19:13:51 +0800 Subject: [PATCH 203/311] CpuUsage: remove unused code (Windows) --- CMakeLists.txt | 1 - src/detection/cpuUsage/cpuUsage.c | 14 -------------- src/detection/cpuUsage/cpuUsage.h | 5 ----- .../cpuUsage/cpuUsage_nowait_windows.cpp | 18 ------------------ 4 files changed, 38 deletions(-) delete mode 100644 src/detection/cpuUsage/cpuUsage_nowait_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 313d46e25..815059e90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -430,7 +430,6 @@ elseif(WIN32) src/detection/bios/bios_windows.c src/detection/board/board_windows.c src/detection/cpu/cpu_windows.c - src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/cpuUsage/cpuUsage_windows.c src/detection/cursor/cursor_windows.c src/detection/disk/disk_windows.c diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuUsage/cpuUsage.c index 82bf1f7d4..1dbdb4bfb 100644 --- a/src/detection/cpuUsage/cpuUsage.c +++ b/src/detection/cpuUsage/cpuUsage.c @@ -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 @@ -61,5 +49,3 @@ const char* ffGetCpuUsageResult(double* result) ffTimeSleep(250); } } - -#endif //FF_DETECTION_CPUUSAGE_NOWAIT diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index 126fc1a8e..250b30570 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -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 diff --git a/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp b/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp deleted file mode 100644 index 7ef1aa855..000000000 --- a/src/detection/cpuUsage/cpuUsage_nowait_windows.cpp +++ /dev/null @@ -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; -} From 325aa536c47b7bccd80752d1abd17f44d22d99bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 23 Nov 2022 19:57:55 +0800 Subject: [PATCH 204/311] Font: improve performance (Windows) --- CMakeLists.txt | 2 +- src/detection/font/font.h | 2 +- src/detection/font/font_windows.c | 22 ++++++++++++++++++++ src/detection/font/font_windows.cpp | 32 ----------------------------- src/modules/font.c | 9 ++++++-- 5 files changed, 31 insertions(+), 36 deletions(-) create mode 100644 src/detection/font/font_windows.c delete mode 100644 src/detection/font/font_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 815059e90..04e4d1950 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -434,7 +434,7 @@ elseif(WIN32) 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.c src/detection/localip/localip_windows.c diff --git a/src/detection/font/font.h b/src/detection/font/font.h index 80bed7a39..822815d2a 100644 --- a/src/detection/font/font.h +++ b/src/detection/font/font.h @@ -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]; diff --git a/src/detection/font/font_windows.c b/src/detection/font/font_windows.c new file mode 100644 index 000000000..b2595d04d --- /dev/null +++ b/src/detection/font/font_windows.c @@ -0,0 +1,22 @@ +#include "font.h" +#include "util/windows/unicode.h" + +#include + +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); + } +} diff --git a/src/detection/font/font_windows.cpp b/src/detection/font/font_windows.cpp deleted file mode 100644 index fd400fb71..000000000 --- a/src/detection/font/font_windows.cpp +++ /dev/null @@ -1,32 +0,0 @@ -extern "C" { -#include "font.h" -#include "common/font.h" -} -#include "util/windows/wmi.hpp" - -#include - -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"); -} diff --git a/src/modules/font.c b/src/modules/font.c index 9ca20b547..25f394f61 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -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; + } } } From 11258c0d8d2718c08a7029918dfae37a9850fa57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 24 Nov 2022 11:16:53 +0800 Subject: [PATCH 205/311] TerminalShell: code cleanup (Windows) --- .../terminalshell/terminalshell_windows.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 3aca7e7b4..92ef75004 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -4,12 +4,9 @@ extern "C" { #include "common/thread.h" } -#include #include #include -#include - #ifdef FF_USE_WIN_NTAPI #include @@ -59,6 +56,7 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb #else #include "util/windows/wmi.hpp" +#include static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName) { @@ -143,9 +141,9 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufSetS(&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 +197,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; From 4b3ed6787764c5485e6bf0f5937ec414a7baf057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 24 Nov 2022 11:24:12 +0800 Subject: [PATCH 206/311] TerminalShell: detect Clink --- .../terminalshell/terminalshell_windows.cpp | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 92ef75004..135388650 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -6,6 +6,7 @@ extern "C" { #include #include +#include #ifdef FF_USE_WIN_NTAPI @@ -138,7 +139,28 @@ 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->shellPrettyName, "explorer")) From 8de88adc0b74751b903b7e6aac282c94fbf3f8e9 Mon Sep 17 00:00:00 2001 From: draumaz Date: Wed, 23 Nov 2022 23:31:11 -0800 Subject: [PATCH 207/311] add CRUX logo, update README.md --- README.md | 2 +- src/logo/builtin.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a5f0b770..e83042df0 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Vanilla, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Vanilla, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 78a528153..bf95a9ba9 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -511,6 +511,40 @@ static const FFlogo* getLogoCentOSSmall() FF_LOGO_RETURN } +static const FFlogo* getLogoCRUX() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("CRUX", "crux") + FF_LOGO_LINES( + " $1odddd\n" + " oddxkkkxxdoo\n" + " ddcoddxxxdoool\n" + " xdclodod olol\n" + " xoc xdd olol\n" + " xdc $2k00$1Okdlol\n" + " xxd$2kOKKKOkd$1ldd\n" + " xdco$2xOkdlo$1dldd\n" + " ddc:cl$2lll$1oooodo\n" + " odxxdd$3xkO000kx$1ooxdo\n" + " oxddx$30NMMMMMMWW0o$1dkkxo\n" + " oooxd$30WMMMMMMMMMW0o$1dxkx\n" + "docldkXW$3MMMMMMMWWN$1Odolco\n" + "xx$2dx$1kxxOKN$3WMMWN$10xdoxo::c\n" + "$2xOkkO$10oo$3odOW$2WW$1XkdodOxc:l\n" + "$2dkkkxkkk$3OKX$2NNNX0Oxx$1xc:cd\n" + " $2odxxdx$3xllo$2dddooxx$1dc:ldo\n" + " $2lodd$1dolccc$2ccox$1xoloo\n" + ) + FF_LOGO_COLORS( + "34", //blue + "35", //magenta + "37" //white + ) + FF_LOGO_COLOR_KEYS("35"); + FF_LOGO_COLOR_TITLE("34"); + FF_LOGO_RETURN +} + static const FFlogo* getLogoCrystalLinux() { FF_LOGO_INIT @@ -2251,6 +2285,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoCelOS, getLogoCentOS, getLogoCentOSSmall, + getLogoCRUX, getLogoCrystalLinux, getLogoDebian, getLogoDevuan, From d500bdff964dd2be328ea9d1d4d1d143b0f7e97c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 24 Nov 2022 17:38:40 +0800 Subject: [PATCH 208/311] WmTheme: convert known color values to readable strings --- src/detection/wmtheme/wmtheme_windows.c | 66 ++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 4713d7c92..e19e9bcbc 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -2,6 +2,62 @@ #include "wmtheme.h" #include "util/windows/register.h" +const char* colorHexToString(DWORD hex) +{ + 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); @@ -10,7 +66,15 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) 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) - ffStrbufAppendF(themeOrError, "Accent Color - #%02X%02X%02X", bgrColor & 0xFF, (bgrColor >> 8) & 0xFF, (bgrColor >> 16) & 0xFF); + { + 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); + } } FF_HKEY_AUTO_DESTROY hKey = NULL; From d70b3100f237ad417e73d5265cabdfea3cb3fe0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 24 Nov 2022 18:54:52 +0800 Subject: [PATCH 209/311] BSD: fix build --- CMakeLists.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04e4d1950..6716badc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -343,7 +343,6 @@ elseif(ANDROID) 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 @@ -353,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 @@ -374,18 +372,31 @@ elseif(BSD) 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 From c50d7bf974a25c82f2c9bc6149e8da06c70cbf50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 24 Nov 2022 21:06:08 +0800 Subject: [PATCH 210/311] Logo: remove `Windows 11 Old`, add `Windows 11 Small` --- src/logo/builtin.c | 64 +++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 78a528153..fa8adf874 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1302,23 +1302,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 @@ -1328,32 +1328,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 } @@ -2115,7 +2109,7 @@ static const FFlogo* getLogoUbuntuSmall() static const FFlogo* getLogoVanilla() { - + FF_LOGO_INIT FF_LOGO_NAMES("vanilla", "vanilla-os","vanilla-linux"); FF_LOGO_LINES( @@ -2279,7 +2273,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoMintOld, getLogoMsys2, getLogoWindows11, - getLogoWindows11Old, + getLogoWindows11Small, getLogoWindows8, getLogoWindows, getLogoNixOS, From 7da45d6c2c152d146977170647183ab64fd29c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 24 Nov 2022 21:21:52 +0800 Subject: [PATCH 211/311] DE: fix detection for Windows Server --- .../displayserver/displayserver_windows.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index 354961094..f39955b8b 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -39,10 +39,19 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067 const FFOSResult* os = ffDetectOS(instance); - if(ffStrbufCompS(&os->version, "11") == 0 || ffStrbufCompS(&os->version, "10") == 0) - ffStrbufSetS(&ds->dePrettyName, "Fluent"); - else if(ffStrbufCompS(&os->version, "8") == 0 || ffStrbufStartsWithS(&os->version, "8.")) - ffStrbufSetS(&ds->dePrettyName, "Metro"); + if( + ffStrbufEqualS(&os->version, "11") || + ffStrbufEqualS(&os->version, "10") || + ffStrbufEqualS(&os->version, "2022") || + ffStrbufEqualS(&os->version, "2019") || + ffStrbufEqualS(&os->version, "2016") + ) ffStrbufSetS(&ds->dePrettyName, "Fluent"); + else if( + ffStrbufEqualS(&os->version, "8") || + ffStrbufEqualS(&os->version, "81.") || + ffStrbufEqualS(&os->version, "2012 R2") || + ffStrbufEqualS(&os->version, "2012") + ) ffStrbufSetS(&ds->dePrettyName, "Metro"); else ffStrbufSetS(&ds->dePrettyName, "Aero"); } From 0ab38bb4d74099db50175eb61178c43831c0d76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 24 Nov 2022 23:29:46 +0800 Subject: [PATCH 212/311] CPU: fix cpu freq detection in WSL `/sys/devices/system/cpu/cpufreq/policy0/` doesn't exist in WSL --- src/detection/cpu/cpu_linux.c | 39 ++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 83c0f1140..ea1c45a69 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -6,7 +6,7 @@ #include #include -static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer) +static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz) { FILE* cpuinfo = fopen("/proc/cpuinfo", "r"); if(cpuinfo == NULL) @@ -25,6 +25,7 @@ static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer) ffParsePropLine(line, "model name :", &cpu->name) || ffParsePropLine(line, "vendor_id :", &cpu->vendor) || ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) || + ffParsePropLine(line, "cpu MHz :", cpuMHz) || (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) //For Android devices ); } @@ -39,16 +40,19 @@ static double getGHz(const char* file) { FFstrbuf content; ffStrbufInit(&content); - ffReadFileBuffer(file, &content); - double herz = ffStrbufToDouble(&content); - ffStrbufDestroy(&content); + if(ffAppendFileBuffer(file, &content)) + { + double herz = ffStrbufToDouble(&content); + ffStrbufDestroy(&content); - //ffStrbufToDouble failed - if(herz != herz) - return 0; + //ffStrbufToDouble failed + if(herz != herz) + return 0; - herz /= 1000.0; //to MHz - return herz / 1000.0; //to GHz + herz /= 1000.0; //to MHz + return herz / 1000.0; //to GHz + } + return 0; } static double getFrequency(const char* info, const char* scaling) @@ -91,7 +95,10 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) FFstrbuf physicalCoresBuffer; ffStrbufInit(&physicalCoresBuffer); - parseCpuInfo(cpu, &physicalCoresBuffer); + FFstrbuf cpuMHz; + ffStrbufInit(&cpuMHz); + + parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz); cpu->coresPhysical = ffStrbufToUInt16(&physicalCoresBuffer, 1); @@ -104,8 +111,16 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) #endif #define BP "/sys/devices/system/cpu/cpufreq/policy0/" - cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq"); - cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq"); + if(ffFileExists(BP, S_IFDIR)) + { + cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq"); + cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq"); + } + else + { + cpu->frequencyMin = cpu->frequencyMax = ffStrbufToDouble(&cpuMHz) / 1000; + } ffStrbufDestroy(&physicalCoresBuffer); + ffStrbufDestroy(&cpuMHz); } From 00f86c63463cb5c227c405629e8af3a6f7035372 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 24 Nov 2022 18:10:49 +0100 Subject: [PATCH 213/311] CMake: Don't require pkg-config --- CMakeLists.txt | 141 +++++++++++++++++++++++++++++++++++++++---------- README.md | 4 +- 2 files changed, 115 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6716badc5..13154fcc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,10 @@ endif() set(THREADS_PREFER_PTHREAD_FLAG NOT WIN32) find_package(Threads) -find_package(PkgConfig REQUIRED) +find_package(PkgConfig) +if(NOT PKG_CONFIG_FOUND) + message(WARNING "pkg-config not found, library detection might be limited") +endif() include(CheckIncludeFile) @@ -488,20 +491,33 @@ if(HAVE_UTMPX_H) target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX_H) endif() -function(ff_lib_enable VARNAME) +function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME) if(NOT ENABLE_${VARNAME}) return() endif() - pkg_search_module(${VARNAME} ${ARGN}) + if(PKG_CONFIG_FOUND) + pkg_search_module(${VARNAME} QUIET ${PKGCONFIG_NAMES}) + endif() + if(NOT ${VARNAME}_FOUND) - message(WARNING "Package ${ARGV1} not found, building without support.") + find_package(${CMAKE_NAME} QUIET) + + set(${VARNAME}_FOUND ${${CMAKE_NAME}_FOUND}) + set(${VARNAME}_INCLUDE_DIRS ${${CMAKE_NAME}_INCLUDE_DIRS}) + set(${VARNAME}_LIBRARIES ${${CMAKE_NAME}_LIBRARIES}) + set(${VARNAME}_CFLAGS_OTHER ${${CMAKE_NAME}_CFLAGS_OTHER}) + endif() + + if(NOT ${VARNAME}_FOUND) + message(STATUS "Library: missing: ${VARNAME}") return() endif() + message(STATUS "Library: found ${VARNAME}") + target_compile_definitions(libfastfetch PRIVATE FF_HAVE_${VARNAME}=1) target_include_directories(libfastfetch PRIVATE ${${VARNAME}_INCLUDE_DIRS}) - target_link_directories(libfastfetch PRIVATE ${${VARNAME}_LIBRARY_DIRS}) foreach(FLAG ${${VARNAME}_CFLAGS_OTHER}) if(FLAG MATCHES "-D.*") @@ -511,29 +527,98 @@ function(ff_lib_enable VARNAME) endforeach() endfunction() -ff_lib_enable(LIBPCI libpci) -ff_lib_enable(VULKAN vulkan) -ff_lib_enable(WAYLAND wayland-client) -ff_lib_enable(XCB_RANDR xcb-randr) -ff_lib_enable(XCB xcb) -ff_lib_enable(XRANDR xrandr) -ff_lib_enable(X11 x11) -ff_lib_enable(GIO gio-2.0) -ff_lib_enable(DCONF dconf) -ff_lib_enable(DBUS dbus-1) -ff_lib_enable(XFCONF libxfconf-0) -ff_lib_enable(SQLITE3 sqlite3) -ff_lib_enable(RPM rpm) -ff_lib_enable(IMAGEMAGICK7 MagickCore-7.Q16HDRI MagickCore-7.Q16 MagickCore-7 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.pc) -ff_lib_enable(IMAGEMAGICK6 MagickCore-6.Q16HDRI MagickCore-6.Q16 MagickCore-6 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.pc) -ff_lib_enable(ZLIB zlib) -ff_lib_enable(CHAFA chafa>=1.10) -ff_lib_enable(EGL egl) -ff_lib_enable(GLX glx) -ff_lib_enable(OSMESA osmesa) -ff_lib_enable(OPENCL OpenCL) -ff_lib_enable(LIBCJSON libcjson) -ff_lib_enable(FREETYPE freetype2) +ff_lib_enable(LIBPCI + "libpci" + "Pci" +) +ff_lib_enable(VULKAN + "vulkan" + "Vulkan" +) +ff_lib_enable(WAYLAND + "wayland-client" + "WaylandClient" +) +ff_lib_enable(XCB_RANDR + "xcb-randr" + "XcbRandr" +) +ff_lib_enable(XCB + "xcb" + "Xcb" +) +ff_lib_enable(XRANDR + "xrandr" + "XRandr" +) +ff_lib_enable(X11 + "x11" + "X11" +) +ff_lib_enable(GIO + "gio-2.0" + "GIO" +) +ff_lib_enable(DCONF + "dconf" + "DConf" +) +ff_lib_enable(DBUS + "dbus-1" + "DBus" +) +ff_lib_enable(XFCONF + "libxfconf-0" + "XFConf" +) +ff_lib_enable(SQLITE3 + "sqlite3" + "SQLite3" +) +ff_lib_enable(RPM + "rpm" + "RPM" +) +ff_lib_enable(IMAGEMAGICK7 + "MagickCore-7.Q16HDRI;MagickCore-7.Q16;MagickCore-7;/usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc;/usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc;/usr/lib/imagemagick7/pkgconfig/MagickCore-7.pc" + "ImageMagick7" +) +ff_lib_enable(IMAGEMAGICK6 + "MagickCore-6.Q16HDRI;MagickCore-6.Q16;MagickCore-6;/usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc;/usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc;/usr/lib/imagemagick6/pkgconfig/MagickCore-6.pc" + "ImageMagick6" +) +ff_lib_enable(ZLIB + "zlib" + "ZLIB" +) +ff_lib_enable(CHAFA + "chafa>=1.10" + "Chafa" +) +ff_lib_enable(EGL + "egl" + "EGL" +) +ff_lib_enable(GLX + "glx" + "GLX" +) +ff_lib_enable(OSMESA + "osmesa" + "OSMesa" +) +ff_lib_enable(OPENCL + "OpenCL" + "OpenCL" +) +ff_lib_enable(LIBCJSON + "libcjson" + "CJson" +) +ff_lib_enable(FREETYPE + "freetype2" + "FreeType2" +) if(ENABLE_THREADS) target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS) diff --git a/README.md b/README.md index e83042df0..c966c4d5d 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, A ## Building -fastfetch uses [`cmake`](https://cmake.org/) and [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) for building. The simplest steps to build the fastfetch and flashfetch binaries are: +fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are: ```bash mkdir -p build cd build @@ -116,7 +116,7 @@ cmake .. cmake --build . --target fastfetch --target flashfetch ``` -If pkg-config fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available. +If the build process fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available. ### Building on Windows From c57417e83429157f2d09b41586a3953d8738131e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 25 Nov 2022 18:09:08 +0800 Subject: [PATCH 214/311] Logo: adjust ubuntu logo style --- src/logo/builtin.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 0cdaaa520..43167ef6a 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2054,26 +2054,26 @@ static const FFlogo* getLogoUbuntu() FF_LOGO_NAMES("ubuntu", "ubuntu-linux") FF_LOGO_LINES( " ....\n" - " .',:clooo: .:looooo:.\n" - " .;looooooooc .oooooooooo'\n" - " .;looooool:,''. :ooooooooooc\n" - " ;looool;. 'oooooooooo,\n" - " ;clool' .cooooooc. ,,\n" - " ... ...... .:oo,\n" + " .',:clooo: .:looooo:.\n" + " .;looooooooc .oooooooooo'\n" + " .;looooool:,''. :ooooooooooc\n" + " ;looool;. 'oooooooooo,\n" + " ;clool' .cooooooc. ,,\n" + " ... ...... .:oo,\n" " .;clol:,. .loooo'\n" - ":ooooooooo, 'ooool\n" + " :ooooooooo, 'ooool\n" "'ooooooooooo. loooo.\n" "'ooooooooool coooo.\n" " ,loooooooc. .loooo.\n" " .,;;;'. ;ooooc\n" - " ... ,ooool.\n" - " .cooooc. ..',,'. .cooo.\n" - " ;ooooo:. ;oooooooc. :l.\n" - " .coooooc,.. coooooooooo.\n" - " .:ooooooolc:. .ooooooooooo'\n" - " .':loooooo; ,oooooooooc\n" - " ..';::c' .;loooo:'\n" - " ." + " ... ,ooool.\n" + " .cooooc. ..',,'. .cooo.\n" + " ;ooooo:. ;oooooooc. :l.\n" + " .coooooc,.. coooooooooo.\n" + " .:ooooooolc:. .ooooooooooo'\n" + " .':loooooo; ,oooooooooc\n" + " ..';::c' .;loooo:'\n" + " ." ) From 34d3021b803b75ca78f1203cb78648d3a3795c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 25 Nov 2022 19:17:37 +0800 Subject: [PATCH 215/311] Build: fix Android is incorrectly detected as Linux --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13154fcc4..fe0f2e9f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,12 +12,13 @@ set(PROJECT_LICENSE "MIT license") ################### # Target Platform # ################### - -if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") +if(ANDROID) + set(LINUX FALSE) +elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) -elseif(NOT APPLE AND NOT ANDROID AND NOT WIN32) +elseif(NOT APPLE AND NOT WIN32) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() From c6a9217c744cc0141f13b2a1c30721e45ce2e40c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 25 Nov 2022 23:13:57 +0800 Subject: [PATCH 216/311] Windows: silense compiler warnings --- src/detection/os/os_windows.cpp | 3 +-- src/detection/terminalshell/terminalshell_windows.cpp | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 9f8c2570c..287063449 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -31,8 +31,7 @@ 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"); + auto BrandingFormatString = (PWSTR(WINAPI*)(PCWSTR))GetProcAddress(hWinbrand, "BrandingFormatString"); if(!BrandingFormatString) return "GetProcAddress(BrandingFormatString) failed"; diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 135388650..a475643df 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -147,7 +147,8 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) if(snapshot) { - MODULEENTRY32W module = { .dwSize = sizeof(module) }; + MODULEENTRY32W module; + 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) From 4316ba988bd35b9f0c0edc8f834e9b21b925f3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 25 Nov 2022 23:14:41 +0800 Subject: [PATCH 217/311] CpuUsage: optimise performance further --- src/detection/cpuUsage/cpuUsage.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuUsage/cpuUsage.c index 1dbdb4bfb..88355668d 100644 --- a/src/detection/cpuUsage/cpuUsage.c +++ b/src/detection/cpuUsage/cpuUsage.c @@ -8,29 +8,22 @@ // We need to use uint64_t because sizeof(long) == 4 on Windows const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll); -static uint64_t inUseAll1, totalAll1, startTime; +static uint64_t inUseAll1, totalAll1; void ffPrepareCPUUsage() { - startTime = ffTimeGetTick(); ffGetCpuUsageInfo(&inUseAll1, &totalAll1); } const char* ffGetCpuUsageResult(double* result) { const char* error = NULL; - if(startTime == 0) + if(inUseAll1 == 0 && totalAll1 == 0) { error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1); if(error) return error; - ffTimeSleep(250); - } - else - { - uint64_t duration = ffTimeGetTick() - startTime; - if(duration < 250) - ffTimeSleep(250 - (uint32_t) duration); + ffTimeSleep(200); } while(true) @@ -46,6 +39,6 @@ const char* ffGetCpuUsageResult(double* result) return NULL; } else - ffTimeSleep(250); + ffTimeSleep(200); } } From 4cf1d5bf946c175934cc36030785e867a6c99186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 26 Nov 2022 12:52:04 +0800 Subject: [PATCH 218/311] util: rename unicode helper function names --- src/detection/battery/battery_windows.c | 4 ++-- src/detection/font/font_windows.c | 2 +- src/detection/gpu/gpu_windows.cpp | 2 +- src/detection/os/os_windows.cpp | 2 +- src/detection/users/users_windows.c | 4 ++-- src/util/windows/register.c | 10 +++++----- src/util/windows/unicode.c | 18 ++++++++---------- src/util/windows/unicode.h | 14 ++++++++++++-- 8 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c index ed4a1a813..37822fe5e 100644 --- a/src/detection/battery/battery_windows.c +++ b/src/detection/battery/battery_windows.c @@ -86,7 +86,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) 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); + ffStrbufSetWS(&battery->modelName, name); } { @@ -94,7 +94,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) 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); + ffStrbufSetWS(&battery->manufacturer, name); } battery->temperature = 0.0/0.0; diff --git a/src/detection/font/font_windows.c b/src/detection/font/font_windows.c index b2595d04d..d858b8b42 100644 --- a/src/detection/font/font_windows.c +++ b/src/detection/font/font_windows.c @@ -15,7 +15,7 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) for(uint32_t i = 0; i < sizeof(fonts) / sizeof(fonts[0]); ++i) { - ffWcharToUtf8(fonts[i]->lfFaceName, &result->fonts[i]); + ffStrbufSetWS(&result->fonts[i], fonts[i]->lfFaceName); if(fonts[i]->lfHeight < 0) ffStrbufAppendF(&result->fonts[i], " (%dpt)", (int)-fonts[i]->lfHeight); } diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index 7254bc2b4..f5d0f4946 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -36,7 +36,7 @@ static const char* detectWithDxgi(FFlist* gpus) ffStrbufInit(&gpu->vendor); ffStrbufInit(&gpu->name); - ffWcharToUtf8(desc.Description, &gpu->name); + ffStrbufSetWS(&gpu->name, desc.Description); ffStrbufInit(&gpu->driver); diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 287063449..fdda72c89 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -36,7 +36,7 @@ static const char* getOsNameByWinbrand(FFstrbuf* osName) return "GetProcAddress(BrandingFormatString) failed"; const wchar_t* rawName = BrandingFormatString(L"%WINDOWS_LONG%"); - ffWcharToUtf8(rawName, osName); + ffStrbufSetWS(osName, rawName); GlobalFree((HGLOBAL)rawName); return NULL; } diff --git a/src/detection/users/users_windows.c b/src/detection/users/users_windows.c index 46e5b4add..0b4316c10 100644 --- a/src/detection/users/users_windows.c +++ b/src/detection/users/users_windows.c @@ -42,8 +42,8 @@ void ffDetectUsers(FFlist* users, FFstrbuf* error) if(session->State != WTSActive) continue; - FF_STRBUF_AUTO_DESTROY domainName = ffStrbufFromWchar(session->pDomainName); - FF_STRBUF_AUTO_DESTROY userName = ffStrbufFromWchar(session->pUserName); + FF_STRBUF_AUTO_DESTROY domainName = ffStrbufCreateWS(session->pDomainName); + FF_STRBUF_AUTO_DESTROY userName = ffStrbufCreateWS(session->pUserName); ffStrbufInitF((FFstrbuf*)ffListAdd(users), "%s\\%s", domainName.chars, userName.chars); } diff --git a/src/util/windows/register.c b/src/util/windows/register.c index 9b0e916b0..9f02137c3 100644 --- a/src/util/windows/register.c +++ b/src/util/windows/register.c @@ -26,7 +26,7 @@ bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrb { if(error) { - FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufFromWchar(subKeyW); + FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufCreateWS(subKeyW); ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars); } return false; @@ -43,7 +43,7 @@ bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFs { if(!valueNameW) valueNameW = L"(default)"; - FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW); + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); ffStrbufAppendF(error, "RegGetValueA(%s, NULL, RRF_RT_REG_SZ) failed", valueNameA.chars); } return false; @@ -55,12 +55,12 @@ bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFs { if(!valueNameW) valueNameW = L"(default)"; - FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW); + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_REG_SZ) failed", valueNameA.chars); } return false; } - ffWcharToUtf8(resultW, result); + ffStrbufSetWS(result, resultW); return true; } @@ -73,7 +73,7 @@ bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstr { if(!valueNameW) valueNameW = L"(default)"; - FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufFromWchar(valueNameW); + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); ffStrbufAppendF(error, "RegGetValueA(%s, result, RRF_RT_DWORD) failed", valueNameA.chars); } return false; diff --git a/src/util/windows/unicode.c b/src/util/windows/unicode.c index f2ffa28cc..b25cdcdd9 100644 --- a/src/util/windows/unicode.c +++ b/src/util/windows/unicode.c @@ -1,33 +1,31 @@ #include "unicode.h" -void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result) +void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source) { - int len = (int)wcslen(input); - if(len <= 0) + if(!length) { ffStrbufClear(result); return; } - int size_needed = WideCharToMultiByte(CP_UTF8, 0, input, len, NULL, 0, NULL, NULL); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL); ffStrbufEnsureFree(result, (uint32_t)size_needed); - WideCharToMultiByte(CP_UTF8, 0, input, len, result->chars, size_needed, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, source, (int)length, result->chars, size_needed, NULL, NULL); result->length = (uint32_t)size_needed; result->chars[size_needed] = '\0'; } -FFstrbuf ffStrbufFromWchar(const wchar_t* input) +FFstrbuf ffStrbufCreateNWS(uint32_t length, const wchar_t* source) { FFstrbuf result; - int len = input ? (int)wcslen(input) : 0; - if(len <= 0) + if(length == 0) ffStrbufInit(&result); else { - int size_needed = WideCharToMultiByte(CP_UTF8, 0, input, len, NULL, 0, NULL, NULL); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL); ffStrbufInitA(&result, (uint32_t)size_needed); - WideCharToMultiByte(CP_UTF8, 0, input, len, result.chars, size_needed, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, source, (int)length, result.chars, size_needed, NULL, NULL); result.length = (uint32_t)size_needed; result.chars[size_needed] = '\0'; } diff --git a/src/util/windows/unicode.h b/src/util/windows/unicode.h index d3926ff06..d70fbb22e 100644 --- a/src/util/windows/unicode.h +++ b/src/util/windows/unicode.h @@ -4,8 +4,18 @@ #define FASTFETCH_INCLUDED_UNICODE_H #include "fastfetch.h" +#include -void ffWcharToUtf8(const wchar_t* input, FFstrbuf* result); -FFstrbuf ffStrbufFromWchar(const wchar_t* input); +void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source); +static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source) +{ + return ffStrbufSetNWS(result, (uint32_t)wcslen(source), source); +} + +FFstrbuf ffStrbufCreateNWS(uint32_t length, const wchar_t* source); +static inline FFstrbuf ffStrbufCreateWS(const wchar_t* source) +{ + return ffStrbufCreateNWS((uint32_t)wcslen(source), source); +} #endif From 5c381460cecdbaeeed1c9fa609ffffb89536a03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 26 Nov 2022 12:55:48 +0800 Subject: [PATCH 219/311] util: rename register -> registry --- CMakeLists.txt | 2 +- src/detection/bios/bios_windows.c | 2 +- src/detection/board/board_windows.c | 2 +- src/detection/cpu/cpu_windows.c | 2 +- src/detection/cursor/cursor_windows.c | 2 +- src/detection/host/host_windows.c | 2 +- src/detection/terminalfont/terminalfont_windows.c | 2 +- src/detection/wmtheme/wmtheme_windows.c | 2 +- src/util/windows/{register.c => registry.c} | 2 +- src/util/windows/{register.h => registry.h} | 0 10 files changed, 9 insertions(+), 9 deletions(-) rename src/util/windows/{register.c => registry.c} (99%) rename src/util/windows/{register.h => registry.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe0f2e9f8..aaaa0ab24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -468,7 +468,7 @@ elseif(WIN32) src/detection/wmtheme/wmtheme_windows.c src/util/windows/getline.c src/util/windows/pwd.c - src/util/windows/register.c + src/util/windows/registry.c src/util/windows/unicode.c src/util/windows/utsname.c src/util/windows/wmi.cpp diff --git a/src/detection/bios/bios_windows.c b/src/detection/bios/bios_windows.c index e29b1cc8c..7facb2576 100644 --- a/src/detection/bios/bios_windows.c +++ b/src/detection/bios/bios_windows.c @@ -1,5 +1,5 @@ #include "bios.h" -#include "util/windows/register.h" +#include "util/windows/registry.h" void ffDetectBios(FFBiosResult* bios) { diff --git a/src/detection/board/board_windows.c b/src/detection/board/board_windows.c index adeae2251..4d02b679b 100644 --- a/src/detection/board/board_windows.c +++ b/src/detection/board/board_windows.c @@ -1,5 +1,5 @@ #include "board.h" -#include "util/windows/register.h" +#include "util/windows/registry.h" void ffDetectBoard(FFBoardResult* board) { diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index a0a86d169..acef000bc 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -1,5 +1,5 @@ #include "cpu.h" -#include "util/windows/register.h" +#include "util/windows/registry.h" #include "util/mallocHelper.h" void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) diff --git a/src/detection/cursor/cursor_windows.c b/src/detection/cursor/cursor_windows.c index c820a33e7..b231d85b2 100644 --- a/src/detection/cursor/cursor_windows.c +++ b/src/detection/cursor/cursor_windows.c @@ -1,6 +1,6 @@ #include "cursor.h" -#include "util/windows/register.h" +#include "util/windows/registry.h" void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) { diff --git a/src/detection/host/host_windows.c b/src/detection/host/host_windows.c index 8c59eed11..5d0ae363b 100644 --- a/src/detection/host/host_windows.c +++ b/src/detection/host/host_windows.c @@ -1,5 +1,5 @@ #include "host.h" -#include "util/windows/register.h" +#include "util/windows/registry.h" void ffDetectHostImpl(FFHostResult* host) { diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index 55da491b3..590aa9339 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -2,7 +2,7 @@ #include "common/io.h" #include "detection/terminalshell/terminalshell.h" #include "terminalfont.h" -#include "util/windows/register.h" +#include "util/windows/registry.h" static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index e19e9bcbc..80a253bf5 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -1,6 +1,6 @@ #include "fastfetch.h" #include "wmtheme.h" -#include "util/windows/register.h" +#include "util/windows/registry.h" const char* colorHexToString(DWORD hex) { diff --git a/src/util/windows/register.c b/src/util/windows/registry.c similarity index 99% rename from src/util/windows/register.c rename to src/util/windows/registry.c index 9f02137c3..2257e1963 100644 --- a/src/util/windows/register.c +++ b/src/util/windows/registry.c @@ -1,4 +1,4 @@ -#include "register.h" +#include "registry.h" #include "unicode.h" #include "util/mallocHelper.h" diff --git a/src/util/windows/register.h b/src/util/windows/registry.h similarity index 100% rename from src/util/windows/register.h rename to src/util/windows/registry.h From a55add190c9d06b58c8b4db6069ccdbd98ed3448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 26 Nov 2022 18:23:08 +0800 Subject: [PATCH 220/311] Wifi: add new module Only Windows is supported currently --- CMakeLists.txt | 7 + completions/bash | 3 + src/common/init.c | 9 +- src/data/config_user.txt | 1 + src/detection/wifi/wifi.h | 44 +++++ src/detection/wifi/wifi_nosupport.c | 7 + src/detection/wifi/wifi_windows.c | 242 ++++++++++++++++++++++++++++ src/fastfetch.c | 21 +++ src/fastfetch.h | 2 + src/flashfetch.c | 1 + src/modules/wifi.c | 79 +++++++++ 11 files changed, 410 insertions(+), 6 deletions(-) create mode 100644 src/detection/wifi/wifi.h create mode 100644 src/detection/wifi/wifi_nosupport.c create mode 100644 src/detection/wifi/wifi_windows.c create mode 100644 src/modules/wifi.c diff --git a/CMakeLists.txt b/CMakeLists.txt index aaaa0ab24..f8e732d46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -289,6 +289,7 @@ set(LIBFASTFETCH_SRC src/modules/users.c src/modules/vulkan.c src/modules/weather.c + src/modules/wifi.c src/modules/wm.c src/modules/wmtheme.c src/util/FFlist.c @@ -331,6 +332,7 @@ if(LINUX) src/detection/terminalshell/terminalshell_linux.c src/detection/uptime/uptime_linux.c src/detection/users/users_linux.c + src/detection/wifi/wifi_nosupport.c src/detection/wmtheme/wmtheme_linux.c ) elseif(ANDROID) @@ -362,6 +364,7 @@ elseif(ANDROID) src/detection/terminalshell/terminalshell_linux.c src/detection/uptime/uptime_linux.c src/detection/users/users_linux.c + src/detection/wifi/wifi_nosupport.c src/detection/wmtheme/wmtheme_nosupport.c ) elseif(BSD) @@ -400,6 +403,7 @@ elseif(BSD) src/detection/terminalshell/terminalshell_linux.c src/detection/uptime/uptime_bsd.c src/detection/users/users_linux.c + src/detection/wifi/wifi_nosupport.c src/detection/wmtheme/wmtheme_linux.c ) elseif(APPLE) @@ -433,6 +437,7 @@ elseif(APPLE) src/detection/terminalshell/terminalshell_linux.c src/detection/uptime/uptime_bsd.c src/detection/users/users_linux.c + src/detection/wifi/wifi_nosupport.c src/detection/wmtheme/wmtheme_apple.m src/util/apple/cf_helpers.c src/util/apple/osascript.m @@ -465,6 +470,7 @@ elseif(WIN32) src/detection/terminalshell/terminalshell_windows.cpp src/detection/uptime/uptime_windows.c src/detection/users/users_windows.c + src/detection/wifi/wifi_windows.c src/detection/wmtheme/wmtheme_windows.c src/util/windows/getline.c src/util/windows/pwd.c @@ -652,6 +658,7 @@ elseif(WIN32) PRIVATE "setupapi" PRIVATE "dxgi" PRIVATE "wtsapi32" + PRIVATE "wlanapi.lib" ) if(USE_WIN_NTAPI) target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI) diff --git a/completions/bash b/completions/bash index fc771d5ad..8a3ef9e0c 100644 --- a/completions/bash +++ b/completions/bash @@ -307,6 +307,9 @@ __fastfetch_completion() "--public-ip-key" "--public-ip-format" "--public-ip-error" + "--wifi-key" + "--wifi-format" + "--wifi-error" "--weather-key" "--weather-format" "--weather-error" diff --git a/src/common/init.c b/src/common/init.c index e8dc44940..1bb934771 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -16,11 +16,6 @@ #include #endif -static bool strbufEqualsAdapter(const void* first, const void* second) -{ - return ffStrbufComp(second, first) == 0; -} - static void initConfigDirs(FFstate* state) { ffListInit(&state->configDirs, sizeof(FFstrbuf)); @@ -35,7 +30,7 @@ static void initConfigDirs(FFstate* state) } #define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \ - if(ffListFirstIndexComp(&state->configDirs, element, strbufEqualsAdapter) < state->configDirs.length - 1) \ + if(ffListFirstIndexComp(&state->configDirs, element, (bool(*)(const void*, const void*))ffStrbufEqual) < state->configDirs.length - 1) \ { \ ffStrbufDestroy(ffListGet(&state->configDirs, state->configDirs.length - 1)); \ --state->configDirs.length; \ @@ -214,6 +209,7 @@ static void defaultConfig(FFinstance* instance) initModuleArg(&instance->config.localIP); initModuleArg(&instance->config.publicIP); initModuleArg(&instance->config.weather); + initModuleArg(&instance->config.wifi); initModuleArg(&instance->config.player); initModuleArg(&instance->config.song); initModuleArg(&instance->config.dateTime); @@ -441,6 +437,7 @@ static void destroyConfig(FFinstance* instance) destroyModuleArg(&instance->config.localIP); destroyModuleArg(&instance->config.publicIP); destroyModuleArg(&instance->config.weather); + destroyModuleArg(&instance->config.wifi); destroyModuleArg(&instance->config.player); destroyModuleArg(&instance->config.song); destroyModuleArg(&instance->config.dateTime); diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 95518af0f..e588557b2 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -237,6 +237,7 @@ #--locale-key Locale #--local-ip-key Local IP ({1}) #--public-ip-key Public IP +#--wifi-key Wifi #--weather-key Weather #--player-key Media Player #--song-key Song diff --git a/src/detection/wifi/wifi.h b/src/detection/wifi/wifi.h new file mode 100644 index 000000000..39ffa293b --- /dev/null +++ b/src/detection/wifi/wifi.h @@ -0,0 +1,44 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_wifi_wifi +#define FF_INCLUDED_detection_wifi_wifi + +#include "fastfetch.h" + +struct FFWifiInterface +{ + FFstrbuf description; + FFstrbuf status; +}; + +struct FFWifiConnection +{ + FFstrbuf status; + FFstrbuf ssid; + FFstrbuf macAddress; + FFstrbuf phyType; + double signalQuality; // Percentage + double rxRate; + double txRate; +}; + +struct FFWifiSecurity +{ + bool enabled; + bool oneXEnabled; + FFstrbuf authAlgo; + FFstrbuf cipherAlgo; +}; + +typedef struct FFWifiResult +{ + struct FFWifiInterface inf; + struct FFWifiConnection conn; + struct FFWifiSecurity security; + + FFstrbuf error; +} FFWifiResult; + +void ffDetectWifi(const FFinstance* instance, FFWifiResult* result); + +#endif diff --git a/src/detection/wifi/wifi_nosupport.c b/src/detection/wifi/wifi_nosupport.c new file mode 100644 index 000000000..98d82f19b --- /dev/null +++ b/src/detection/wifi/wifi_nosupport.c @@ -0,0 +1,7 @@ +#include "wifi.h" + +void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) +{ + FF_UNUSED(instance); + ffStrbufAppendS(&result->error, "Not supported on this platform"); +} diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c new file mode 100644 index 000000000..3a3ebf404 --- /dev/null +++ b/src/detection/wifi/wifi_windows.c @@ -0,0 +1,242 @@ +#include "wifi.h" +#include "util/windows/unicode.h" + +#include + +static inline void wrapCloseHandle(HANDLE* handle) +{ + if(*handle) + CloseHandle(*handle); +} +static inline void wrapWlanFreeMemory(void* memory) +{ + if(*(void**)memory) + WlanFreeMemory(*(void**)memory); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wswitch" + +static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result) +{ + switch (state) { + case wlan_interface_state_not_ready: + ffStrbufAppendS(result, "Not ready"); + break; + case wlan_interface_state_connected: + ffStrbufAppendS(result, "Connected"); + break; + case wlan_interface_state_ad_hoc_network_formed: + ffStrbufAppendS(result, "First node in a ad hoc network"); + break; + case wlan_interface_state_disconnecting: + ffStrbufAppendS(result, "Disconnecting"); + break; + case wlan_interface_state_disconnected: + ffStrbufAppendS(result, "Not connected"); + break; + case wlan_interface_state_associating: + ffStrbufAppendS(result, "Attempting to associate with a network"); + break; + case wlan_interface_state_discovering: + ffStrbufAppendS(result, "Auto configuration is discovering settings for the network"); + break; + case wlan_interface_state_authenticating: + ffStrbufAppendS(result, "In process of authenticating"); + break; + default: + ffStrbufAppendS(result, "Unknown"); + break; + } +} + +void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) +{ + FF_UNUSED(instance); + + DWORD curVersion; + HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hClient = NULL; + if(WlanOpenHandle(1, NULL, &curVersion, &hClient) != ERROR_SUCCESS) + { + ffStrbufAppendS(&result->error, "WlanOpenHandle() failed"); + return; + } + + WLAN_INTERFACE_INFO_LIST* __attribute__((__cleanup__(wrapWlanFreeMemory))) ifList = NULL; + if(WlanEnumInterfaces(hClient, NULL, &ifList) != ERROR_SUCCESS) + { + ffStrbufAppendS(&result->error, "WlanEnumInterfaces() failed"); + return; + } + + if(ifList->dwNumberOfItems == 0) + { + ffStrbufAppendS(&result->error, "WlanEnumInterfaces() returns empty result"); + return; + } + + WLAN_INTERFACE_INFO* ifInfo = (WLAN_INTERFACE_INFO*)&ifList->InterfaceInfo[0]; + ffStrbufSetWS(&result->inf.description, ifInfo->strInterfaceDescription); + convertIfStateToString(ifInfo->isState, &result->inf.status); + + if(ifInfo->isState != wlan_interface_state_connected) + return; + + WLAN_CONNECTION_ATTRIBUTES* __attribute__((__cleanup__(wrapWlanFreeMemory))) connInfo = NULL; + DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES); + WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid; + + if(WlanQueryInterface(hClient, + &ifInfo->InterfaceGuid, + wlan_intf_opcode_current_connection, + NULL, + &connectInfoSize, + (PVOID*)&connInfo, + &opCode) != ERROR_SUCCESS) + { + ffStrbufAppendS(&result->error, "WlanQueryInterface() failed"); + return; + } + + convertIfStateToString(connInfo->isState, &result->conn.status); + ffStrbufAppendNS(&result->conn.ssid, + connInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength, + (const char *)connInfo->wlanAssociationAttributes.dot11Ssid.ucSSID); + + for (size_t i = 0; i < sizeof(connInfo->wlanAssociationAttributes.dot11Bssid); i++) + ffStrbufAppendF(&result->conn.macAddress, "%.2X-", connInfo->wlanAssociationAttributes.dot11Bssid[i]); + ffStrbufTrimRight(&result->conn.macAddress, '-'); + + switch (connInfo->wlanAssociationAttributes.dot11PhyType) + { + case dot11_phy_type_fhss: + ffStrbufAppendS(&result->conn.phyType, "802.11 (FHSS)"); + break; + case dot11_phy_type_dsss: + ffStrbufAppendS(&result->conn.phyType, "802.11 (DSSS)"); + break; + case dot11_phy_type_irbaseband: + ffStrbufAppendS(&result->conn.phyType, "802.11 (IR)"); + break; + case dot11_phy_type_ofdm: + ffStrbufAppendS(&result->conn.phyType, "802.11a"); + break; + case dot11_phy_type_hrdsss: + ffStrbufAppendS(&result->conn.phyType, "802.11b"); + break; + case dot11_phy_type_erp: + ffStrbufAppendS(&result->conn.phyType, "802.11g"); + break; + case dot11_phy_type_ht: + ffStrbufAppendS(&result->conn.phyType, "802.11n (Wi-Fi 4)"); + break; + case 8 /*dot11_phy_type_vht*/: + ffStrbufAppendS(&result->conn.phyType, "802.11ac (Wi-Fi 5)"); + break; + case 9 /*dot11_phy_type_dmg*/: + ffStrbufAppendS(&result->conn.phyType, "802.11ad (WiGig)"); + break; + case 10 /*dot11_phy_type_he*/: + ffStrbufAppendS(&result->conn.phyType, "802.11ax (Wi-Fi 6)"); + break; + case 11 /*dot11_phy_type_eht*/: + ffStrbufAppendS(&result->conn.phyType, "802.11be (Wi-Fi 7)"); + break; + default: + ffStrbufAppendF(&result->conn.phyType, "Unknown (%u)", (unsigned)connInfo->wlanAssociationAttributes.dot11PhyType); + break; + } + + result->conn.signalQuality = connInfo->wlanAssociationAttributes.wlanSignalQuality; + result->conn.rxRate = connInfo->wlanAssociationAttributes.ulRxRate; + result->conn.txRate = connInfo->wlanAssociationAttributes.ulTxRate; + + result->security.enabled = connInfo->wlanSecurityAttributes.bSecurityEnabled; + result->security.oneXEnabled = connInfo->wlanSecurityAttributes.bOneXEnabled; + switch (connInfo->wlanSecurityAttributes.dot11AuthAlgorithm) + { + case DOT11_AUTH_ALGO_80211_OPEN: + ffStrbufAppendS(&result->security.authAlgo, "802.11 Open"); + break; + case DOT11_AUTH_ALGO_80211_SHARED_KEY: + ffStrbufAppendS(&result->security.authAlgo, "802.11 Shared"); + break; + case DOT11_AUTH_ALGO_WPA: + ffStrbufAppendS(&result->security.authAlgo, "WPA"); + break; + case DOT11_AUTH_ALGO_WPA_PSK: + ffStrbufAppendS(&result->security.authAlgo, "WPA-PSK"); + break; + case DOT11_AUTH_ALGO_WPA_NONE: + ffStrbufAppendS(&result->security.authAlgo, "WPA-None"); + break; + case DOT11_AUTH_ALGO_RSNA: + ffStrbufAppendS(&result->security.authAlgo, "RSNA"); + break; + case DOT11_AUTH_ALGO_RSNA_PSK: + ffStrbufAppendS(&result->security.authAlgo, "RSNA with PSK"); + break; + case 8 /* DOT11_AUTH_ALGO_WPA3 */: + ffStrbufAppendS(&result->security.authAlgo, "WPA3"); + break; + case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */: + ffStrbufAppendS(&result->security.authAlgo, "WPA3-SAE"); + break; + case 10 /* DOT11_AUTH_ALGO_OWE */: + ffStrbufAppendS(&result->security.authAlgo, "OWE"); + break; + case 11 /* DOT11_AUTH_ALGO_WPA3_ENT */: + ffStrbufAppendS(&result->security.authAlgo, "OWE-ENT"); + break; + default: + ffStrbufAppendF(&result->security.authAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11AuthAlgorithm); + break; + } + switch (connInfo->wlanSecurityAttributes.dot11CipherAlgorithm) + { + case DOT11_CIPHER_ALGO_NONE: + ffStrbufAppendS(&result->security.cipherAlgo, "None"); + break; + case DOT11_CIPHER_ALGO_WEP40: + ffStrbufAppendS(&result->security.cipherAlgo, "WEP-40"); + break; + case DOT11_CIPHER_ALGO_TKIP: + ffStrbufAppendS(&result->security.cipherAlgo, "TKIP"); + break; + case DOT11_CIPHER_ALGO_CCMP: + ffStrbufAppendS(&result->security.cipherAlgo, "CCMP"); + break; + case DOT11_CIPHER_ALGO_WEP104: + ffStrbufAppendS(&result->security.cipherAlgo, "WEP-104"); + break; + case 0x06 /* DOT11_CIPHER_ALGO_BIP */: + ffStrbufAppendS(&result->security.cipherAlgo, "BIP-CMAC-128"); + break; + case 0x08 /* DOT11_CIPHER_ALGO_GCMP */: + ffStrbufAppendS(&result->security.cipherAlgo, "GCMP-128"); + break; + case 0x09 /* DOT11_CIPHER_ALGO_GCMP_256 */: + ffStrbufAppendS(&result->security.cipherAlgo, "GCMP-256"); + break; + case 0x0a /* DOT11_CIPHER_ALGO_CCMP_256 */: + ffStrbufAppendS(&result->security.cipherAlgo, "CCMP-256"); + break; + case 0x0b /* DOT11_CIPHER_ALGO_BIP_GMAC_128 */: + ffStrbufAppendS(&result->security.cipherAlgo, "BIP-GMAC-128"); + break; + case 0x0c /* DOT11_CIPHER_ALGO_BIP_GMAC_256 */: + ffStrbufAppendS(&result->security.cipherAlgo, "BIP-GMAC-256"); + break; + case 0x0d /* DOT11_CIPHER_ALGO_BIP_CMAC_256 */: + ffStrbufAppendS(&result->security.cipherAlgo, "BIP-CMAC-256"); + break; + case DOT11_CIPHER_ALGO_WEP: + ffStrbufAppendS(&result->security.cipherAlgo, "WEP"); + break; + default: + ffStrbufAppendF(&result->security.cipherAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11CipherAlgorithm); + break; + } +} + +#pragma GCC diagnostic pop diff --git a/src/fastfetch.c b/src/fastfetch.c index 0db0e3619..2716b92e3 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -350,6 +350,24 @@ static inline void printCommandHelp(const char* command) "Public IP address" ); } + else if(strcasecmp(command, "wifi-format") == 0) + { + constructAndPrintCommandHelpFormat("wifi", "{4} - {6}", 3, + "Interface description", + "Interface status", + "Connection status", + "Connection SSID", + "Connection mac address", + "Connection PHY type", + "Connection signal quality (percentage)", + "Connection RX rate", + "Connection TX rate", + "Security enabled", + "Security 802.1X enabled", + "Security auth algorithm", + "Security cipher algorithm" + ); + } else if(strcasecmp(command, "player-format") == 0) { constructAndPrintCommandHelpFormat("player", "{}", 4, @@ -1041,6 +1059,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else if(optionParseModuleArgs(key, value, "shell", &instance->config.shell)) {} else if(optionParseModuleArgs(key, value, "resolution", &instance->config.resolution)) {} else if(optionParseModuleArgs(key, value, "de", &instance->config.de)) {} + else if(optionParseModuleArgs(key, value, "wifi", &instance->config.wifi)) {} else if(optionParseModuleArgs(key, value, "wm", &instance->config.wm)) {} else if(optionParseModuleArgs(key, value, "wm-theme", &instance->config.wmTheme)) {} else if(optionParseModuleArgs(key, value, "theme", &instance->config.theme)) {} @@ -1310,6 +1329,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char ffPrintLocalIp(instance); else if(strcasecmp(line, "publicip") == 0) ffPrintPublicIp(instance); + else if(strcasecmp(line, "wifi") == 0) + ffPrintWifi(instance); else if(strcasecmp(line, "weather") == 0) ffPrintWeather(instance); else if(strcasecmp(line, "player") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index b4e639edf..36840bb40 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -108,6 +108,7 @@ typedef struct FFconfig FFModuleArgs shell; FFModuleArgs resolution; FFModuleArgs de; + FFModuleArgs wifi; FFModuleArgs wm; FFModuleArgs wmTheme; FFModuleArgs theme; @@ -293,6 +294,7 @@ void ffPrintTime(FFinstance* instance); void ffPrintLocalIp(FFinstance* instance); void ffPrintPublicIp(FFinstance* instance); void ffPrintWeather(FFinstance* instance); +void ffPrintWifi(FFinstance* instance); void ffPrintColors(FFinstance* instance); void ffPrintVulkan(FFinstance* instance); void ffPrintOpenGL(FFinstance* instance); diff --git a/src/flashfetch.c b/src/flashfetch.c index dea96af08..6b961dfa3 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -50,6 +50,7 @@ int main(int argc, char** argv) //ffPrintSong(&instance); //ffPrintLocalIp(&instance); //ffPrintPublicIp(&instance); + //ffPrintWifi(&instance); //ffPrintCPUUsage(&instance); ffPrintLocale(&instance); //ffPrintDateTime(&instance); diff --git a/src/modules/wifi.c b/src/modules/wifi.c new file mode 100644 index 000000000..1e5ddab20 --- /dev/null +++ b/src/modules/wifi.c @@ -0,0 +1,79 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/wifi/wifi.h" + +#define FF_WIFI_MODULE_NAME "Wifi" +#define FF_WIFI_NUM_FORMAT_ARGS 13 + +void ffPrintWifi(FFinstance* instance) +{ + FFWifiResult result; + ffStrbufInit(&result.inf.description); + ffStrbufInit(&result.inf.status); + ffStrbufInit(&result.conn.status); + ffStrbufInit(&result.conn.ssid); + ffStrbufInit(&result.conn.macAddress); + ffStrbufInit(&result.conn.phyType); + result.conn.signalQuality = 0.0/0.0; + result.conn.rxRate = 0.0/0.0; + result.conn.txRate = 0.0/0.0; + result.security.enabled = false; + result.security.oneXEnabled = false; + ffStrbufInit(&result.security.authAlgo); + ffStrbufInit(&result.security.cipherAlgo); + ffStrbufInit(&result.error); + + ffDetectWifi(instance, &result); + + if(!result.error.length) + { + if(instance->config.wifi.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi.key); + if(result.conn.ssid.length) + { + printf("%s - %s", result.conn.ssid.chars, result.conn.phyType.chars); + if(!result.security.enabled) + puts(" - insecure"); + else + putchar('\n'); + } + else + { + puts(result.inf.status.chars); + } + } + else + { + ffPrintFormat(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result.inf.description}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.inf.status}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.status}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.ssid}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.macAddress}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.phyType}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.signalQuality}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.rxRate}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.txRate}, + {FF_FORMAT_ARG_TYPE_BOOL, &result.security.enabled}, + {FF_FORMAT_ARG_TYPE_BOOL, &result.security.oneXEnabled}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.security.authAlgo}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.security.cipherAlgo}, + }); + } + } + else + { + ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wmTheme, "%*s", result.error.length, result.error.chars); + } + + ffStrbufDestroy(&result.inf.description); + ffStrbufDestroy(&result.inf.status); + ffStrbufDestroy(&result.conn.status); + ffStrbufDestroy(&result.conn.ssid); + ffStrbufDestroy(&result.conn.macAddress); + ffStrbufDestroy(&result.conn.phyType); + ffStrbufDestroy(&result.security.authAlgo); + ffStrbufDestroy(&result.security.cipherAlgo); + ffStrbufDestroy(&result.error); +} From 5e5442426cfc5ad9681b77d6905db9b0f03b2033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 27 Nov 2022 16:00:56 +0800 Subject: [PATCH 221/311] Wifi: load wlanapi.dll dynamically Windows Server doesn't support it --- CMakeLists.txt | 1 - README.md | 1 + presets/all | 2 +- src/common/init.c | 2 + src/detection/wifi/wifi_windows.c | 65 ++++++++++++++++++------------- src/fastfetch.c | 2 + src/fastfetch.h | 1 + 7 files changed, 44 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8e732d46..073c07e3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -658,7 +658,6 @@ elseif(WIN32) PRIVATE "setupapi" PRIVATE "dxgi" PRIVATE "wtsapi32" - PRIVATE "wlanapi.lib" ) if(USE_WIN_NTAPI) target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI) diff --git a/README.md b/README.md index c966c4d5d..7774c5c7c 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ The following libraries are used if present at runtime: ### Windows * [`libcJSON`](https://github.com/DaveGamble/cJSON): Used for Windows Terminal font detection. +* [`wlanapi`](https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/): A system dll which isn't supported by Windows Server by default. Used for Wifi info detection. * [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. * [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module diff --git a/presets/all b/presets/all index f68223bb8..ac42d20c6 100644 --- a/presets/all +++ b/presets/all @@ -1 +1 @@ ---structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors +--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors diff --git a/src/common/init.c b/src/common/init.c index 1bb934771..fb3bba75a 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -242,6 +242,7 @@ static void defaultConfig(FFinstance* instance) ffStrbufInitA(&instance->config.libOpenCL, 0); ffStrbufInitA(&instance->config.libcJSON, 0); ffStrbufInitA(&instance->config.libfreetype, 0); + ffStrbufInit(&instance->config.libwlanapi); instance->config.cpuTemp = false; instance->config.gpuTemp = false; @@ -470,6 +471,7 @@ static void destroyConfig(FFinstance* instance) ffStrbufDestroy(&instance->config.libOpenCL); ffStrbufDestroy(&instance->config.libcJSON); ffStrbufDestroy(&instance->config.libfreetype); + ffStrbufDestroy(&instance->config.libwlanapi); ffStrbufDestroy(&instance->config.diskFolders); ffStrbufDestroy(&instance->config.batteryDir); diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c index 3a3ebf404..22a71a9f9 100644 --- a/src/detection/wifi/wifi_windows.c +++ b/src/detection/wifi/wifi_windows.c @@ -1,19 +1,9 @@ #include "wifi.h" +#include "common/library.h" #include "util/windows/unicode.h" #include -static inline void wrapCloseHandle(HANDLE* handle) -{ - if(*handle) - CloseHandle(*handle); -} -static inline void wrapWlanFreeMemory(void* memory) -{ - if(*(void**)memory) - WlanFreeMemory(*(void**)memory); -} - #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" @@ -50,29 +40,37 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result) } } -void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) +static const char* detectWifiImpl(const FFinstance* instance, FFWifiResult* result) { - FF_UNUSED(instance); + FF_LIBRARY_LOAD(wlanapi, &instance->config.libcJSON, "dlopen wlanapi"FF_LIBRARY_EXTENSION" failed", "wlanapi"FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanOpenHandle) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanEnumInterfaces) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanQueryInterface) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanFreeMemory) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanCloseHandle) DWORD curVersion; - HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hClient = NULL; - if(WlanOpenHandle(1, NULL, &curVersion, &hClient) != ERROR_SUCCESS) + HANDLE hClient = NULL; + WLAN_INTERFACE_INFO_LIST* ifList = NULL; + WLAN_CONNECTION_ATTRIBUTES* connInfo = NULL; + const char* error = NULL; + + if(ffWlanOpenHandle(1, NULL, &curVersion, &hClient) != ERROR_SUCCESS) { - ffStrbufAppendS(&result->error, "WlanOpenHandle() failed"); - return; + error = "WlanOpenHandle() failed"; + goto exit; } - WLAN_INTERFACE_INFO_LIST* __attribute__((__cleanup__(wrapWlanFreeMemory))) ifList = NULL; - if(WlanEnumInterfaces(hClient, NULL, &ifList) != ERROR_SUCCESS) + if(ffWlanEnumInterfaces(hClient, NULL, &ifList) != ERROR_SUCCESS) { - ffStrbufAppendS(&result->error, "WlanEnumInterfaces() failed"); - return; + error = "WlanEnumInterfaces() failed"; + goto exit; } if(ifList->dwNumberOfItems == 0) { - ffStrbufAppendS(&result->error, "WlanEnumInterfaces() returns empty result"); - return; + error = "No wifi interfaces found"; + goto exit; } WLAN_INTERFACE_INFO* ifInfo = (WLAN_INTERFACE_INFO*)&ifList->InterfaceInfo[0]; @@ -80,13 +78,12 @@ void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) convertIfStateToString(ifInfo->isState, &result->inf.status); if(ifInfo->isState != wlan_interface_state_connected) - return; + goto exit; - WLAN_CONNECTION_ATTRIBUTES* __attribute__((__cleanup__(wrapWlanFreeMemory))) connInfo = NULL; DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES); WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid; - if(WlanQueryInterface(hClient, + if(ffWlanQueryInterface(hClient, &ifInfo->InterfaceGuid, wlan_intf_opcode_current_connection, NULL, @@ -94,8 +91,8 @@ void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) (PVOID*)&connInfo, &opCode) != ERROR_SUCCESS) { - ffStrbufAppendS(&result->error, "WlanQueryInterface() failed"); - return; + error = "WlanQueryInterface() failed"; + goto exit; } convertIfStateToString(connInfo->isState, &result->conn.status); @@ -237,6 +234,18 @@ void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) ffStrbufAppendF(&result->security.cipherAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11CipherAlgorithm); break; } + +exit: + if(connInfo) ffWlanFreeMemory(connInfo); + if(ifList) ffWlanFreeMemory(ifList); + if(hClient) ffWlanCloseHandle(hClient, NULL); + dlclose(wlanapi); + return error; } #pragma GCC diagnostic pop + +void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) +{ + ffStrbufAppendS(&result->error, detectWifiImpl(instance, result)); +} diff --git a/src/fastfetch.c b/src/fastfetch.c index 2716b92e3..44b492cca 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1141,6 +1141,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.libOpenCL); else if(strcasecmp(subkey, "-cjson") == 0) optionParseString(key, value, &instance->config.libcJSON); + else if(strcasecmp(subkey, "-wlanapi") == 0) + optionParseString(key, value, &instance->config.libwlanapi); else goto error; } diff --git a/src/fastfetch.h b/src/fastfetch.h index 36840bb40..16a80d6b9 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -161,6 +161,7 @@ typedef struct FFconfig FFstrbuf libOpenCL; FFstrbuf libcJSON; FFstrbuf libfreetype; + FFstrbuf libwlanapi; bool cpuTemp; bool gpuTemp; From db33d246cb42ee1c023b89695cda3a3109fb91cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 28 Nov 2022 01:57:45 +0800 Subject: [PATCH 222/311] common/io: improve performance for large files --- src/common/io.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++-- src/common/io.h | 6 +++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/common/io.c b/src/common/io.c index be2cb6afb..0fce38c2c 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -4,7 +4,9 @@ #include #include -#ifndef WIN32 +#ifdef _WIN32 + #include +#else #include #include #endif @@ -38,6 +40,21 @@ bool ffWriteFDBuffer(int fd, const FFstrbuf* content) bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) { + #ifdef _WIN32 + HANDLE handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if(handle == INVALID_HANDLE_VALUE) + { + createSubfolders(fileName); + handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if(handle == INVALID_HANDLE_VALUE) + return false; + } + + DWORD written; + bool ret = !!WriteFile(handle, data, (DWORD)dataSize, &written, NULL); + + CloseHandle(handle); + #else int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC; int openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; @@ -53,6 +70,7 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) bool ret = write(fd, data, dataSize) != -1; close(fd); + #endif return ret; } @@ -62,11 +80,51 @@ bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer) return ffWriteFileData(fileName, buffer->length, buffer->chars); } +#ifdef _WIN32 + +bool ffAppendHandleBuffer(HANDLE handle, FFstrbuf* buffer) +{ + DWORD readed = 0; + + LARGE_INTEGER fileSize; + if(!GetFileSizeEx(handle, &fileSize)) + fileSize.QuadPart = 0; + + ffStrbufEnsureFree(buffer, fileSize.QuadPart > 0 ? (uint32_t)fileSize.QuadPart : 31); + uint32_t free = ffStrbufGetFree(buffer); + + bool success; + while( + (success = !!ReadFile(handle, buffer->chars + buffer->length, free, &readed, NULL)) && + (uint32_t) readed == free + ) { + buffer->length += (uint32_t) readed; + ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte. + free = ffStrbufGetFree(buffer); + } + + if(readed > 0) + buffer->length += (uint32_t) readed; + + buffer->chars[buffer->length] = '\0'; + + ffStrbufTrimRight(buffer, '\n'); + ffStrbufTrimRight(buffer, ' '); + + return success; +} + +#endif + bool ffAppendFDBuffer(int fd, FFstrbuf* buffer) { ssize_t readed = 0; - ffStrbufEnsureFree(buffer, 31); // 32 - 1 for the null terminator + struct stat64 fileInfo; + if(fstat64(fd, &fileInfo) != 0) + return false; + + ffStrbufEnsureFree(buffer, fileInfo.st_size > 0 ? (uint32_t)fileInfo.st_size : 31); uint32_t free = ffStrbufGetFree(buffer); while( @@ -92,6 +150,17 @@ bool ffAppendFDBuffer(int fd, FFstrbuf* buffer) ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data) { + #ifdef _WIN32 + HANDLE handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(handle == INVALID_HANDLE_VALUE) + return false; + + DWORD readed; + if(!ReadFile(handle, data, (DWORD)dataSize, &readed, NULL)) + return -1; + + return (ssize_t)readed; + #else int fd = open(fileName, O_RDONLY); if(fd == -1) return -1; @@ -101,10 +170,20 @@ ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data) close(fd); return readed; + #endif } bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer) { + #ifdef _WIN32 + HANDLE handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(handle == INVALID_HANDLE_VALUE) + return false; + + bool ret = ffAppendHandleBuffer(handle, buffer); + + CloseHandle(handle); + #else int fd = open(fileName, O_RDONLY); if(fd == -1) return false; @@ -112,6 +191,7 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer) bool ret = ffAppendFDBuffer(fd, buffer); close(fd); + #endif return ret; } diff --git a/src/common/io.h b/src/common/io.h index 2c4db8716..b5446f455 100644 --- a/src/common/io.h +++ b/src/common/io.h @@ -5,7 +5,7 @@ #include "fastfetch.h" -#include //mode_t +#include //mode_t, fstat, stat bool ffWriteFDBuffer(int fd, const FFstrbuf* content); bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data); @@ -16,6 +16,10 @@ ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data); bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer); bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer); +#ifdef _WIN32 +bool ffAppendHandleBuffer(HANDLE handle, FFstrbuf* buffer); +#endif + bool ffFileExists(const char* fileName, mode_t mode); // Not thread safe! From 974dc962592d1ddd296ba0ca376526212ccff4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 28 Nov 2022 15:13:47 +0800 Subject: [PATCH 223/311] Wifi: support multiple interfaces --- src/detection/wifi/wifi.h | 4 +- src/detection/wifi/wifi_nosupport.c | 4 +- src/detection/wifi/wifi_windows.c | 315 ++++++++++++++-------------- src/modules/wifi.c | 100 ++++----- 4 files changed, 212 insertions(+), 211 deletions(-) diff --git a/src/detection/wifi/wifi.h b/src/detection/wifi/wifi.h index 39ffa293b..e16c95e7d 100644 --- a/src/detection/wifi/wifi.h +++ b/src/detection/wifi/wifi.h @@ -35,10 +35,8 @@ typedef struct FFWifiResult struct FFWifiInterface inf; struct FFWifiConnection conn; struct FFWifiSecurity security; - - FFstrbuf error; } FFWifiResult; -void ffDetectWifi(const FFinstance* instance, FFWifiResult* result); +const char* ffDetectWifi(const FFinstance* instance, FFlist* result /*list of FFWifiItem*/); #endif diff --git a/src/detection/wifi/wifi_nosupport.c b/src/detection/wifi/wifi_nosupport.c index 98d82f19b..0bfc199d1 100644 --- a/src/detection/wifi/wifi_nosupport.c +++ b/src/detection/wifi/wifi_nosupport.c @@ -1,7 +1,7 @@ #include "wifi.h" -void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) +const char* ffDetectWifi(const FFinstance* instance, FFlist* result) { FF_UNUSED(instance); - ffStrbufAppendS(&result->error, "Not supported on this platform"); + return "Not supported on this platform"; } diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c index 22a71a9f9..4e5dc5e2a 100644 --- a/src/detection/wifi/wifi_windows.c +++ b/src/detection/wifi/wifi_windows.c @@ -40,7 +40,7 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result) } } -static const char* detectWifiImpl(const FFinstance* instance, FFWifiResult* result) +const char* ffDetectWifi(const FFinstance* instance, FFlist* result) { FF_LIBRARY_LOAD(wlanapi, &instance->config.libcJSON, "dlopen wlanapi"FF_LIBRARY_EXTENSION" failed", "wlanapi"FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanOpenHandle) @@ -52,10 +52,9 @@ static const char* detectWifiImpl(const FFinstance* instance, FFWifiResult* resu DWORD curVersion; HANDLE hClient = NULL; WLAN_INTERFACE_INFO_LIST* ifList = NULL; - WLAN_CONNECTION_ATTRIBUTES* connInfo = NULL; const char* error = NULL; - if(ffWlanOpenHandle(1, NULL, &curVersion, &hClient) != ERROR_SUCCESS) + if(ffWlanOpenHandle(2, NULL, &curVersion, &hClient) != ERROR_SUCCESS) { error = "WlanOpenHandle() failed"; goto exit; @@ -73,170 +72,187 @@ static const char* detectWifiImpl(const FFinstance* instance, FFWifiResult* resu goto exit; } - WLAN_INTERFACE_INFO* ifInfo = (WLAN_INTERFACE_INFO*)&ifList->InterfaceInfo[0]; - ffStrbufSetWS(&result->inf.description, ifInfo->strInterfaceDescription); - convertIfStateToString(ifInfo->isState, &result->inf.status); - - if(ifInfo->isState != wlan_interface_state_connected) - goto exit; - - DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES); - WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid; - - if(ffWlanQueryInterface(hClient, - &ifInfo->InterfaceGuid, - wlan_intf_opcode_current_connection, - NULL, - &connectInfoSize, - (PVOID*)&connInfo, - &opCode) != ERROR_SUCCESS) + for(uint32_t index = 0; index < ifList->dwNumberOfItems; ++index) { - error = "WlanQueryInterface() failed"; - goto exit; - } + WLAN_INTERFACE_INFO* ifInfo = (WLAN_INTERFACE_INFO*)&ifList->InterfaceInfo[index]; - convertIfStateToString(connInfo->isState, &result->conn.status); - ffStrbufAppendNS(&result->conn.ssid, - connInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength, - (const char *)connInfo->wlanAssociationAttributes.dot11Ssid.ucSSID); + FFWifiResult* item = (FFWifiResult*)ffListAdd(result); + ffStrbufInit(&item->inf.description); + ffStrbufInit(&item->inf.status); + ffStrbufInit(&item->conn.status); + ffStrbufInit(&item->conn.ssid); + ffStrbufInit(&item->conn.macAddress); + ffStrbufInit(&item->conn.phyType); + item->conn.signalQuality = 0.0/0.0; + item->conn.rxRate = 0.0/0.0; + item->conn.txRate = 0.0/0.0; + item->security.enabled = false; + item->security.oneXEnabled = false; + ffStrbufInit(&item->security.authAlgo); + ffStrbufInit(&item->security.cipherAlgo); - for (size_t i = 0; i < sizeof(connInfo->wlanAssociationAttributes.dot11Bssid); i++) - ffStrbufAppendF(&result->conn.macAddress, "%.2X-", connInfo->wlanAssociationAttributes.dot11Bssid[i]); - ffStrbufTrimRight(&result->conn.macAddress, '-'); + ffStrbufSetWS(&item->inf.description, ifInfo->strInterfaceDescription); + convertIfStateToString(ifInfo->isState, &item->inf.status); - switch (connInfo->wlanAssociationAttributes.dot11PhyType) - { - case dot11_phy_type_fhss: - ffStrbufAppendS(&result->conn.phyType, "802.11 (FHSS)"); + if(ifInfo->isState != wlan_interface_state_connected) + continue; + + DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES); + WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid; + WLAN_CONNECTION_ATTRIBUTES* connInfo = NULL; + + if(ffWlanQueryInterface(hClient, + &ifInfo->InterfaceGuid, + wlan_intf_opcode_current_connection, + NULL, + &connectInfoSize, + (PVOID*)&connInfo, + &opCode) != ERROR_SUCCESS + ) continue; + + convertIfStateToString(connInfo->isState, &item->conn.status); + ffStrbufAppendNS(&item->conn.ssid, + connInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength, + (const char *)connInfo->wlanAssociationAttributes.dot11Ssid.ucSSID); + + for (size_t i = 0; i < sizeof(connInfo->wlanAssociationAttributes.dot11Bssid); i++) + ffStrbufAppendF(&item->conn.macAddress, "%.2X-", connInfo->wlanAssociationAttributes.dot11Bssid[i]); + ffStrbufTrimRight(&item->conn.macAddress, '-'); + + switch (connInfo->wlanAssociationAttributes.dot11PhyType) + { + case dot11_phy_type_fhss: + ffStrbufAppendS(&item->conn.phyType, "802.11 (FHSS)"); + break; + case dot11_phy_type_dsss: + ffStrbufAppendS(&item->conn.phyType, "802.11 (DSSS)"); + break; + case dot11_phy_type_irbaseband: + ffStrbufAppendS(&item->conn.phyType, "802.11 (IR)"); + break; + case dot11_phy_type_ofdm: + ffStrbufAppendS(&item->conn.phyType, "802.11a"); + break; + case dot11_phy_type_hrdsss: + ffStrbufAppendS(&item->conn.phyType, "802.11b"); + break; + case dot11_phy_type_erp: + ffStrbufAppendS(&item->conn.phyType, "802.11g"); + break; + case dot11_phy_type_ht: + ffStrbufAppendS(&item->conn.phyType, "802.11n (Wi-Fi 4)"); + break; + case 8 /*dot11_phy_type_vht*/: + ffStrbufAppendS(&item->conn.phyType, "802.11ac (Wi-Fi 5)"); + break; + case 9 /*dot11_phy_type_dmg*/: + ffStrbufAppendS(&item->conn.phyType, "802.11ad (WiGig)"); + break; + case 10 /*dot11_phy_type_he*/: + ffStrbufAppendS(&item->conn.phyType, "802.11ax (Wi-Fi 6)"); + break; + case 11 /*dot11_phy_type_eht*/: + ffStrbufAppendS(&item->conn.phyType, "802.11be (Wi-Fi 7)"); + break; + default: + ffStrbufAppendF(&item->conn.phyType, "Unknown (%u)", (unsigned)connInfo->wlanAssociationAttributes.dot11PhyType); + break; + } + + item->conn.signalQuality = connInfo->wlanAssociationAttributes.wlanSignalQuality; + item->conn.rxRate = connInfo->wlanAssociationAttributes.ulRxRate; + item->conn.txRate = connInfo->wlanAssociationAttributes.ulTxRate; + + item->security.enabled = connInfo->wlanSecurityAttributes.bSecurityEnabled; + item->security.oneXEnabled = connInfo->wlanSecurityAttributes.bOneXEnabled; + switch (connInfo->wlanSecurityAttributes.dot11AuthAlgorithm) + { + case DOT11_AUTH_ALGO_80211_OPEN: + ffStrbufAppendS(&item->security.authAlgo, "802.11 Open"); + break; + case DOT11_AUTH_ALGO_80211_SHARED_KEY: + ffStrbufAppendS(&item->security.authAlgo, "802.11 Shared"); + break; + case DOT11_AUTH_ALGO_WPA: + ffStrbufAppendS(&item->security.authAlgo, "WPA"); + break; + case DOT11_AUTH_ALGO_WPA_PSK: + ffStrbufAppendS(&item->security.authAlgo, "WPA-PSK"); + break; + case DOT11_AUTH_ALGO_WPA_NONE: + ffStrbufAppendS(&item->security.authAlgo, "WPA-None"); + break; + case DOT11_AUTH_ALGO_RSNA: + ffStrbufAppendS(&item->security.authAlgo, "RSNA"); + break; + case DOT11_AUTH_ALGO_RSNA_PSK: + ffStrbufAppendS(&item->security.authAlgo, "RSNA with PSK"); + break; + case 8 /* DOT11_AUTH_ALGO_WPA3 */: + ffStrbufAppendS(&item->security.authAlgo, "WPA3"); + break; + case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */: + ffStrbufAppendS(&item->security.authAlgo, "WPA3-SAE"); + break; + case 10 /* DOT11_AUTH_ALGO_OWE */: + ffStrbufAppendS(&item->security.authAlgo, "OWE"); + break; + case 11 /* DOT11_AUTH_ALGO_WPA3_ENT */: + ffStrbufAppendS(&item->security.authAlgo, "OWE-ENT"); + break; + default: + ffStrbufAppendF(&item->security.authAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11AuthAlgorithm); + break; + } + switch (connInfo->wlanSecurityAttributes.dot11CipherAlgorithm) + { + case DOT11_CIPHER_ALGO_NONE: + ffStrbufAppendS(&item->security.cipherAlgo, "None"); break; - case dot11_phy_type_dsss: - ffStrbufAppendS(&result->conn.phyType, "802.11 (DSSS)"); + case DOT11_CIPHER_ALGO_WEP40: + ffStrbufAppendS(&item->security.cipherAlgo, "WEP-40"); break; - case dot11_phy_type_irbaseband: - ffStrbufAppendS(&result->conn.phyType, "802.11 (IR)"); + case DOT11_CIPHER_ALGO_TKIP: + ffStrbufAppendS(&item->security.cipherAlgo, "TKIP"); break; - case dot11_phy_type_ofdm: - ffStrbufAppendS(&result->conn.phyType, "802.11a"); + case DOT11_CIPHER_ALGO_CCMP: + ffStrbufAppendS(&item->security.cipherAlgo, "CCMP"); break; - case dot11_phy_type_hrdsss: - ffStrbufAppendS(&result->conn.phyType, "802.11b"); + case DOT11_CIPHER_ALGO_WEP104: + ffStrbufAppendS(&item->security.cipherAlgo, "WEP-104"); break; - case dot11_phy_type_erp: - ffStrbufAppendS(&result->conn.phyType, "802.11g"); + case 0x06 /* DOT11_CIPHER_ALGO_BIP */: + ffStrbufAppendS(&item->security.cipherAlgo, "BIP-CMAC-128"); break; - case dot11_phy_type_ht: - ffStrbufAppendS(&result->conn.phyType, "802.11n (Wi-Fi 4)"); + case 0x08 /* DOT11_CIPHER_ALGO_GCMP */: + ffStrbufAppendS(&item->security.cipherAlgo, "GCMP-128"); break; - case 8 /*dot11_phy_type_vht*/: - ffStrbufAppendS(&result->conn.phyType, "802.11ac (Wi-Fi 5)"); + case 0x09 /* DOT11_CIPHER_ALGO_GCMP_256 */: + ffStrbufAppendS(&item->security.cipherAlgo, "GCMP-256"); break; - case 9 /*dot11_phy_type_dmg*/: - ffStrbufAppendS(&result->conn.phyType, "802.11ad (WiGig)"); + case 0x0a /* DOT11_CIPHER_ALGO_CCMP_256 */: + ffStrbufAppendS(&item->security.cipherAlgo, "CCMP-256"); break; - case 10 /*dot11_phy_type_he*/: - ffStrbufAppendS(&result->conn.phyType, "802.11ax (Wi-Fi 6)"); + case 0x0b /* DOT11_CIPHER_ALGO_BIP_GMAC_128 */: + ffStrbufAppendS(&item->security.cipherAlgo, "BIP-GMAC-128"); break; - case 11 /*dot11_phy_type_eht*/: - ffStrbufAppendS(&result->conn.phyType, "802.11be (Wi-Fi 7)"); + case 0x0c /* DOT11_CIPHER_ALGO_BIP_GMAC_256 */: + ffStrbufAppendS(&item->security.cipherAlgo, "BIP-GMAC-256"); + break; + case 0x0d /* DOT11_CIPHER_ALGO_BIP_CMAC_256 */: + ffStrbufAppendS(&item->security.cipherAlgo, "BIP-CMAC-256"); + break; + case DOT11_CIPHER_ALGO_WEP: + ffStrbufAppendS(&item->security.cipherAlgo, "WEP"); break; default: - ffStrbufAppendF(&result->conn.phyType, "Unknown (%u)", (unsigned)connInfo->wlanAssociationAttributes.dot11PhyType); + ffStrbufAppendF(&item->security.cipherAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11CipherAlgorithm); break; - } - - result->conn.signalQuality = connInfo->wlanAssociationAttributes.wlanSignalQuality; - result->conn.rxRate = connInfo->wlanAssociationAttributes.ulRxRate; - result->conn.txRate = connInfo->wlanAssociationAttributes.ulTxRate; - - result->security.enabled = connInfo->wlanSecurityAttributes.bSecurityEnabled; - result->security.oneXEnabled = connInfo->wlanSecurityAttributes.bOneXEnabled; - switch (connInfo->wlanSecurityAttributes.dot11AuthAlgorithm) - { - case DOT11_AUTH_ALGO_80211_OPEN: - ffStrbufAppendS(&result->security.authAlgo, "802.11 Open"); - break; - case DOT11_AUTH_ALGO_80211_SHARED_KEY: - ffStrbufAppendS(&result->security.authAlgo, "802.11 Shared"); - break; - case DOT11_AUTH_ALGO_WPA: - ffStrbufAppendS(&result->security.authAlgo, "WPA"); - break; - case DOT11_AUTH_ALGO_WPA_PSK: - ffStrbufAppendS(&result->security.authAlgo, "WPA-PSK"); - break; - case DOT11_AUTH_ALGO_WPA_NONE: - ffStrbufAppendS(&result->security.authAlgo, "WPA-None"); - break; - case DOT11_AUTH_ALGO_RSNA: - ffStrbufAppendS(&result->security.authAlgo, "RSNA"); - break; - case DOT11_AUTH_ALGO_RSNA_PSK: - ffStrbufAppendS(&result->security.authAlgo, "RSNA with PSK"); - break; - case 8 /* DOT11_AUTH_ALGO_WPA3 */: - ffStrbufAppendS(&result->security.authAlgo, "WPA3"); - break; - case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */: - ffStrbufAppendS(&result->security.authAlgo, "WPA3-SAE"); - break; - case 10 /* DOT11_AUTH_ALGO_OWE */: - ffStrbufAppendS(&result->security.authAlgo, "OWE"); - break; - case 11 /* DOT11_AUTH_ALGO_WPA3_ENT */: - ffStrbufAppendS(&result->security.authAlgo, "OWE-ENT"); - break; - default: - ffStrbufAppendF(&result->security.authAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11AuthAlgorithm); - break; - } - switch (connInfo->wlanSecurityAttributes.dot11CipherAlgorithm) - { - case DOT11_CIPHER_ALGO_NONE: - ffStrbufAppendS(&result->security.cipherAlgo, "None"); - break; - case DOT11_CIPHER_ALGO_WEP40: - ffStrbufAppendS(&result->security.cipherAlgo, "WEP-40"); - break; - case DOT11_CIPHER_ALGO_TKIP: - ffStrbufAppendS(&result->security.cipherAlgo, "TKIP"); - break; - case DOT11_CIPHER_ALGO_CCMP: - ffStrbufAppendS(&result->security.cipherAlgo, "CCMP"); - break; - case DOT11_CIPHER_ALGO_WEP104: - ffStrbufAppendS(&result->security.cipherAlgo, "WEP-104"); - break; - case 0x06 /* DOT11_CIPHER_ALGO_BIP */: - ffStrbufAppendS(&result->security.cipherAlgo, "BIP-CMAC-128"); - break; - case 0x08 /* DOT11_CIPHER_ALGO_GCMP */: - ffStrbufAppendS(&result->security.cipherAlgo, "GCMP-128"); - break; - case 0x09 /* DOT11_CIPHER_ALGO_GCMP_256 */: - ffStrbufAppendS(&result->security.cipherAlgo, "GCMP-256"); - break; - case 0x0a /* DOT11_CIPHER_ALGO_CCMP_256 */: - ffStrbufAppendS(&result->security.cipherAlgo, "CCMP-256"); - break; - case 0x0b /* DOT11_CIPHER_ALGO_BIP_GMAC_128 */: - ffStrbufAppendS(&result->security.cipherAlgo, "BIP-GMAC-128"); - break; - case 0x0c /* DOT11_CIPHER_ALGO_BIP_GMAC_256 */: - ffStrbufAppendS(&result->security.cipherAlgo, "BIP-GMAC-256"); - break; - case 0x0d /* DOT11_CIPHER_ALGO_BIP_CMAC_256 */: - ffStrbufAppendS(&result->security.cipherAlgo, "BIP-CMAC-256"); - break; - case DOT11_CIPHER_ALGO_WEP: - ffStrbufAppendS(&result->security.cipherAlgo, "WEP"); - break; - default: - ffStrbufAppendF(&result->security.cipherAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11CipherAlgorithm); - break; + } + ffWlanFreeMemory(connInfo); } exit: - if(connInfo) ffWlanFreeMemory(connInfo); if(ifList) ffWlanFreeMemory(ifList); if(hClient) ffWlanCloseHandle(hClient, NULL); dlclose(wlanapi); @@ -244,8 +260,3 @@ exit: } #pragma GCC diagnostic pop - -void ffDetectWifi(const FFinstance* instance, FFWifiResult* result) -{ - ffStrbufAppendS(&result->error, detectWifiImpl(instance, result)); -} diff --git a/src/modules/wifi.c b/src/modules/wifi.c index 1e5ddab20..7f075d4b4 100644 --- a/src/modules/wifi.c +++ b/src/modules/wifi.c @@ -7,73 +7,65 @@ void ffPrintWifi(FFinstance* instance) { - FFWifiResult result; - ffStrbufInit(&result.inf.description); - ffStrbufInit(&result.inf.status); - ffStrbufInit(&result.conn.status); - ffStrbufInit(&result.conn.ssid); - ffStrbufInit(&result.conn.macAddress); - ffStrbufInit(&result.conn.phyType); - result.conn.signalQuality = 0.0/0.0; - result.conn.rxRate = 0.0/0.0; - result.conn.txRate = 0.0/0.0; - result.security.enabled = false; - result.security.oneXEnabled = false; - ffStrbufInit(&result.security.authAlgo); - ffStrbufInit(&result.security.cipherAlgo); - ffStrbufInit(&result.error); + FFlist result; + ffListInit(&result, sizeof(FFWifiResult)); - ffDetectWifi(instance, &result); + const char* error = ffDetectWifi(instance, &result); - if(!result.error.length) + if(!error) { - if(instance->config.wifi.outputFormat.length == 0) + for(uint32_t index = 0; index < result.length; ++index) { - ffPrintLogoAndKey(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi.key); - if(result.conn.ssid.length) + FFWifiResult* item = (FFWifiResult*)ffListGet(&result, index); + uint8_t moduleIndex = result.length == 1 ? 0 : (uint8_t)(index + 1); + + if(instance->config.wifi.outputFormat.length == 0) { - printf("%s - %s", result.conn.ssid.chars, result.conn.phyType.chars); - if(!result.security.enabled) - puts(" - insecure"); + ffPrintLogoAndKey(instance, FF_WIFI_MODULE_NAME, moduleIndex, &instance->config.wifi.key); + if(item->conn.ssid.length) + { + printf("%s - %s", item->conn.ssid.chars, item->conn.phyType.chars); + if(!item->security.enabled) + puts(" - insecure"); + else + putchar('\n'); + } else - putchar('\n'); + { + puts(item->inf.status.chars); + } } else { - puts(result.inf.status.chars); + ffPrintFormat(instance, FF_WIFI_MODULE_NAME, moduleIndex, &instance->config.wifi, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.description}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.status}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.status}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.ssid}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.macAddress}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.phyType}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.signalQuality}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.rxRate}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.txRate}, + {FF_FORMAT_ARG_TYPE_BOOL, &item->security.enabled}, + {FF_FORMAT_ARG_TYPE_BOOL, &item->security.oneXEnabled}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->security.authAlgo}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->security.cipherAlgo}, + }); } - } - else - { - ffPrintFormat(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result.inf.description}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.inf.status}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.status}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.ssid}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.macAddress}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.phyType}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.signalQuality}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.rxRate}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.txRate}, - {FF_FORMAT_ARG_TYPE_BOOL, &result.security.enabled}, - {FF_FORMAT_ARG_TYPE_BOOL, &result.security.oneXEnabled}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.security.authAlgo}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.security.cipherAlgo}, - }); + + ffStrbufDestroy(&item->inf.description); + ffStrbufDestroy(&item->inf.status); + ffStrbufDestroy(&item->conn.status); + ffStrbufDestroy(&item->conn.ssid); + ffStrbufDestroy(&item->conn.macAddress); + ffStrbufDestroy(&item->conn.phyType); + ffStrbufDestroy(&item->security.authAlgo); + ffStrbufDestroy(&item->security.cipherAlgo); } } else { - ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wmTheme, "%*s", result.error.length, result.error.chars); + ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wmTheme, "%s", error); } - - ffStrbufDestroy(&result.inf.description); - ffStrbufDestroy(&result.inf.status); - ffStrbufDestroy(&result.conn.status); - ffStrbufDestroy(&result.conn.ssid); - ffStrbufDestroy(&result.conn.macAddress); - ffStrbufDestroy(&result.conn.phyType); - ffStrbufDestroy(&result.security.authAlgo); - ffStrbufDestroy(&result.security.cipherAlgo); - ffStrbufDestroy(&result.error); } From 57b794cbd9db318d27c4e44ec2eb6e9608e46a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 28 Nov 2022 16:29:51 +0800 Subject: [PATCH 224/311] macOS: fix build --- src/common/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/io.c b/src/common/io.c index 0fce38c2c..1c2fb918b 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -120,8 +120,8 @@ bool ffAppendFDBuffer(int fd, FFstrbuf* buffer) { ssize_t readed = 0; - struct stat64 fileInfo; - if(fstat64(fd, &fileInfo) != 0) + struct stat fileInfo; + if(fstat(fd, &fileInfo) != 0) return false; ffStrbufEnsureFree(buffer, fileInfo.st_size > 0 ? (uint32_t)fileInfo.st_size : 31); From b3e635a923f25d1df01726ef981065ce657f48c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 28 Nov 2022 16:34:56 +0800 Subject: [PATCH 225/311] Wifi: support macOS --- CMakeLists.txt | 3 +- src/detection/wifi/wifi.h | 3 +- src/detection/wifi/wifi_apple.m | 132 ++++++++++++++++++++++++++++++ src/detection/wifi/wifi_windows.c | 56 ++++++------- src/fastfetch.c | 3 +- src/modules/wifi.c | 8 +- 6 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 src/detection/wifi/wifi_apple.m diff --git a/CMakeLists.txt b/CMakeLists.txt index 073c07e3c..a2049b950 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -437,7 +437,7 @@ elseif(APPLE) src/detection/terminalshell/terminalshell_linux.c src/detection/uptime/uptime_bsd.c src/detection/users/users_linux.c - src/detection/wifi/wifi_nosupport.c + src/detection/wifi/wifi_apple.m src/detection/wmtheme/wmtheme_apple.m src/util/apple/cf_helpers.c src/util/apple/osascript.m @@ -641,6 +641,7 @@ if(APPLE) PRIVATE "-framework OpenGL" PRIVATE "-framework OpenCL" PRIVATE "-framework Cocoa" + PRIVATE "-framework CoreWLAN" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" ) elseif(WIN32) diff --git a/src/detection/wifi/wifi.h b/src/detection/wifi/wifi.h index e16c95e7d..375299a76 100644 --- a/src/detection/wifi/wifi.h +++ b/src/detection/wifi/wifi.h @@ -26,8 +26,7 @@ struct FFWifiSecurity { bool enabled; bool oneXEnabled; - FFstrbuf authAlgo; - FFstrbuf cipherAlgo; + FFstrbuf algorithm; }; typedef struct FFWifiResult diff --git a/src/detection/wifi/wifi_apple.m b/src/detection/wifi/wifi_apple.m new file mode 100644 index 000000000..8d96778f1 --- /dev/null +++ b/src/detection/wifi/wifi_apple.m @@ -0,0 +1,132 @@ +#include "wifi.h" + +#import + +const char* ffDetectWifi(const FFinstance* instance, FFlist* result) +{ + FF_UNUSED(instance); + + NSArray* interfaces = CWWiFiClient.sharedWiFiClient.interfaces; + if(!interfaces) + return "CWWiFiClient.sharedWiFiClient.interfaces is nil"; + + if(interfaces.count == 0) + return "No wifi interfaces found"; + + for(CWInterface* inf in interfaces) + { + FFWifiResult* item = (FFWifiResult*)ffListAdd(result); + ffStrbufInit(&item->inf.description); + ffStrbufInit(&item->inf.status); + ffStrbufInit(&item->conn.status); + ffStrbufInit(&item->conn.ssid); + ffStrbufInit(&item->conn.macAddress); + ffStrbufInit(&item->conn.phyType); + item->conn.signalQuality = 0.0/0.0; + item->conn.rxRate = 0.0/0.0; + item->conn.txRate = 0.0/0.0; + item->security.enabled = false; + item->security.oneXEnabled = false; + ffStrbufInit(&item->security.algorithm); + + ffStrbufAppendS(&item->inf.description, inf.interfaceName.UTF8String); + ffStrbufAppendS(&item->inf.status, inf.powerOn ? "Power On" : "Power Off"); + if(!inf.powerOn) + continue; + + ffStrbufAppendS(&item->conn.status, inf.serviceActive ? "Active" : "Inactive"); + if(!inf.serviceActive) + continue; + + ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String); + ffStrbufAppendS(&item->conn.macAddress, inf.hardwareAddress.UTF8String); + switch(inf.activePHYMode) + { + case kCWPHYModeNone: + ffStrbufAppendS(&item->conn.phyType, "none"); + break; + case kCWPHYMode11a: + ffStrbufAppendS(&item->conn.phyType, "802.11a"); + break; + case kCWPHYMode11b: + ffStrbufAppendS(&item->conn.phyType, "802.11b"); + break; + case kCWPHYMode11g: + ffStrbufAppendS(&item->conn.phyType, "802.11g"); + break; + case kCWPHYMode11n: + ffStrbufAppendS(&item->conn.phyType, "802.11n (Wi-Fi 4)"); + break; + case kCWPHYMode11ac: + ffStrbufAppendS(&item->conn.phyType, "802.11ac (Wi-Fi 5)"); + break; + case kCWPHYMode11ax: + ffStrbufAppendS(&item->conn.phyType, "802.11ax (Wi-Fi 6)"); + break; + case 7 /*kCWPHYMode11be?*/: + ffStrbufAppendS(&item->conn.phyType, "802.11be (Wi-Fi 7)"); + break; + default: + ffStrbufAppendF(&item->conn.phyType, "Unknown (%ld)", inf.activePHYMode); + break; + } + item->conn.signalQuality = inf.rssiValue >= -50 ? 100 : inf.rssiValue <= -100 ? 0 : (inf.rssiValue + 100) * 2; + item->conn.txRate = inf.transmitRate; + item->security.enabled = inf.security != kCWSecurityNone; + switch(inf.security) + { + case kCWSecurityNone: + ffStrbufAppendS(&item->security.algorithm, "None"); + break; + case kCWSecurityWEP: + ffStrbufAppendS(&item->security.algorithm, "WEP"); + break; + case kCWSecurityWPAPersonal: + ffStrbufAppendS(&item->security.algorithm, "WPA Personal"); + break; + case kCWSecurityWPAPersonalMixed: + ffStrbufAppendS(&item->security.algorithm, "WPA Persional Mixed"); + break; + case kCWSecurityWPA2Personal: + ffStrbufAppendS(&item->security.algorithm, "WPA2 Personal"); + break; + case kCWSecurityPersonal: + ffStrbufAppendS(&item->security.algorithm, "Personal"); + break; + case kCWSecurityDynamicWEP: + ffStrbufAppendS(&item->security.algorithm, "Dynamic WEP"); + break; + case kCWSecurityWPAEnterprise: + ffStrbufAppendS(&item->security.algorithm, "WPA Enterprise"); + break; + case kCWSecurityWPAEnterpriseMixed: + ffStrbufAppendS(&item->security.algorithm, "WPA Enterprise Mixed"); + break; + case kCWSecurityWPA2Enterprise: + ffStrbufAppendS(&item->security.algorithm, "WPA2 Enterprise"); + break; + case kCWSecurityEnterprise: + ffStrbufAppendS(&item->security.algorithm, "Enterprise"); + break; + case kCWSecurityWPA3Personal: + ffStrbufAppendS(&item->security.algorithm, "WPA3 Personal"); + break; + case kCWSecurityWPA3Enterprise: + ffStrbufAppendS(&item->security.algorithm, "WPA3 Enterprise"); + break; + case kCWSecurityWPA3Transition: + ffStrbufAppendS(&item->security.algorithm, "WPA3 Transition"); + break; + case 14 /*kCWSecurityOWE*/: + ffStrbufAppendS(&item->security.algorithm, "OWE"); + break; + case 15 /*kCWSecurityOWETransition*/: + ffStrbufAppendS(&item->security.algorithm, "OWE Transition"); + break; + default: + ffStrbufAppendF(&item->security.algorithm, "Unknown (%ld)", inf.security); + break; + } + } + return NULL; +} diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c index 4e5dc5e2a..f113197f5 100644 --- a/src/detection/wifi/wifi_windows.c +++ b/src/detection/wifi/wifi_windows.c @@ -88,8 +88,7 @@ const char* ffDetectWifi(const FFinstance* instance, FFlist* result) item->conn.txRate = 0.0/0.0; item->security.enabled = false; item->security.oneXEnabled = false; - ffStrbufInit(&item->security.authAlgo); - ffStrbufInit(&item->security.cipherAlgo); + ffStrbufInit(&item->security.algorithm); ffStrbufSetWS(&item->inf.description, ifInfo->strInterfaceDescription); convertIfStateToString(ifInfo->isState, &item->inf.status); @@ -168,85 +167,86 @@ const char* ffDetectWifi(const FFinstance* instance, FFlist* result) switch (connInfo->wlanSecurityAttributes.dot11AuthAlgorithm) { case DOT11_AUTH_ALGO_80211_OPEN: - ffStrbufAppendS(&item->security.authAlgo, "802.11 Open"); + ffStrbufAppendS(&item->security.algorithm, "802.11 Open"); break; case DOT11_AUTH_ALGO_80211_SHARED_KEY: - ffStrbufAppendS(&item->security.authAlgo, "802.11 Shared"); + ffStrbufAppendS(&item->security.algorithm, "802.11 Shared"); break; case DOT11_AUTH_ALGO_WPA: - ffStrbufAppendS(&item->security.authAlgo, "WPA"); + ffStrbufAppendS(&item->security.algorithm, "WPA"); break; case DOT11_AUTH_ALGO_WPA_PSK: - ffStrbufAppendS(&item->security.authAlgo, "WPA-PSK"); + ffStrbufAppendS(&item->security.algorithm, "WPA-PSK"); break; case DOT11_AUTH_ALGO_WPA_NONE: - ffStrbufAppendS(&item->security.authAlgo, "WPA-None"); + ffStrbufAppendS(&item->security.algorithm, "WPA-None"); break; case DOT11_AUTH_ALGO_RSNA: - ffStrbufAppendS(&item->security.authAlgo, "RSNA"); + ffStrbufAppendS(&item->security.algorithm, "RSNA"); break; case DOT11_AUTH_ALGO_RSNA_PSK: - ffStrbufAppendS(&item->security.authAlgo, "RSNA with PSK"); + ffStrbufAppendS(&item->security.algorithm, "RSNA with PSK"); break; case 8 /* DOT11_AUTH_ALGO_WPA3 */: - ffStrbufAppendS(&item->security.authAlgo, "WPA3"); + ffStrbufAppendS(&item->security.algorithm, "WPA3"); break; case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */: - ffStrbufAppendS(&item->security.authAlgo, "WPA3-SAE"); + ffStrbufAppendS(&item->security.algorithm, "WPA3-SAE"); break; case 10 /* DOT11_AUTH_ALGO_OWE */: - ffStrbufAppendS(&item->security.authAlgo, "OWE"); + ffStrbufAppendS(&item->security.algorithm, "OWE"); break; case 11 /* DOT11_AUTH_ALGO_WPA3_ENT */: - ffStrbufAppendS(&item->security.authAlgo, "OWE-ENT"); + ffStrbufAppendS(&item->security.algorithm, "OWE-ENT"); break; default: - ffStrbufAppendF(&item->security.authAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11AuthAlgorithm); + ffStrbufAppendF(&item->security.algorithm, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11AuthAlgorithm); break; } + ffStrbufAppendS(&item->security.algorithm, " - "); switch (connInfo->wlanSecurityAttributes.dot11CipherAlgorithm) { case DOT11_CIPHER_ALGO_NONE: - ffStrbufAppendS(&item->security.cipherAlgo, "None"); + ffStrbufAppendS(&item->security.algorithm, "None"); break; case DOT11_CIPHER_ALGO_WEP40: - ffStrbufAppendS(&item->security.cipherAlgo, "WEP-40"); + ffStrbufAppendS(&item->security.algorithm, "WEP-40"); break; case DOT11_CIPHER_ALGO_TKIP: - ffStrbufAppendS(&item->security.cipherAlgo, "TKIP"); + ffStrbufAppendS(&item->security.algorithm, "TKIP"); break; case DOT11_CIPHER_ALGO_CCMP: - ffStrbufAppendS(&item->security.cipherAlgo, "CCMP"); + ffStrbufAppendS(&item->security.algorithm, "CCMP"); break; case DOT11_CIPHER_ALGO_WEP104: - ffStrbufAppendS(&item->security.cipherAlgo, "WEP-104"); + ffStrbufAppendS(&item->security.algorithm, "WEP-104"); break; case 0x06 /* DOT11_CIPHER_ALGO_BIP */: - ffStrbufAppendS(&item->security.cipherAlgo, "BIP-CMAC-128"); + ffStrbufAppendS(&item->security.algorithm, "BIP-CMAC-128"); break; case 0x08 /* DOT11_CIPHER_ALGO_GCMP */: - ffStrbufAppendS(&item->security.cipherAlgo, "GCMP-128"); + ffStrbufAppendS(&item->security.algorithm, "GCMP-128"); break; case 0x09 /* DOT11_CIPHER_ALGO_GCMP_256 */: - ffStrbufAppendS(&item->security.cipherAlgo, "GCMP-256"); + ffStrbufAppendS(&item->security.algorithm, "GCMP-256"); break; case 0x0a /* DOT11_CIPHER_ALGO_CCMP_256 */: - ffStrbufAppendS(&item->security.cipherAlgo, "CCMP-256"); + ffStrbufAppendS(&item->security.algorithm, "CCMP-256"); break; case 0x0b /* DOT11_CIPHER_ALGO_BIP_GMAC_128 */: - ffStrbufAppendS(&item->security.cipherAlgo, "BIP-GMAC-128"); + ffStrbufAppendS(&item->security.algorithm, "BIP-GMAC-128"); break; case 0x0c /* DOT11_CIPHER_ALGO_BIP_GMAC_256 */: - ffStrbufAppendS(&item->security.cipherAlgo, "BIP-GMAC-256"); + ffStrbufAppendS(&item->security.algorithm, "BIP-GMAC-256"); break; case 0x0d /* DOT11_CIPHER_ALGO_BIP_CMAC_256 */: - ffStrbufAppendS(&item->security.cipherAlgo, "BIP-CMAC-256"); + ffStrbufAppendS(&item->security.algorithm, "BIP-CMAC-256"); break; case DOT11_CIPHER_ALGO_WEP: - ffStrbufAppendS(&item->security.cipherAlgo, "WEP"); + ffStrbufAppendS(&item->security.algorithm, "WEP"); break; default: - ffStrbufAppendF(&item->security.cipherAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11CipherAlgorithm); + ffStrbufAppendF(&item->security.algorithm, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11CipherAlgorithm); break; } ffWlanFreeMemory(connInfo); diff --git a/src/fastfetch.c b/src/fastfetch.c index 44b492cca..f0815cae4 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -364,8 +364,7 @@ static inline void printCommandHelp(const char* command) "Connection TX rate", "Security enabled", "Security 802.1X enabled", - "Security auth algorithm", - "Security cipher algorithm" + "Security algorithm" ); } else if(strcasecmp(command, "player-format") == 0) diff --git a/src/modules/wifi.c b/src/modules/wifi.c index 7f075d4b4..596c18baa 100644 --- a/src/modules/wifi.c +++ b/src/modules/wifi.c @@ -3,7 +3,7 @@ #include "detection/wifi/wifi.h" #define FF_WIFI_MODULE_NAME "Wifi" -#define FF_WIFI_NUM_FORMAT_ARGS 13 +#define FF_WIFI_NUM_FORMAT_ARGS 12 void ffPrintWifi(FFinstance* instance) { @@ -49,8 +49,7 @@ void ffPrintWifi(FFinstance* instance) {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.txRate}, {FF_FORMAT_ARG_TYPE_BOOL, &item->security.enabled}, {FF_FORMAT_ARG_TYPE_BOOL, &item->security.oneXEnabled}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->security.authAlgo}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->security.cipherAlgo}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->security.algorithm}, }); } @@ -60,8 +59,7 @@ void ffPrintWifi(FFinstance* instance) ffStrbufDestroy(&item->conn.ssid); ffStrbufDestroy(&item->conn.macAddress); ffStrbufDestroy(&item->conn.phyType); - ffStrbufDestroy(&item->security.authAlgo); - ffStrbufDestroy(&item->security.cipherAlgo); + ffStrbufDestroy(&item->security.algorithm); } } else From 7991abab0b072f84e503c7899e5d764c787d9523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 1 Dec 2022 17:45:17 +0800 Subject: [PATCH 226/311] TerminalFont: support deepin-terminal --- README.md | 2 +- .../terminalfont/terminalfont_linux.c | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7774c5c7c..7a656d598 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt ##### Terminal fonts ``` -Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu +Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, Deepin Terminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu ``` ## Building diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index e63ccd815..28128ad3f 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -140,6 +140,55 @@ static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* ffStrbufDestroy(&useSysFont); } +static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + FFstrbuf fontName; + ffStrbufInit(&fontName); + + FFstrbuf fontSize; + ffStrbufInit(&fontSize); + + FFstrbuf profile; + ffStrbufInitF(&profile, "%s/.config/deepin/deepin-terminal/config.conf", instance->state.passwd->pw_dir); + FILE* file = fopen(profile.chars, "r"); + + if(file) + { + char* line = NULL; + size_t len = 0; + + for(int count = 0; getline(&line, &len, file) != -1 && count < 2;) + { + if(strcmp(line, "[basic.interface.font]\n") == 0) + { + if(getline(&line, &len, file) != -1) + ffParsePropLine(line, "value=", &fontName); + ++count; + } + else if(strcmp(line, "[basic.interface.font_size]\n") == 0) + { + if(getline(&line, &len, file) != -1) + ffParsePropLine(line, "value=", &fontSize); + ++count; + } + } + + fclose(file); + } + + ffStrbufDestroy(&profile); + + if(fontName.length == 0) + ffStrbufAppendS(&fontName, "Noto Sans Mono"); + if(fontSize.length == 0) + ffStrbufAppendS(&fontSize, "11"); + + ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&fontSize); +} + void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0) @@ -152,4 +201,6 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "gnome-terminal-") == 0) detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "deepin-terminal") == 0) + detectDeepinTerminal(instance, terminalFont); } From 0cad657ce22de7d192e3cdbde4d81b41fd0fb954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 01:01:17 +0800 Subject: [PATCH 227/311] Swap: correct implementation (Windows) --- CMakeLists.txt | 2 +- src/detection/swap/swap_windows.c | 11 ----- src/detection/swap/swap_windows.cpp | 64 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 12 deletions(-) delete mode 100644 src/detection/swap/swap_windows.c create mode 100644 src/detection/swap/swap_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a2049b950..bb119b853 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -465,7 +465,7 @@ elseif(WIN32) src/detection/packages/packages_windows.c src/detection/poweradapter/poweradapter_nosupport.c src/detection/processes/processes_windows.cpp - src/detection/swap/swap_windows.c + src/detection/swap/swap_windows.cpp src/detection/terminalfont/terminalfont_windows.c src/detection/terminalshell/terminalshell_windows.cpp src/detection/uptime/uptime_windows.c diff --git a/src/detection/swap/swap_windows.c b/src/detection/swap/swap_windows.c deleted file mode 100644 index 9fc1d86a4..000000000 --- a/src/detection/swap/swap_windows.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "swap.h" - -void ffDetectSwapImpl(FFMemoryStorage* swap) -{ - MEMORYSTATUSEX statex = { - .dwLength = sizeof(statex), - }; - GlobalMemoryStatusEx(&statex); - swap->bytesTotal = statex.ullTotalPageFile; - swap->bytesUsed = statex.ullTotalPageFile - statex.ullAvailPageFile; -} diff --git a/src/detection/swap/swap_windows.cpp b/src/detection/swap/swap_windows.cpp new file mode 100644 index 000000000..5e7597602 --- /dev/null +++ b/src/detection/swap/swap_windows.cpp @@ -0,0 +1,64 @@ +extern "C" { +#include "swap.h" +#include "util/mallocHelper.h" +} + +#ifdef FF_USE_WIN_NTAPI + +#include +#include + +extern "C" +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + SYSTEM_INFO sysInfo; + GetNativeSystemInfo(&sysInfo); + + ULONG size = sizeof(SYSTEM_PAGEFILE_INFORMATION); + SYSTEM_PAGEFILE_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PAGEFILE_INFORMATION*)malloc(size); + while(true) + { + NTSTATUS status = NtQuerySystemInformation(SystemPagefileInformation, pstart, size, &size); + if(status == STATUS_INFO_LENGTH_MISMATCH) + { + if(!(pstart = (SYSTEM_PAGEFILE_INFORMATION*)realloc(pstart, size))) + { + ffStrbufAppendF(&swap->error, "relloc(pstart, %lu) failed", size); + return; + } + } + else if(!NT_SUCCESS(status)) + { + ffStrbufAppendF(&swap->error, "NtQuerySystemInformation(SystemPagefileInformation, %lu) failed", size); + return; + } + break; + } + swap->bytesUsed = (uint64_t)pstart->TotalUsed * sysInfo.dwPageSize; + swap->bytesTotal = (uint64_t)pstart->CurrentSize * sysInfo.dwPageSize; +} + +#else + +#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"); +} + +#endif From be698bd806d1064e4bea65752a16c897977c61a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 01:01:48 +0800 Subject: [PATCH 228/311] Processes: don't hard code magic numbers (Windows) --- src/detection/processes/processes_windows.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp index 2b267c4a5..860ee8998 100644 --- a/src/detection/processes/processes_windows.cpp +++ b/src/detection/processes/processes_windows.cpp @@ -5,6 +5,7 @@ extern "C" { #ifdef FF_USE_WIN_NTAPI +#include #include uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) @@ -12,7 +13,7 @@ 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*/) + if(NtQuerySystemInformation(SystemProcessInformation, nullptr, 0, &size) != STATUS_INFO_LENGTH_MISMATCH) { ffStrbufAppendS(error, "NtQuerySystemInformation(SystemProcessInformation, NULL) failed"); return 0; From 1dc578badb45d67bb34f940115868cdfca7aab1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 01:20:06 +0800 Subject: [PATCH 229/311] Wifi: silence warnings --- src/detection/wifi/wifi_nosupport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/wifi/wifi_nosupport.c b/src/detection/wifi/wifi_nosupport.c index 0bfc199d1..d09116c9b 100644 --- a/src/detection/wifi/wifi_nosupport.c +++ b/src/detection/wifi/wifi_nosupport.c @@ -2,6 +2,6 @@ const char* ffDetectWifi(const FFinstance* instance, FFlist* result) { - FF_UNUSED(instance); + FF_UNUSED(instance, result); return "Not supported on this platform"; } From 15a98a83cd7b0ceea750426a323ebde0f3abe7d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 11:29:33 +0800 Subject: [PATCH 230/311] Linux: fix some memleaks --- src/detection/displayserver/linux/xlib.c | 16 ++++++++++------ src/detection/opengl/opengl_linux.c | 6 +++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/detection/displayserver/linux/xlib.c b/src/detection/displayserver/linux/xlib.c index 2cdc91d3c..b0748bde8 100644 --- a/src/detection/displayserver/linux/xlib.c +++ b/src/detection/displayserver/linux/xlib.c @@ -9,12 +9,14 @@ typedef struct X11PropertyData { FF_LIBRARY_SYMBOL(XInternAtom) FF_LIBRARY_SYMBOL(XGetWindowProperty) + FF_LIBRARY_SYMBOL(XFree) } X11PropertyData; static bool x11InitPropertyData(void* libraryHandle, X11PropertyData* propertyData) { FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XInternAtom, false) FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XGetWindowProperty, false) + FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XFree, false) return true; } @@ -29,7 +31,8 @@ static unsigned char* x11GetProperty(X11PropertyData* data, Display* display, Wi unsigned long unused; unsigned char* result = NULL; - data->ffXGetWindowProperty(display, window, requestAtom, 0, 64, False, AnyPropertyType, &actualType, (int*) &unused, &unused, &unused, &result); + if(data->ffXGetWindowProperty(display, window, requestAtom, 0, 64, False, AnyPropertyType, &actualType, (int*) &unused, &unused, &unused, &result) != Success) + return NULL; return result; } @@ -43,14 +46,15 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl if(wmWindow == NULL) return; - const char* wmName = (const char*) x11GetProperty(data, display, *wmWindow, "_NET_WM_NAME"); + char* wmName = (char*) x11GetProperty(data, display, *wmWindow, "_NET_WM_NAME"); if(wmName == NULL) - wmName = (const char*) x11GetProperty(data, display, *wmWindow, "WM_NAME"); + wmName = (char*) x11GetProperty(data, display, *wmWindow, "WM_NAME"); - if(!ffStrSet(wmName)) - return; + if(ffStrSet(wmName)) + ffStrbufSetS(&result->wmProcessName, wmName); - ffStrbufSetS(&result->wmProcessName, wmName); + data->ffXFree(wmName); + data->ffXFree(wmWindow); } void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) diff --git a/src/detection/opengl/opengl_linux.c b/src/detection/opengl/opengl_linux.c index 6e5b8d503..e2d17f03d 100644 --- a/src/detection/opengl/opengl_linux.c +++ b/src/detection/opengl/opengl_linux.c @@ -158,6 +158,7 @@ typedef struct GLXData FF_LIBRARY_SYMBOL(glXDestroyGLXPixmap) FF_LIBRARY_SYMBOL(XFreePixmap) FF_LIBRARY_SYMBOL(XCloseDisplay) + FF_LIBRARY_SYMBOL(XFree) Display* display; XVisualInfo* visualInfo; @@ -213,7 +214,9 @@ static const char* glxHandleDisplay(FFOpenGLResult* result, GLXData* data) if(data->visualInfo == NULL) return "glXChooseVisual returned NULL"; - return glxHandleVisualInfo(result, data); + const char* error = glxHandleVisualInfo(result, data); + data->ffXFree(data->visualInfo); + return error; } static const char* glxHandleData(FFOpenGLResult* result, GLXData* data) @@ -247,6 +250,7 @@ static const char* glxPrint(FFinstance* instance, FFOpenGLResult* result) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXDestroyGLXPixmap); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XFreePixmap); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XCloseDisplay); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XFree); const char* error = glxHandleData(result, &data); dlclose(glx); From 2a8235ae388fbcc2b1ac55e7c123542f0379b22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 22:18:39 +0800 Subject: [PATCH 231/311] Host: improve performance (macOS) --- src/detection/host/host_apple.c | 252 ++++++++++++++++++-------------- 1 file changed, 143 insertions(+), 109 deletions(-) diff --git a/src/detection/host/host_apple.c b/src/detection/host/host_apple.c index f00946ad6..a63976d10 100644 --- a/src/detection/host/host_apple.c +++ b/src/detection/host/host_apple.c @@ -1,112 +1,145 @@ #include "host.h" #include "common/sysctl.h" +static inline bool strEqual(const char* a, const char* b) +{ + return strcmp(a, b) == 0; +} + static const char* getProductName(const FFstrbuf* hwModel) { //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L1386 - if(ffStrbufCompS(hwModel, "Mac14,7") == 0) return "MacBook Pro (13-inch, M2, 2022)"; - if(ffStrbufCompS(hwModel, "MacBookPro18,3") == 0 || - ffStrbufCompS(hwModel, "MacBookPro18,4") == 0) return "MacBook Pro (14-inch, 2021)"; - if(ffStrbufCompS(hwModel, "MacBookPro18,1") == 0 || - ffStrbufCompS(hwModel, "MacBookPro18,2") == 0) return "MacBook Pro (16-inch, 2021)"; - if(ffStrbufCompS(hwModel, "MacBookPro17,1") == 0) return "MacBook Pro (13-inch, M1, 2020)"; - if(ffStrbufCompS(hwModel, "MacBookPro16,4") == 0) return "MacBook Pro (16-inch, 2019)"; - if(ffStrbufCompS(hwModel, "MacBookPro16,3") == 0) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro16,2") == 0) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro16,1") == 0) return "MacBook Pro (16-inch, 2019)"; - if(ffStrbufCompS(hwModel, "MacBookPro15,4") == 0) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro15,3") == 0) return "MacBook Pro (15-inch, 2019)"; - if(ffStrbufCompS(hwModel, "MacBookPro15,2") == 0) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro15,1") == 0) return "MacBook Pro (15-inch, 2018/2019)"; - if(ffStrbufCompS(hwModel, "MacBookPro14,3") == 0) return "MacBook Pro (15-inch, 2017)"; - if(ffStrbufCompS(hwModel, "MacBookPro14,2") == 0) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro14,1") == 0) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro13,3") == 0) return "MacBook Pro (15-inch, 2016)"; - if(ffStrbufCompS(hwModel, "MacBookPro13,2") == 0) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro13,1") == 0) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)"; - if(ffStrbufCompS(hwModel, "MacBookPro12,1") == 0) return "MacBook Pro (Retina, 13-inch, Early 2015)"; - if(ffStrbufCompS(hwModel, "MacBookPro11,4") == 0 || - ffStrbufCompS(hwModel, "MacBookPro11,5") == 0) return "MacBook Pro (Retina, 15-inch, Mid 2015)"; - if(ffStrbufCompS(hwModel, "MacBookPro11,2") == 0 || - ffStrbufCompS(hwModel, "MacBookPro11,3") == 0) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)"; - if(ffStrbufCompS(hwModel, "MacBookPro11,1") == 0) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)"; - if(ffStrbufCompS(hwModel, "MacBookPro10,2") == 0) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)"; - if(ffStrbufCompS(hwModel, "MacBookPro10,1") == 0) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)"; - if(ffStrbufCompS(hwModel, "MacBookPro9,2") == 0) return "MacBook Pro (13-inch, Mid 2012)"; - if(ffStrbufCompS(hwModel, "MacBookPro9,1") == 0) return "MacBook Pro (15-inch, Mid 2012)"; - if(ffStrbufCompS(hwModel, "MacBookPro8,3") == 0) return "MacBook Pro (17-inch, 2011)"; - if(ffStrbufCompS(hwModel, "MacBookPro8,2") == 0) return "MacBook Pro (15-inch, 2011)"; - if(ffStrbufCompS(hwModel, "MacBookPro8,1") == 0) return "MacBook Pro (13-inch, 2011)"; - if(ffStrbufCompS(hwModel, "MacBookPro7,1") == 0) return "MacBook Pro (13-inch, Mid 2010)"; - if(ffStrbufCompS(hwModel, "MacBookPro6,2") == 0) return "MacBook Pro (15-inch, Mid 2010)"; - if(ffStrbufCompS(hwModel, "MacBookPro6,1") == 0) return "MacBook Pro (17-inch, Mid 2010)"; - if(ffStrbufCompS(hwModel, "MacBookPro5,5") == 0) return "MacBook Pro (13-inch, Mid 2009)"; - if(ffStrbufCompS(hwModel, "MacBookPro5,3") == 0) return "MacBook Pro (15-inch, Mid 2009)"; - if(ffStrbufCompS(hwModel, "MacBookPro5,2") == 0) return "MacBook Pro (17-inch, Mid/Early 2009)"; - if(ffStrbufCompS(hwModel, "MacBookPro5,1") == 0) return "MacBook Pro (15-inch, Late 2008)"; - if(ffStrbufCompS(hwModel, "MacBookPro4,1") == 0) return "MacBook Pro (17/15-inch, Early 2008)"; - if(ffStrbufCompS(hwModel, "Mac14,2") == 0) return "MacBook Air (M2, 2022)"; - if(ffStrbufCompS(hwModel, "MacBookAir10,1") == 0) return "MacBook Air (M1, 2020)"; - if(ffStrbufCompS(hwModel, "MacBookAir9,1") == 0) return "MacBook Air (Retina, 13-inch, 2020)"; - if(ffStrbufCompS(hwModel, "MacBookAir8,2") == 0) return "MacBook Air (Retina, 13-inch, 2019)"; - if(ffStrbufCompS(hwModel, "MacBookAir8,1") == 0) return "MacBook Air (Retina, 13-inch, 2018)"; - if(ffStrbufCompS(hwModel, "MacBookAir7,2") == 0) return "MacBook Air (13-inch, Early 2015/2017)"; - if(ffStrbufCompS(hwModel, "MacBookAir7,1") == 0) return "MacBook Air (11-inch, Early 2015)"; - if(ffStrbufCompS(hwModel, "MacBookAir6,2") == 0) return "MacBook Air (13-inch, Mid 2013/Early 2014)"; - if(ffStrbufCompS(hwModel, "MacBookAir6,1") == 0) return "MacBook Air (11-inch, Mid 2013/Early 2014)"; - if(ffStrbufCompS(hwModel, "MacBookAir5,2") == 0) return "MacBook Air (13-inch, Mid 2012)"; - if(ffStrbufCompS(hwModel, "MacBookAir5,1") == 0) return "MacBook Air (11-inch, Mid 2012)"; - if(ffStrbufCompS(hwModel, "MacBookAir4,2") == 0) return "MacBook Air (13-inch, Mid 2011)"; - if(ffStrbufCompS(hwModel, "MacBookAir4,1") == 0) return "MacBook Air (11-inch, Mid 2011)"; - if(ffStrbufCompS(hwModel, "MacBookAir3,2") == 0) return "MacBook Air (13-inch, Late 2010)"; - if(ffStrbufCompS(hwModel, "MacBookAir3,1") == 0) return "MacBook Air (11-inch, Late 2010)"; - if(ffStrbufCompS(hwModel, "MacBookAir2,1") == 0) return "MacBook Air (Mid 2009)"; - if(ffStrbufCompS(hwModel, "MacBook10,1") == 0) return "MacBook (Retina, 12-inch, 2017)"; - if(ffStrbufCompS(hwModel, "MacBook9,1") == 0) return "MacBook (Retina, 12-inch, Early 2016)"; - if(ffStrbufCompS(hwModel, "MacBook8,1") == 0) return "MacBook (Retina, 12-inch, Early 2015)"; - if(ffStrbufCompS(hwModel, "MacBook7,1") == 0) return "MacBook (13-inch, Mid 2010)"; - if(ffStrbufCompS(hwModel, "MacBook6,1") == 0) return "MacBook (13-inch, Late 2009)"; - if(ffStrbufCompS(hwModel, "MacBook5,2") == 0) return "MacBook (13-inch, Early/Mid 2009)"; - if(ffStrbufCompS(hwModel, "Mac13,1") == 0) return "Mac Studio (2022, Two USB-C front ports)"; - if(ffStrbufCompS(hwModel, "Mac13,2") == 0) return "Mac Studio (2022, Two Thunderbolt 4 front ports)"; - if(ffStrbufCompS(hwModel, "Macmini9,1") == 0) return "Mac mini (M1, 2020)"; - if(ffStrbufCompS(hwModel, "Macmini8,1") == 0) return "Mac mini (2018)"; - if(ffStrbufCompS(hwModel, "Macmini7,1") == 0) return "Mac mini (Mid 2014)"; - if(ffStrbufCompS(hwModel, "Macmini6,1") == 0 || - ffStrbufCompS(hwModel, "Macmini6,2") == 0) return "Mac mini (Late 2012)"; - if(ffStrbufCompS(hwModel, "Macmini5,1") == 0 || - ffStrbufCompS(hwModel, "Macmini5,2") == 0) return "Mac mini (Mid 2011)"; - if(ffStrbufCompS(hwModel, "Macmini4,1") == 0) return "Mac mini (Mid 2010)"; - if(ffStrbufCompS(hwModel, "Macmini3,1") == 0) return "Mac mini (Early/Late 2009)"; - if(ffStrbufCompS(hwModel, "MacPro7,1") == 0) return "Mac Pro (2019)"; - if(ffStrbufCompS(hwModel, "MacPro6,1") == 0) return "Mac Pro (Late 2013)"; - if(ffStrbufCompS(hwModel, "MacPro5,1") == 0) return "Mac Pro (Mid 2010 - Mid 2012)"; - if(ffStrbufCompS(hwModel, "MacPro4,1") == 0) return "Mac Pro (Early 2009)"; - if(ffStrbufCompS(hwModel, "iMac21,1") == 0 || - ffStrbufCompS(hwModel, "iMac21,2") == 0) return "iMac (24-inch, M1, 2021)"; - if(ffStrbufCompS(hwModel, "iMac20,1") == 0 || - ffStrbufCompS(hwModel, "iMac20,2") == 0) return "iMac (Retina 5K, 27-inch, 2020)"; - if(ffStrbufCompS(hwModel, "iMac19,1") == 0 || - ffStrbufCompS(hwModel, "iMac19,2") == 0) return "iMac (Retina 4K, 21.5-inch, 2019)"; - if(ffStrbufCompS(hwModel, "iMacPro1,1") == 0) return "iMac Pro (2017)"; - if(ffStrbufCompS(hwModel, "iMac18,3") == 0) return "iMac (Retina 5K, 27-inch, 2017)"; - if(ffStrbufCompS(hwModel, "iMac18,2") == 0) return "iMac (Retina 4K, 21.5-inch, 2017)"; - if(ffStrbufCompS(hwModel, "iMac18,1") == 0) return "iMac (21.5-inch, 2017)"; - if(ffStrbufCompS(hwModel, "iMac17,1") == 0) return "iMac (Retina 5K, 27-inch, Late 2015)"; - if(ffStrbufCompS(hwModel, "iMac16,2") == 0) return "iMac (Retina 4K, 21.5-inch, Late 2015)"; - if(ffStrbufCompS(hwModel, "iMac16,1") == 0) return "iMac (21.5-inch, Late 2015)"; - if(ffStrbufCompS(hwModel, "iMac15,1") == 0) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"; - if(ffStrbufCompS(hwModel, "iMac14,4") == 0) return "iMac (21.5-inch, Mid 2014)"; - if(ffStrbufCompS(hwModel, "iMac14,2") == 0) return "iMac (27-inch, Late 2013)"; - if(ffStrbufCompS(hwModel, "iMac14,1") == 0) return "iMac (21.5-inch, Late 2013)"; - if(ffStrbufCompS(hwModel, "iMac13,2") == 0) return "iMac (27-inch, Late 2012)"; - if(ffStrbufCompS(hwModel, "iMac13,1") == 0) return "iMac (21.5-inch, Late 2012)"; - if(ffStrbufCompS(hwModel, "iMac12,2") == 0) return "iMac (27-inch, Mid 2011)"; - if(ffStrbufCompS(hwModel, "iMac12,1") == 0) return "iMac (21.5-inch, Mid 2011)"; - if(ffStrbufCompS(hwModel, "iMac11,3") == 0) return "iMac (27-inch, Mid 2010)"; - if(ffStrbufCompS(hwModel, "iMac11,2") == 0) return "iMac (21.5-inch, Mid 2010)"; - if(ffStrbufCompS(hwModel, "iMac10,1") == 0) return "iMac (27/21.5-inch, Late 2009)"; - if(ffStrbufCompS(hwModel, "iMac9,1") == 0) return "iMac (24/20-inch, Early 2009)"; + if(ffStrbufStartsWithS(hwModel, "MacBookPro")) + { + const char* version = hwModel->chars + strlen("MacBookPro"); + if(strEqual(version, "18,3") || + strEqual(version, "18,4")) return "MacBook Pro (14-inch, 2021)"; + if(strEqual(version, "18,1") || + strEqual(version, "18,2")) return "MacBook Pro (16-inch, 2021)"; + if(strEqual(version, "17,1")) return "MacBook Pro (13-inch, M1, 2020)"; + if(strEqual(version, "16,4")) return "MacBook Pro (16-inch, 2019)"; + if(strEqual(version, "16,3")) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)"; + if(strEqual(version, "16,2")) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)"; + if(strEqual(version, "16,1")) return "MacBook Pro (16-inch, 2019)"; + if(strEqual(version, "15,4")) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)"; + if(strEqual(version, "15,3")) return "MacBook Pro (15-inch, 2019)"; + if(strEqual(version, "15,2")) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)"; + if(strEqual(version, "15,1")) return "MacBook Pro (15-inch, 2018/2019)"; + if(strEqual(version, "14,3")) return "MacBook Pro (15-inch, 2017)"; + if(strEqual(version, "14,2")) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)"; + if(strEqual(version, "14,1")) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)"; + if(strEqual(version, "13,3")) return "MacBook Pro (15-inch, 2016)"; + if(strEqual(version, "13,2")) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)"; + if(strEqual(version, "13,1")) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)"; + if(strEqual(version, "12,1")) return "MacBook Pro (Retina, 13-inch, Early 2015)"; + if(strEqual(version, "11,4") || + strEqual(version, "11,5")) return "MacBook Pro (Retina, 15-inch, Mid 2015)"; + if(strEqual(version, "11,2") || + strEqual(version, "11,3")) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)"; + if(strEqual(version, "11,1")) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)"; + if(strEqual(version, "10,2")) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)"; + if(strEqual(version, "10,1")) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)"; + if(strEqual(version, "9,2")) return "MacBook Pro (13-inch, Mid 2012)"; + if(strEqual(version, "9,1")) return "MacBook Pro (15-inch, Mid 2012)"; + if(strEqual(version, "8,3")) return "MacBook Pro (17-inch, 2011)"; + if(strEqual(version, "8,2")) return "MacBook Pro (15-inch, 2011)"; + if(strEqual(version, "8,1")) return "MacBook Pro (13-inch, 2011)"; + if(strEqual(version, "7,1")) return "MacBook Pro (13-inch, Mid 2010)"; + if(strEqual(version, "6,2")) return "MacBook Pro (15-inch, Mid 2010)"; + if(strEqual(version, "6,1")) return "MacBook Pro (17-inch, Mid 2010)"; + if(strEqual(version, "5,5")) return "MacBook Pro (13-inch, Mid 2009)"; + if(strEqual(version, "5,3")) return "MacBook Pro (15-inch, Mid 2009)"; + if(strEqual(version, "5,2")) return "MacBook Pro (17-inch, Mid/Early 2009)"; + if(strEqual(version, "5,1")) return "MacBook Pro (15-inch, Late 2008)"; + if(strEqual(version, "4,1")) return "MacBook Pro (17/15-inch, Early 2008)"; + } + else if(ffStrbufStartsWithS(hwModel, "MacBookAir")) + { + const char* version = hwModel->chars + strlen("MacBookAir"); + if(strEqual(version, "10,1")) return "MacBook Air (M1, 2020)"; + if(strEqual(version, "9,1")) return "MacBook Air (Retina, 13-inch, 2020)"; + if(strEqual(version, "8,2")) return "MacBook Air (Retina, 13-inch, 2019)"; + if(strEqual(version, "8,1")) return "MacBook Air (Retina, 13-inch, 2018)"; + if(strEqual(version, "7,2")) return "MacBook Air (13-inch, Early 2015/2017)"; + if(strEqual(version, "7,1")) return "MacBook Air (11-inch, Early 2015)"; + if(strEqual(version, "6,2")) return "MacBook Air (13-inch, Mid 2013/Early 2014)"; + if(strEqual(version, "6,1")) return "MacBook Air (11-inch, Mid 2013/Early 2014)"; + if(strEqual(version, "5,2")) return "MacBook Air (13-inch, Mid 2012)"; + if(strEqual(version, "5,1")) return "MacBook Air (11-inch, Mid 2012)"; + if(strEqual(version, "4,2")) return "MacBook Air (13-inch, Mid 2011)"; + if(strEqual(version, "4,1")) return "MacBook Air (11-inch, Mid 2011)"; + if(strEqual(version, "3,2")) return "MacBook Air (13-inch, Late 2010)"; + if(strEqual(version, "3,1")) return "MacBook Air (11-inch, Late 2010)"; + if(strEqual(version, "2,1")) return "MacBook Air (Mid 2009)"; + } + else if(ffStrbufStartsWithS(hwModel, "Macmini")) + { + const char* version = hwModel->chars + strlen("Macmini"); + if(strEqual(version, "9,1")) return "Mac mini (M1, 2020)"; + if(strEqual(version, "8,1")) return "Mac mini (2018)"; + if(strEqual(version, "7,1")) return "Mac mini (Mid 2014)"; + if(strEqual(version, "6,1") || + strEqual(version, "6,2")) return "Mac mini (Late 2012)"; + if(strEqual(version, "5,1") || + strEqual(version, "5,2")) return "Mac mini (Mid 2011)"; + if(strEqual(version, "4,1")) return "Mac mini (Mid 2010)"; + if(strEqual(version, "3,1")) return "Mac mini (Early/Late 2009)"; + } + else if(ffStrbufStartsWithS(hwModel, "MacBook")) + { + const char* version = hwModel->chars + strlen("MacBook"); + if(strEqual(version, "10,1")) return "MacBook (Retina, 12-inch, 2017)"; + if(strEqual(version, "9,1")) return "MacBook (Retina, 12-inch, Early 2016)"; + if(strEqual(version, "8,1")) return "MacBook (Retina, 12-inch, Early 2015)"; + if(strEqual(version, "7,1")) return "MacBook (13-inch, Mid 2010)"; + if(strEqual(version, "6,1")) return "MacBook (13-inch, Late 2009)"; + if(strEqual(version, "5,2")) return "MacBook (13-inch, Early/Mid 2009)"; + } + else if(ffStrbufStartsWithS(hwModel, "MacPro")) + { + const char* version = hwModel->chars + strlen("MacPro"); + if(strEqual(version, "7,1")) return "Mac Pro (2019)"; + if(strEqual(version, "6,1")) return "Mac Pro (Late 2013)"; + if(strEqual(version, "5,1")) return "Mac Pro (Mid 2010 - Mid 2012)"; + if(strEqual(version, "4,1")) return "Mac Pro (Early 2009)"; + } + else if(ffStrbufStartsWithS(hwModel, "Mac")) + { + const char* version = hwModel->chars + strlen("Mac"); + if(strEqual(version, "14,7")) return "MacBook Pro (13-inch, M2, 2022)"; + if(strEqual(version, "14,2")) return "MacBook Air (M2, 2022)"; + if(strEqual(version, "13,1")) return "Mac Studio (2022, Two USB-C front ports)"; + if(strEqual(version, "13,2")) return "Mac Studio (2022, Two Thunderbolt 4 front ports)"; + } + else if(ffStrbufStartsWithS(hwModel, "iMac")) + { + const char* version = hwModel->chars + strlen("iMac"); + if(strEqual(version, "21,1") || + strEqual(version, "21,2")) return "iMac (24-inch, M1, 2021)"; + if(strEqual(version, "20,1") || + strEqual(version, "20,2")) return "iMac (Retina 5K, 27-inch, 2020)"; + if(strEqual(version, "19,1") || + strEqual(version, "19,2")) return "iMac (Retina 4K, 21.5-inch, 2019)"; + if(strEqual(version, "Pro1,1")) return "iMac Pro (2017)"; + if(strEqual(version, "18,3")) return "iMac (Retina 5K, 27-inch, 2017)"; + if(strEqual(version, "18,2")) return "iMac (Retina 4K, 21.5-inch, 2017)"; + if(strEqual(version, "18,1")) return "iMac (21.5-inch, 2017)"; + if(strEqual(version, "17,1")) return "iMac (Retina 5K, 27-inch, Late 2015)"; + if(strEqual(version, "16,2")) return "iMac (Retina 4K, 21.5-inch, Late 2015)"; + if(strEqual(version, "16,1")) return "iMac (21.5-inch, Late 2015)"; + if(strEqual(version, "15,1")) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"; + if(strEqual(version, "14,4")) return "iMac (21.5-inch, Mid 2014)"; + if(strEqual(version, "14,2")) return "iMac (27-inch, Late 2013)"; + if(strEqual(version, "14,1")) return "iMac (21.5-inch, Late 2013)"; + if(strEqual(version, "13,2")) return "iMac (27-inch, Late 2012)"; + if(strEqual(version, "13,1")) return "iMac (21.5-inch, Late 2012)"; + if(strEqual(version, "12,2")) return "iMac (27-inch, Mid 2011)"; + if(strEqual(version, "12,1")) return "iMac (21.5-inch, Mid 2011)"; + if(strEqual(version, "11,3")) return "iMac (27-inch, Mid 2010)"; + if(strEqual(version, "11,2")) return "iMac (21.5-inch, Mid 2010)"; + if(strEqual(version, "10,1")) return "iMac (27/21.5-inch, Late 2009)"; + if(strEqual(version, "9,1")) return "iMac (24/20-inch, Early 2009)"; + } return hwModel->chars; } @@ -119,11 +152,12 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productVersion); ffStrbufInit(&host->productSku); - ffStrbufInitA(&host->sysVendor, 0); - ffStrbufInitA(&host->chassisType, 0); - ffStrbufInitA(&host->chassisVendor, 0); - ffStrbufInitA(&host->chassisVersion, 0); + ffStrbufInitS(&host->sysVendor, "Apple"); + ffStrbufInit(&host->chassisType); + ffStrbufInit(&host->chassisVendor); + ffStrbufInit(&host->chassisVersion); - ffSysctlGetString("hw.model", &host->productFamily); - ffStrbufAppendS(&host->productName, getProductName(&host->productFamily)); + ffStrbufAppendS(&host->error, ffSysctlGetString("hw.model", &host->productFamily)); + if(host->error.length == 0) + ffStrbufAppendS(&host->productName, getProductName(&host->productFamily)); } From 8b0d034a94cc4c28494bfeef1bd598a6af0d2221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 22:20:01 +0800 Subject: [PATCH 232/311] FFstrbuf: fix bug of AppendF when string len == ffStrbufGetFree --- src/util/FFstrbuf.c | 17 +++++++---------- tests/strbuf.c | 34 +++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 415ec6fb7..b86a7454c 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -138,21 +138,18 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) va_copy(copy, arguments); uint32_t free = ffStrbufGetFree(strbuf); - uint32_t written = (uint32_t) vsnprintf(strbuf->chars + strbuf->length, free, format, arguments); + int written = vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated > 0 ? free + 1 : 0, format, arguments); - if(strbuf->length + written > free) + if(written > 0 && strbuf->length + (uint32_t) written > free) { - ffStrbufEnsureFree(strbuf, written); - written = (uint32_t) vsnprintf(strbuf->chars + strbuf->length, ffStrbufGetFree(strbuf), format, copy); + ffStrbufEnsureFree(strbuf, (uint32_t) written); + written = vsnprintf(strbuf->chars + strbuf->length, (uint32_t) written + 1, format, copy); } va_end(copy); - if(written == 0) - return; - - strbuf->length += written; - strbuf->chars[strbuf->length] = '\0'; + if(written > 0) + strbuf->length += (uint32_t) written; } void ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until) @@ -438,5 +435,5 @@ void ffStrbufDestroy(FFstrbuf* strbuf) //Avoid free-after-use. These 3 assignments are cheap so don't remove them strbuf->allocated = strbuf->length = 0; free(strbuf->chars); - strbuf->chars = NULL; + strbuf->chars = CHAR_NULL_PTR; } diff --git a/tests/strbuf.c b/tests/strbuf.c index 403da59d5..5474d313e 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -63,7 +63,7 @@ int main(int argc, char** argv) VERIFY(strbuf.length == 5); VERIFY(strbuf.allocated >= 6); - VERIFY(ffStrbufCompS(&strbuf, "12345") == 0); + VERIFY(ffStrbufEqualS(&strbuf, "12345")); //appendNS @@ -72,7 +72,7 @@ int main(int argc, char** argv) VERIFY(strbuf.length == 9); VERIFY(strbuf.allocated >= 10); - VERIFY(ffStrbufCompS(&strbuf, "123456789") == 0); + VERIFY(ffStrbufEqualS(&strbuf, "123456789")); //appendS long @@ -87,7 +87,7 @@ int main(int argc, char** argv) VERIFY(strbuf.length == 9); VERIFY(strbuf.allocated >= 110); VERIFY(strbuf.chars[strbuf.length] == 0); - VERIFY(ffStrbufCompS(&strbuf, "123456789") == 0); + VERIFY(ffStrbufEqualS(&strbuf, "123456789")); //startsWithC @@ -166,10 +166,16 @@ int main(int argc, char** argv) VERIFY(!ffStrbufEndsWithIgnCaseS(&strbuf, "0aBcDeFg")); //ensure - ffStrbufEnsureEndsWithC(&strbuf, '^'); - VERIFY(ffStrbufCompS(&strbuf, "^aBcDeFg")); ffStrbufEnsureEndsWithC(&strbuf, '$'); - VERIFY(ffStrbufCompS(&strbuf, "^aBcDeFg$")); + VERIFY(ffStrbufEqualS(&strbuf, "AbCdEfG$")); + ffStrbufEnsureEndsWithC(&strbuf, '$'); + VERIFY(ffStrbufEqualS(&strbuf, "AbCdEfG$")); + + //clear + ffStrbufClear(&strbuf); + VERIFY(strbuf.allocated > 0); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.chars && strbuf.chars[0] == 0); //Destroy @@ -177,7 +183,21 @@ int main(int argc, char** argv) VERIFY(strbuf.allocated == 0); VERIFY(strbuf.length == 0); - VERIFY(strbuf.chars == NULL); + VERIFY(strbuf.chars && strbuf.chars[0] == 0); + + //initA + ffStrbufInitA(&strbuf, 32); + + VERIFY(strbuf.allocated == 32); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.chars && strbuf.chars[0] == 0); + + //appendF + ffStrbufAppendF(&strbuf, "%s", "1234567890123456789012345678901"); + VERIFY(strbuf.allocated == 32); + VERIFY(ffStrbufEqualS(&strbuf, "1234567890123456789012345678901")); + + ffStrbufDestroy(&strbuf); //Success puts("\033[32mAll tests passed!"FASTFETCH_TEXT_MODIFIER_RESET); From 911780ba3ca4eb115200fd71a9c311cd5722c66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 22:20:23 +0800 Subject: [PATCH 233/311] Cursor: silence compiler warnings --- src/detection/cursor/cursor_nosupport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/cursor/cursor_nosupport.c b/src/detection/cursor/cursor_nosupport.c index c548b2f6c..c54637c96 100644 --- a/src/detection/cursor/cursor_nosupport.c +++ b/src/detection/cursor/cursor_nosupport.c @@ -2,5 +2,6 @@ void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) { + FF_UNUSED(instance, result); ffStrbufInitS(&result->error, "Not supported on this platform"); } From 19ec59cca5dd2b1b789dd2c827cbdcaeb564ae2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 2 Dec 2022 22:34:56 +0800 Subject: [PATCH 234/311] Wifi: init basic support for Linux --- CMakeLists.txt | 2 +- README.md | 2 +- src/detection/wifi/wifi_linux.c | 59 +++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/detection/wifi/wifi_linux.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bb119b853..16c2e604c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,7 +332,7 @@ if(LINUX) src/detection/terminalshell/terminalshell_linux.c src/detection/uptime/uptime_linux.c src/detection/users/users_linux.c - src/detection/wifi/wifi_nosupport.c + src/detection/wifi/wifi_linux.c src/detection/wmtheme/wmtheme_linux.c ) elseif(ANDROID) diff --git a/README.md b/README.md index 7a656d598..5cc094bf4 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ All categories not listed here should work without needing a specific implementa ##### Available Modules ``` -Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom +Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, Wifi, DateTime, Date, Time, Locale, Colors, Break, Custom ``` ##### Logos diff --git a/src/detection/wifi/wifi_linux.c b/src/detection/wifi/wifi_linux.c new file mode 100644 index 000000000..88de374d0 --- /dev/null +++ b/src/detection/wifi/wifi_linux.c @@ -0,0 +1,59 @@ +#include "wifi.h" + +#include "common/io.h" +#include +#include + +static const char* detectInf(uint32_t ifIndex, FFWifiResult* wifi) +{ + //TODO: play with netlink + FF_UNUSED(ifIndex, wifi); + return "Unimplemented"; +} + +const char* ffDetectWifi(const FFinstance* instance, FFlist* result) +{ + struct if_nameindex* infs = if_nameindex(); + if(!infs) + return "if_nameindex() failed"; + + FFstrbuf path; + ffStrbufInit(&path); + + for(struct if_nameindex* i = infs; !(i->if_index == 0 && i->if_name == NULL); ++i) + { + ffStrbufSetF(&path, "/sys/class/net/%s/phy80211", i->if_name); + if(!ffFileExists(path.chars, S_IFDIR)) + continue; + + FFWifiResult* item = (FFWifiResult*)ffListAdd(result); + ffStrbufInitS(&item->inf.description, i->if_name); + ffStrbufInit(&item->inf.status); + ffStrbufInit(&item->conn.status); + ffStrbufInit(&item->conn.ssid); + ffStrbufInit(&item->conn.macAddress); + ffStrbufInit(&item->conn.phyType); + item->conn.signalQuality = 0.0/0.0; + item->conn.rxRate = 0.0/0.0; + item->conn.txRate = 0.0/0.0; + item->security.enabled = false; + item->security.oneXEnabled = false; + ffStrbufInit(&item->security.algorithm); + + ffStrbufSetF(&path, "/sys/class/net/%s/operstate", i->if_name); + if(!ffAppendFileBuffer(path.chars, &item->inf.status) || !ffStrbufEqualS(&item->inf.status, "up")) + continue; + + ffStrbufSetF(&path, "/sys/class/net/%s/address", i->if_name); + ffAppendFileBuffer(path.chars, &item->conn.macAddress); + + detectInf(i->if_index, item); + } + if_freenameindex(infs); + ffStrbufDestroy(&path); + + if(result->length == 0) + return "No wifi interfaces found"; + + return NULL; +} From 58aa3e94e468dc0b7512bcd710079b2eaf2364fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 3 Dec 2022 22:21:24 +0800 Subject: [PATCH 235/311] Init: add `--disable-stdout-buffer` option --- .github/workflows/push.yml | 8 ++++---- completions/bash | 1 + src/data/config_user.txt | 6 ++++++ src/data/help.txt | 1 + src/fastfetch.c | 5 +++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 6a41daff2..0733c64c0 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -35,7 +35,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer - name: run flashfetch run: ./flashfetch @@ -81,7 +81,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer - name: run flashfetch run: ./flashfetch @@ -113,7 +113,7 @@ jobs: run: | cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . cmake --build . --target package - ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer ./flashfetch ctest @@ -180,7 +180,7 @@ jobs: run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer - name: run flashfetch run: ./flashfetch diff --git a/completions/bash b/completions/bash index 8a3ef9e0c..6b6e4e574 100644 --- a/completions/bash +++ b/completions/bash @@ -175,6 +175,7 @@ __fastfetch_completion() "--logo-print-remaining" "--multithreading" "--allow-slow-operations" + "--disable-stdout-buffer" "--disable-linewrap" "--hide-cursor" "--cpu-temp" diff --git a/src/data/config_user.txt b/src/data/config_user.txt index e588557b2..a2430cff9 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -33,6 +33,12 @@ # Default is true. #--multithreading true +# Disable stdout buffer option: +# Sets if fastfetch should disable application buffer of stdout. Mainly for debugging purpose. +# Must be true or false. +# Default is false. +#--disable-stdout-buffer false + # Slow operations option: # Sets if fastfetch is allowed to use known slow operations to detect more / better values. # Must be true or false. diff --git a/src/data/help.txt b/src/data/help.txt index ed25dcb11..948f88dcc 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -19,6 +19,7 @@ General options: --load-config : load a config file or a preset (+) --multithreading : use multiple threads to detect values --allow-slow-operations : allow operations that are usually very slow for more detailed output + --disable-stdout-buffer : disable stdout application buffer --escape-bedrock : on bedrock linux, sets if it should escape the bedrock jail or not --pipe : disable logo and all escape sequences diff --git a/src/fastfetch.c b/src/fastfetch.c index f0815cae4..356b94b88 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -909,6 +909,11 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.multithreading = optionParseBoolean(value); else if(strcasecmp(key, "--allow-slow-operations") == 0) instance->config.allowSlowOperations = optionParseBoolean(value); + else if(strcasecmp(key, "--disable-stdout-buffer") == 0) + { + if(optionParseBoolean(value)) + setvbuf(stdout, NULL, _IONBF, 0); + } else if(strcasecmp(key, "--escape-bedrock") == 0) instance->config.escapeBedrock = optionParseBoolean(value); else if(strcasecmp(key, "--pipe") == 0) From 4f0be4f72c755226ade14f7137f8653a426f184e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 5 Dec 2022 18:02:10 +0800 Subject: [PATCH 236/311] Wifi: silence compiler warnings --- src/detection/wifi/wifi_linux.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/detection/wifi/wifi_linux.c b/src/detection/wifi/wifi_linux.c index 88de374d0..985ba6f74 100644 --- a/src/detection/wifi/wifi_linux.c +++ b/src/detection/wifi/wifi_linux.c @@ -13,6 +13,8 @@ static const char* detectInf(uint32_t ifIndex, FFWifiResult* wifi) const char* ffDetectWifi(const FFinstance* instance, FFlist* result) { + FF_UNUSED(instance); + struct if_nameindex* infs = if_nameindex(); if(!infs) return "if_nameindex() failed"; From 983bd50a09b2e189aff9493676a7703ab7d69b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 6 Dec 2022 16:26:51 +0800 Subject: [PATCH 237/311] FFstrbuf: improve performance of InitF --- src/util/FFstrbuf.c | 22 +++++++++++++++++----- src/util/FFstrbuf.h | 1 + tests/strbuf.c | 7 +++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index b86a7454c..27150ef24 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -26,14 +26,23 @@ void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) { assert(format != NULL); - ffStrbufInit(strbuf); - va_list arguments; va_start(arguments, format); - ffStrbufAppendVF(strbuf, format, arguments); + ffStrbufInitVF(strbuf, format, arguments); va_end(arguments); } +void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) +{ + assert(format != NULL); + + int len = vasprintf(&strbuf->chars, format, arguments); + assert(len >= 0); + + strbuf->allocated = (uint32_t)(len + 1); + strbuf->length = (uint32_t)len; +} + uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) { assert(strbuf != NULL); @@ -168,10 +177,13 @@ void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...) { assert(format != NULL); - ffStrbufClear(strbuf); - va_list arguments; va_start(arguments, format); + + if(strbuf->allocated == 0) + return ffStrbufInitVF(strbuf, format, arguments); + + ffStrbufClear(strbuf); ffStrbufAppendVF(strbuf, format, arguments); va_end(arguments); } diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 80503e55d..8116311da 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -32,6 +32,7 @@ typedef struct FFstrbuf void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate); void ffStrbufInitCopy(FFstrbuf* strbuf, const FFstrbuf* src); void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...); +void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments); void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free); diff --git a/tests/strbuf.c b/tests/strbuf.c index 5474d313e..c02d31510 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -199,6 +199,13 @@ int main(int argc, char** argv) ffStrbufDestroy(&strbuf); + //initF + ffStrbufInitF(&strbuf, "%s", "1234567890123456789012345678901"); + VERIFY(strbuf.allocated == 32); + VERIFY(ffStrbufEqualS(&strbuf, "1234567890123456789012345678901")); + + ffStrbufDestroy(&strbuf); + //Success puts("\033[32mAll tests passed!"FASTFETCH_TEXT_MODIFIER_RESET); } From d946a46d3f0dfeeca21d1dd5a19fc00f81a6825f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 8 Dec 2022 18:27:04 +0800 Subject: [PATCH 238/311] TerminalFont: fix memleaks (Linux) --- src/detection/terminalfont/terminalfont_linux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 28128ad3f..54ea3a328 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -173,6 +173,7 @@ static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResul } } + free(line); fclose(file); } From b4e2997389b84985d8be6e7a08705ef714ff6de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 6 Dec 2022 17:03:31 +0800 Subject: [PATCH 239/311] Tests: don't include `fastfetch.h` --- src/common/bar.c | 1 + src/common/format.c | 1 + src/common/init.c | 1 + src/common/printing.c | 1 + src/fastfetch.h | 4 ---- src/logo/logo.c | 1 + src/modules/colors.c | 1 + src/modules/custom.c | 1 + src/modules/title.c | 1 + src/util/textModifier.h | 10 ++++++++++ tests/list.c | 8 ++++---- tests/strbuf.c | 10 +++++----- 12 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 src/util/textModifier.h diff --git a/src/common/bar.c b/src/common/bar.c index a8f7c7b62..34b14aa7a 100644 --- a/src/common/bar.c +++ b/src/common/bar.c @@ -1,3 +1,4 @@ +#include "util/textModifier.h" #include "bar.h" // green, yellow, red: print the color on nth (0~9) block diff --git a/src/common/format.c b/src/common/format.c index 70f24e38e..b491713cf 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/format.h" #include "common/parsing.h" +#include "util/textModifier.h" #include diff --git a/src/common/init.c b/src/common/init.c index fb3bba75a..1483a6499 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -5,6 +5,7 @@ #include "detection/qt.h" #include "detection/gtk.h" #include "detection/displayserver/displayserver.h" +#include "util/textModifier.h" #include #include diff --git a/src/common/printing.c b/src/common/printing.c index 38d5f9619..4b593001a 100644 --- a/src/common/printing.c +++ b/src/common/printing.c @@ -1,5 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" +#include "util/textModifier.h" void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat) { diff --git a/src/fastfetch.h b/src/fastfetch.h index 16a80d6b9..96dd4a445 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -26,10 +26,6 @@ static inline void ffUnused(int dummy, ...) { (void) dummy; } #define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); -#define FASTFETCH_TEXT_MODIFIER_BOLT "\033[1m" -#define FASTFETCH_TEXT_MODIFIER_ERROR "\033[1;31m" -#define FASTFETCH_TEXT_MODIFIER_RESET "\033[0m" - #define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) typedef enum FFLogoType diff --git a/src/logo/logo.c b/src/logo/logo.c index 93667ddd3..6abb1b083 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -3,6 +3,7 @@ #include "common/printing.h" #include "detection/os/os.h" #include "detection/terminalshell/terminalshell.h" +#include "util/textModifier.h" #include #include diff --git a/src/modules/colors.c b/src/modules/colors.c index 626ced7b0..40a936e00 100644 --- a/src/modules/colors.c +++ b/src/modules/colors.c @@ -1,5 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" +#include "util/textModifier.h" void ffPrintColors(FFinstance* instance) { diff --git a/src/modules/custom.c b/src/modules/custom.c index 723f7059c..f91a5b69e 100644 --- a/src/modules/custom.c +++ b/src/modules/custom.c @@ -1,5 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" +#include "util/textModifier.h" void ffPrintCustom(FFinstance* instance, const char* key, const char* value) { diff --git a/src/modules/title.c b/src/modules/title.c index 089b5105c..cef00d146 100644 --- a/src/modules/title.c +++ b/src/modules/title.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/printing.h" #include "detection/title.h" +#include "util/textModifier.h" static inline void printTitlePart(FFinstance* instance, const FFstrbuf* content) { diff --git a/src/util/textModifier.h b/src/util/textModifier.h new file mode 100644 index 000000000..f282d31d5 --- /dev/null +++ b/src/util/textModifier.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_TEXT_MODIFIER +#define FASTFETCH_INCLUDED_TEXT_MODIFIER + +#define FASTFETCH_TEXT_MODIFIER_BOLT "\033[1m" +#define FASTFETCH_TEXT_MODIFIER_ERROR "\033[1;31m" +#define FASTFETCH_TEXT_MODIFIER_RESET "\033[0m" + +#endif diff --git a/tests/list.c b/tests/list.c index 38be491e5..e9c10423e 100644 --- a/tests/list.c +++ b/tests/list.c @@ -1,8 +1,10 @@ -#include "fastfetch.h" +#include "util/FFlist.h" +#include "util/textModifier.h" #include #include #include +#include __attribute__((__noreturn__)) static void testFailed(const FFlist* list, const char* expression, int lineNo) @@ -26,10 +28,8 @@ static bool numEqualsAdapter(const void* first, const void* second) #define VERIFY(expression) if(!(expression)) testFailed(&list, #expression, __LINE__) -int main(int argc, char** argv) +int main(void) { - FF_UNUSED(argc, argv) - FFlist list; //initA diff --git a/tests/strbuf.c b/tests/strbuf.c index c02d31510..dd8b6d57d 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -1,7 +1,9 @@ -#include "fastfetch.h" +#include "util/FFstrbuf.h" +#include "util/textModifier.h" #include #include +#include __attribute__((__noreturn__)) static void testFailed(const FFstrbuf* strbuf, const char* expression, int lineNo) @@ -17,14 +19,12 @@ static void testFailed(const FFstrbuf* strbuf, const char* expression, int lineN #define VERIFY(expression) if(!(expression)) testFailed(&strbuf, #expression, __LINE__) int shouldNotBeCalled(int c) { - FF_UNUSED(c); + (void)c; exit(1); } -int main(int argc, char** argv) +int main(void) { - FF_UNUSED(argc, argv) - FFstrbuf strbuf; //destroy 0 From ed259fad9ca65c3c5f0779d8ce094d8b08364000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 8 Dec 2022 18:33:43 +0800 Subject: [PATCH 240/311] Windows: tweaks --- CMakeLists.txt | 23 +++++++++------- src/fastfetch_config.h.in | 4 +++ src/util/windows/version.rc | 48 ++++++++++++++++++++++++++++++++++ src/util/windows/version.rc.in | 47 --------------------------------- 4 files changed, 65 insertions(+), 57 deletions(-) create mode 100644 src/util/windows/version.rc delete mode 100644 src/util/windows/version.rc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 16c2e604c..c9dd5bac8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,11 @@ if (SET_TWEAK AND EXISTS "${CMAKE_SOURCE_DIR}/.git") ) string(REGEX MATCH "-[0-9]+" PROJECT_VERSION_TWEAK "${PROJECT_VERSION_TWEAK}") endif() +if(PROJECT_VERSION_TWEAK) + string(REGEX MATCH "[0-9]+" PROJECT_VERSION_TWEAK_NUM "${PROJECT_VERSION_TWEAK}") +else() + set(PROJECT_VERSION_TWEAK_NUM 0) +endif() ############# # Text data # @@ -684,6 +689,9 @@ target_link_libraries(libfastfetch add_executable(fastfetch src/fastfetch.c ) +target_compile_definitions(fastfetch + PRIVATE FASTFETCH_TARGET_BINARY_NAME="fastfetch" +) target_link_libraries(fastfetch PRIVATE libfastfetch ) @@ -691,27 +699,22 @@ target_link_libraries(fastfetch add_executable(flashfetch src/flashfetch.c ) +target_compile_definitions(flashfetch + PRIVATE FASTFETCH_TARGET_BINARY_NAME="flashfetch" +) 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 + PRIVATE src/util/windows/version.rc ) set(TARGET_NAME flashfetch) - configure_file(src/util/windows/version.rc.in version.flashfetch.rc) target_sources(flashfetch - PRIVATE version.flashfetch.rc + PRIVATE src/util/windows/version.rc ) endif() diff --git a/src/fastfetch_config.h.in b/src/fastfetch_config.h.in index 171881da9..0fcf3f2d1 100644 --- a/src/fastfetch_config.h.in +++ b/src/fastfetch_config.h.in @@ -7,6 +7,10 @@ #define FASTFETCH_PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@ #define FASTFETCH_PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@ #define FASTFETCH_PROJECT_VERSION_TWEAK "@PROJECT_VERSION_TWEAK@" +#define FASTFETCH_PROJECT_VERSION_TWEAK_NUM @PROJECT_VERSION_TWEAK_NUM@ +#define FASTFETCH_PROJECT_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@" +#define FASTFETCH_PROJECT_DESCRIPTION "@PROJECT_DESCRIPTION@" +#define FASTFETCH_PROJECT_LICENSE "@PROJECT_LICENSE@" #define FASTFETCH_TARGET_DIR_ROOT "@TARGET_DIR_ROOT@" #define FASTFETCH_TARGET_DIR_USR "@TARGET_DIR_USR@" diff --git a/src/util/windows/version.rc b/src/util/windows/version.rc new file mode 100644 index 000000000..9934522c1 --- /dev/null +++ b/src/util/windows/version.rc @@ -0,0 +1,48 @@ +// +// Include the necessary resources +// +#include +#include +#include "fastfetch_config.h" + +#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 FASTFETCH_PROJECT_VERSION_MAJOR,FASTFETCH_PROJECT_VERSION_MINOR,FASTFETCH_PROJECT_VERSION_PATCH,FASTFETCH_PROJECT_VERSION_TWEAK_NUM +PRODUCTVERSION FASTFETCH_PROJECT_VERSION_MAJOR,FASTFETCH_PROJECT_VERSION_MINOR,FASTFETCH_PROJECT_VERSION_PATCH,FASTFETCH_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", FASTFETCH_PROJECT_HOMEPAGE_URL + VALUE "FileDescription", FASTFETCH_TARGET_BINARY_NAME " - " FASTFETCH_PROJECT_DESCRIPTION + VALUE "FileVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK + VALUE "InternalName", FASTFETCH_TARGET_BINARY_NAME ".exe" + VALUE "LegalCopyright", FASTFETCH_PROJECT_LICENSE + VALUE "OriginalFilename", FASTFETCH_TARGET_BINARY_NAME ".exe" + VALUE "ProductName", FASTFETCH_PROJECT_NAME + VALUE "ProductVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409,1252 + END +END +#endif diff --git a/src/util/windows/version.rc.in b/src/util/windows/version.rc.in deleted file mode 100644 index 3e1833eec..000000000 --- a/src/util/windows/version.rc.in +++ /dev/null @@ -1,47 +0,0 @@ -// -// 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 From 4558af2e43e26473a1e5a761dc3b0aeca07a591f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 10 Dec 2022 13:10:06 +0800 Subject: [PATCH 241/311] Windows: fix build --- CMakeLists.txt | 4 ++-- src/util/windows/version.rc | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9dd5bac8..9932e29a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -690,7 +690,7 @@ add_executable(fastfetch src/fastfetch.c ) target_compile_definitions(fastfetch - PRIVATE FASTFETCH_TARGET_BINARY_NAME="fastfetch" + PRIVATE FASTFETCH_TARGET_BINARY_NAME=fastfetch ) target_link_libraries(fastfetch PRIVATE libfastfetch @@ -700,7 +700,7 @@ add_executable(flashfetch src/flashfetch.c ) target_compile_definitions(flashfetch - PRIVATE FASTFETCH_TARGET_BINARY_NAME="flashfetch" + PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch ) target_link_libraries(flashfetch PRIVATE libfastfetch diff --git a/src/util/windows/version.rc b/src/util/windows/version.rc index 9934522c1..a8ea2519c 100644 --- a/src/util/windows/version.rc +++ b/src/util/windows/version.rc @@ -16,6 +16,8 @@ #define VER_DEBUG 0 #endif +#define FF_TO_STR(str) #str + // ------- version info ------------------------------------------------------- VS_VERSION_INFO VERSIONINFO @@ -31,11 +33,11 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", FASTFETCH_PROJECT_HOMEPAGE_URL - VALUE "FileDescription", FASTFETCH_TARGET_BINARY_NAME " - " FASTFETCH_PROJECT_DESCRIPTION + VALUE "FileDescription", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME) " - " FASTFETCH_PROJECT_DESCRIPTION VALUE "FileVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK - VALUE "InternalName", FASTFETCH_TARGET_BINARY_NAME ".exe" + VALUE "InternalName", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME) ".exe" VALUE "LegalCopyright", FASTFETCH_PROJECT_LICENSE - VALUE "OriginalFilename", FASTFETCH_TARGET_BINARY_NAME ".exe" + VALUE "OriginalFilename", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME) ".exe" VALUE "ProductName", FASTFETCH_PROJECT_NAME VALUE "ProductVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK END From 72dcc5223d78caac4a94111b6772dd7baa6436a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 10 Dec 2022 13:11:41 +0800 Subject: [PATCH 242/311] Global: rename `--disable-stdout-buffer` to `--unbuffered` --- .github/workflows/push.yml | 8 ++++---- completions/bash | 2 +- src/data/config_user.txt | 2 +- src/data/help.txt | 2 +- src/fastfetch.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 0733c64c0..1cd9ca862 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -35,7 +35,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - name: run flashfetch run: ./flashfetch @@ -81,7 +81,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - name: run flashfetch run: ./flashfetch @@ -113,7 +113,7 @@ jobs: run: | cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . cmake --build . --target package - ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer + ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered ./flashfetch ctest @@ -180,7 +180,7 @@ jobs: run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --disable-stdout-buffer + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - name: run flashfetch run: ./flashfetch diff --git a/completions/bash b/completions/bash index 6b6e4e574..7de2b3edf 100644 --- a/completions/bash +++ b/completions/bash @@ -175,7 +175,7 @@ __fastfetch_completion() "--logo-print-remaining" "--multithreading" "--allow-slow-operations" - "--disable-stdout-buffer" + "--unbuffered" "--disable-linewrap" "--hide-cursor" "--cpu-temp" diff --git a/src/data/config_user.txt b/src/data/config_user.txt index a2430cff9..0b354c5a1 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -37,7 +37,7 @@ # Sets if fastfetch should disable application buffer of stdout. Mainly for debugging purpose. # Must be true or false. # Default is false. -#--disable-stdout-buffer false +#--unbuffered false # Slow operations option: # Sets if fastfetch is allowed to use known slow operations to detect more / better values. diff --git a/src/data/help.txt b/src/data/help.txt index 948f88dcc..1cebf5748 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -19,7 +19,7 @@ General options: --load-config : load a config file or a preset (+) --multithreading : use multiple threads to detect values --allow-slow-operations : allow operations that are usually very slow for more detailed output - --disable-stdout-buffer : disable stdout application buffer + --unbuffered : disable stdout application buffer --escape-bedrock : on bedrock linux, sets if it should escape the bedrock jail or not --pipe : disable logo and all escape sequences diff --git a/src/fastfetch.c b/src/fastfetch.c index 356b94b88..ffbc964a9 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -909,7 +909,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.multithreading = optionParseBoolean(value); else if(strcasecmp(key, "--allow-slow-operations") == 0) instance->config.allowSlowOperations = optionParseBoolean(value); - else if(strcasecmp(key, "--disable-stdout-buffer") == 0) + else if(strcasecmp(key, "--unbuffered") == 0) { if(optionParseBoolean(value)) setvbuf(stdout, NULL, _IONBF, 0); From e3590bc6732adff58dd8f6b002d3a953ead7bc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 10 Dec 2022 14:19:12 +0800 Subject: [PATCH 243/311] Wmtheme: fix detection on Windows 10- --- src/detection/wmtheme/wmtheme_windows.c | 37 +++++++++++++++++-------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 80a253bf5..cf070be69 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -54,6 +54,8 @@ const char* colorHexToString(DWORD hex) case 0x4c574e: return "Sage"; case 0x807143: return "Camouflage desert"; case 0x766c59: return "Camouflage"; + case 0x000000: return "Black"; + case 0xFFFFFF: return "White"; default: return NULL; } } @@ -62,20 +64,30 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) { FF_UNUSED(instance); - { + do { + uint32_t rgbColor; 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, "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); + rgbColor = ((bgrColor & 0xFF) << 16) | (bgrColor & 0xFF00) | ((bgrColor >> 16) & 0xFF); + } - } + else if(RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\DWM", L"ColorizationColor", RRF_RT_REG_DWORD, NULL, &rgbColor, &bufSize) == ERROR_SUCCESS) + { + ffStrbufAppendS(themeOrError, "Colorization Color - "); + rgbColor &= 0xFFFFFF; + } + else + break; + + const char* text = colorHexToString(rgbColor); + if(text) + ffStrbufAppendS(themeOrError, text); + else + ffStrbufAppendF(themeOrError, "#%06lX", (long)rgbColor); + } while(false); FF_HKEY_AUTO_DESTROY hKey = NULL; if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hKey, NULL)) @@ -99,10 +111,11 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) 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]); + ffStrbufSubstrBeforeLastC(&theme, '.'); + ffStrbufSubstrAfterLastC(&theme, '\\'); + if(isalpha(theme.chars[0])) + theme.chars[0] = (char)toupper(theme.chars[0]); + if(themeOrError->length > 0) ffStrbufAppendS(themeOrError, ", "); ffStrbufAppendF(themeOrError, "Theme - %s", theme.chars); } From 24ae7ec6e074ec483b07b2ace33287349152164e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 10 Dec 2022 14:22:59 +0800 Subject: [PATCH 244/311] Windows: build msvcrt version for Windows 10- However we don't include it in release package to prevent users from confusion. Also clarify we only support FreeBSD --- .github/workflows/push.yml | 84 +++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 1cd9ca862..236cd5cbb 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -95,8 +95,8 @@ jobs: name: fastfetch-macos path: ./fastfetch-*.* - bsd: - name: BSD + freebsd: + name: FreeBSD runs-on: macos-12 permissions: security-events: write @@ -120,7 +120,7 @@ jobs: - name: upload artifacts uses: actions/upload-artifact@v3 with: - name: fastfetch-bsd + name: fastfetch-freebsd path: ./fastfetch-*.* windows: @@ -197,6 +197,80 @@ jobs: ./fastfetch.exe ./flashfetch.exe + windows-old: + name: Windows-old + runs-on: windows-latest + permissions: + security-events: write + contents: read + defaults: + run: + shell: msys2 {0} + steps: + - name: checkout repository + uses: actions/checkout@v3 + + - name: setup-msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: git mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-x86_64-cjson mingw-w64-x86_64-vulkan-loader mingw-w64-x86_64-opencl-icd + + - name: print msys version + run: uname -a + + # https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785 + - name: create OpenCL.pc + run: | + cat > /mingw64/lib/pkgconfig/OpenCL.pc << EOF + prefix=/mingw64 + exec_prefix=${prefix} + libdir=${exec_prefix}/lib + includedir=${prefix}/include + + Name: OpenCL + Description: Open Computing Language generic Installable Client Driver Loader + Version: 2022.09.30-1 + Libs: -L${libdir} -lOpenCL.dll + Cflags: -I${includedir} + EOF + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: c, cpp + + - name: configure project + run: env PKG_CONFIG_PATH=/mingw64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . + + - name: build project + run: cmake --build . + + - name: perform CodeQL analysis + uses: github/codeql-action/analyze@v2 + + - name: copy necessary dlls + run: cp /mingw64/bin/{libcjson,libOpenCL,vulkan-1}.dll . + + - name: run fastfetch + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + + - name: run flashfetch + run: ./flashfetch + + - name: run tests + run: ctest + + - name: upload artifacts + uses: actions/upload-artifact@v3 + with: + name: fastfetch-windows-old + path: | + ./*.dll + ./fastfetch.exe + ./flashfetch.exe + release: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch' name: Release @@ -204,7 +278,7 @@ jobs: needs: - linux - macos - - bsd + - freebsd - windows permissions: contents: write @@ -225,4 +299,4 @@ jobs: tag: ${{ needs.linux.outputs.ffversion }} commit: ${{ github.sha }} artifactErrorsFailBuild: true - artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/*,fastfetch-windows/* + artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-freebsd/*,fastfetch-windows/* From 68b98c1bd24043d74468a253774abda434c2277f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 10 Dec 2022 22:21:11 +0800 Subject: [PATCH 245/311] Windows: disable stdout buffer --- src/common/init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 1483a6499..c86285b70 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -121,7 +121,6 @@ static void initState(FFstate* state) #ifdef WIN32 //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support setlocale(LC_ALL, ".UTF8"); - setvbuf(stdout, NULL, _IOFBF, 4096); #endif state->logoWidth = 0; @@ -359,7 +358,7 @@ void ffStart(FFinstance* instance) DWORD mode = 0; GetConsoleMode(hStdout, &mode); SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); - // SetConsoleOutputCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); #else struct sigaction action = { .sa_handler = exitSignalHandler }; sigaction(SIGINT, &action, NULL); From 3a5af1bbb3802c007f0d4dc3e1c785665cd86823 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 12 Dec 2022 13:43:10 +0100 Subject: [PATCH 246/311] Logo: data source option #345 --- src/data/config_user.txt | 2 +- src/data/help.txt | 8 +++--- src/fastfetch.c | 54 ++++++++++++++++++++++++---------------- src/fastfetch.h | 16 ++++++------ src/logo/image/image.c | 18 +++++++------- src/logo/logo.c | 15 ++++++++--- 6 files changed, 69 insertions(+), 44 deletions(-) diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 0b354c5a1..fb231eab0 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -67,7 +67,7 @@ # Logo type option: # Sets the logo type to use. -# Must be auto, builtin, file, raw, sixel, kitty or chafa. +# Must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa. # Default is auto. #--logo-type auto diff --git a/src/data/help.txt b/src/data/help.txt index 1cebf5748..cd0c36168 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -25,7 +25,7 @@ General options: Logo options: -l,--logo : set the logo to use. The type is specified by --logo-type. If default: the name of a builtin logo or a path to a file - --logo-type : set the type of the logo given. Must be auto, builtin, file, raw, sixel, kitty or chafa. + --logo-type : set the type of the logo given. Must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa. --logo-width : set the width of the logo (in characters), if it is an image --logo-height : set the height of the logo (in characters), if it is an image --logo-color-[1-9] : overwrite a color in the logo @@ -33,11 +33,13 @@ Logo options: --logo-padding-left : set the padding on the left of the logo --logo-padding-right : set the padding on the right of the logo --logo-print-remaining : weather to print the remaining logo, if it has more lines than modules to display + --file : short for --logo-type file --logo + --file-raw : short for --logo-type file-raw --logo + --data : short for --logo-type data --logo + --data-raw : short for --logo-type data-raw --logo --sixel : short for --logo-type sixel --logo --kitty : short for --logo-type kitty --logo --chafa : short for --logo-type chafa --logo - --file : short for --logo-type file --logo - --raw : short for --logo-type raw --logo Display options: -s,--structure : sets the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. diff --git a/src/fastfetch.c b/src/fastfetch.c index ffbc964a9..3f7f9f829 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -50,13 +50,13 @@ static void constructAndPrintCommandHelpFormat(const char* name, const char* def static inline void printCommandHelp(const char* command) { if(command == NULL) - fputs(FASTFETCH_DATATEXT_HELP, stdout); + puts(FASTFETCH_DATATEXT_HELP); else if(strcasecmp(command, "c") == 0 || strcasecmp(command, "color") == 0) - fputs(FASTFETCH_DATATEXT_HELP_COLOR, stdout); + puts(FASTFETCH_DATATEXT_HELP_COLOR); else if(strcasecmp(command, "format") == 0) - fputs(FASTFETCH_DATATEXT_HELP_FORMAT, stdout); + puts(FASTFETCH_DATATEXT_HELP_FORMAT); else if(strcasecmp(command, "load-config") == 0 || strcasecmp(command, "loadconfig") == 0 || strcasecmp(command, "config") == 0) - fputs(FASTFETCH_DATATEXT_HELP_CONFIG, stdout); + puts(FASTFETCH_DATATEXT_HELP_CONFIG); else if(strcasecmp(command, "os-format") == 0) { constructAndPrintCommandHelpFormat("os", "{3} {12}", 12, @@ -945,10 +945,12 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con "auto", FF_LOGO_TYPE_AUTO, "builtin", FF_LOGO_TYPE_BUILTIN, "file", FF_LOGO_TYPE_FILE, - "raw", FF_LOGO_TYPE_RAW, - "sixel", FF_LOGO_TYPE_SIXEL, - "kitty", FF_LOGO_TYPE_KITTY, - "chafa", FF_LOGO_TYPE_CHAFA, + "file-raw", FF_LOGO_TYPE_FILE_RAW, + "data", FF_LOGO_TYPE_DATA, + "data-raw", FF_LOGO_TYPE_DATA_RAW, + "sixel", FF_LOGO_TYPE_IMAGE_SIXEL, + "kitty", FF_LOGO_TYPE_IMAGE_KITTY, + "chafa", FF_LOGO_TYPE_IMAGE_CHAFA, NULL ); } @@ -985,30 +987,40 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else goto error; } - else if(strcasecmp(key, "--sixel") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_SIXEL; - } - else if(strcasecmp(key, "--kitty") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_KITTY; - } else if(strcasecmp(key, "--file") == 0) { optionParseString(key, value, &instance->config.logo.source); instance->config.logo.type = FF_LOGO_TYPE_FILE; } - else if(strcasecmp(key, "--raw") == 0) + else if(strcasecmp(key, "--file-raw") == 0) { optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_RAW; + instance->config.logo.type = FF_LOGO_TYPE_FILE_RAW; + } + else if(strcasecmp(key, "--data") == 0) + { + optionParseString(key, value, &instance->config.logo.source); + instance->config.logo.type = FF_LOGO_TYPE_DATA; + } + else if(strcasecmp(key, "--data-raw") == 0) + { + optionParseString(key, value, &instance->config.logo.source); + instance->config.logo.type = FF_LOGO_TYPE_DATA_RAW; + } + else if(strcasecmp(key, "--sixel") == 0) + { + optionParseString(key, value, &instance->config.logo.source); + instance->config.logo.type = FF_LOGO_TYPE_IMAGE_SIXEL; + } + else if(strcasecmp(key, "--kitty") == 0) + { + optionParseString(key, value, &instance->config.logo.source); + instance->config.logo.type = FF_LOGO_TYPE_IMAGE_KITTY; } else if(strcasecmp(key, "--chafa") == 0) { optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_CHAFA; + instance->config.logo.type = FF_LOGO_TYPE_IMAGE_CHAFA; } /////////////////// diff --git a/src/fastfetch.h b/src/fastfetch.h index 96dd4a445..36bb4131a 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -30,13 +30,15 @@ static inline void ffUnused(int dummy, ...) { (void) dummy; } typedef enum FFLogoType { - FF_LOGO_TYPE_AUTO, //If something is given, first try builtin, then file. Otherwise detect logo - FF_LOGO_TYPE_BUILTIN, //Builtin ascii art. - FF_LOGO_TYPE_FILE, //Raw text file, printed as is. - FF_LOGO_TYPE_RAW, //Raw text file, printed with color codes replacement. - FF_LOGO_TYPE_SIXEL, //Image file, printed as sixel codes. - FF_LOGO_TYPE_KITTY, //Image file, printed as kitty graphics protocol - FF_LOGO_TYPE_CHAFA //Image file, printed as ascii art using libchafa + FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo + FF_LOGO_TYPE_BUILTIN, //builtin ascii art + FF_LOGO_TYPE_FILE, //text file, printed with color code replacement + FF_LOGO_TYPE_FILE_RAW, //text file, printed as is + FF_LOGO_TYPE_DATA, //text data, printed with color code replacement + FF_LOGO_TYPE_DATA_RAW, //text data, printed as is + FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes. + FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol + FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa } FFLogoType; typedef enum FFBinaryPrefixType diff --git a/src/logo/image/image.c b/src/logo/image/image.c index d927735ad..1acf09b84 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -114,7 +114,7 @@ static void printImagePixels(FFinstance* instance, FFLogoRequestData* requestDat instance->state.logoWidth = requestData->logoCharacterWidth + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; instance->state.logoHeight = requestData->logoCharacterHeight; - if(requestData->type == FF_LOGO_TYPE_KITTY) + if(requestData->type == FF_LOGO_TYPE_IMAGE_KITTY) instance->state.logoHeight -= 1; //Write cache files @@ -346,15 +346,15 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* } bool printSuccessful = false; - if(requestData->type == FF_LOGO_TYPE_CHAFA) + if(requestData->type == FF_LOGO_TYPE_IMAGE_CHAFA) { #ifdef FF_HAVE_CHAFA printSuccessful = printImageChafa(instance, requestData, &imageData); #endif } - else if(requestData->type == FF_LOGO_TYPE_KITTY) + else if(requestData->type == FF_LOGO_TYPE_IMAGE_KITTY) printSuccessful = printImageKitty(instance, requestData, &imageData); - else if(requestData->type == FF_LOGO_TYPE_SIXEL) + else if(requestData->type == FF_LOGO_TYPE_IMAGE_SIXEL) printSuccessful = printImageSixel(instance, requestData, &imageData); ffDestroyImageInfo(imageData.imageInfo); @@ -407,7 +407,7 @@ static bool printCachedChars(FFinstance* instance, FFLogoRequestData* requestDat FFstrbuf content; ffStrbufInitA(&content, 32768); - if(requestData->type == FF_LOGO_TYPE_CHAFA) + if(requestData->type == FF_LOGO_TYPE_IMAGE_CHAFA) readCachedStrbuf(requestData, &content, FF_CACHE_FILE_CHAFA); if(content.length == 0) @@ -440,13 +440,13 @@ static bool printCachedPixel(FFinstance* instance, FFLogoRequestData* requestDat } int fd = -1; - if(requestData->type == FF_LOGO_TYPE_KITTY) + if(requestData->type == FF_LOGO_TYPE_IMAGE_KITTY) { fd = getCacheFD(requestData, FF_CACHE_FILE_KITTY_COMPRESSED); if(fd == -1) fd = getCacheFD(requestData, FF_CACHE_FILE_KITTY_UNCOMPRESSED); } - else if(requestData->type == FF_LOGO_TYPE_SIXEL) + else if(requestData->type == FF_LOGO_TYPE_IMAGE_SIXEL) fd = getCacheFD(requestData, FF_CACHE_FILE_SIXEL); if(fd == -1) @@ -473,7 +473,7 @@ static bool printCachedPixel(FFinstance* instance, FFLogoRequestData* requestDat static bool printCached(FFinstance* instance, FFLogoRequestData* requestData) { - if(requestData->type == FF_LOGO_TYPE_CHAFA) + if(requestData->type == FF_LOGO_TYPE_IMAGE_CHAFA) return printCachedChars(instance, requestData); else return printCachedPixel(instance, requestData); @@ -517,7 +517,7 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) requestData.characterPixelHeight = 1; if( - (type != FF_LOGO_TYPE_CHAFA || instance->config.logo.width == 0 || instance->config.logo.height == 0) && + (type != FF_LOGO_TYPE_IMAGE_CHAFA || instance->config.logo.width == 0 || instance->config.logo.height == 0) && !getCharacterPixelDimensions(&requestData) ) return false; diff --git a/src/logo/logo.c b/src/logo/logo.c index 6abb1b083..3c48e0854 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -266,6 +266,11 @@ static inline void logoPrintDetected(FFinstance* instance) logoPrintStruct(instance, logoGetBuiltinDetected(instance)); } +static void logoPrintData(FFinstance* instance, bool doColorReplacement) { + ffLogoPrintChars(instance, instance->config.logo.source.chars, doColorReplacement); + logoApplyColorsDetected(instance); +} + static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement) { FFstrbuf content; @@ -294,14 +299,18 @@ static bool logoPrintImageIfExists(FFinstance* instance, FFLogoType logo) static void logoPrintKnownType(FFinstance* instance) { - bool successfull; + bool successfull = true; if(instance->config.logo.type == FF_LOGO_TYPE_BUILTIN) successfull = logoPrintBuiltinIfExists(instance, instance->config.logo.source.chars); else if(instance->config.logo.type == FF_LOGO_TYPE_FILE) successfull = logoPrintFileIfExists(instance, true); - else if(instance->config.logo.type == FF_LOGO_TYPE_RAW) + else if(instance->config.logo.type == FF_LOGO_TYPE_FILE_RAW) successfull = logoPrintFileIfExists(instance, false); + else if(instance->config.logo.type == FF_LOGO_TYPE_DATA) + logoPrintData(instance, true); + else if(instance->config.logo.type == FF_LOGO_TYPE_DATA_RAW) + logoPrintData(instance, false); else //image successfull = logoPrintImageIfExists(instance, instance->config.logo.type); @@ -349,7 +358,7 @@ void ffLogoPrint(FFinstance* instance) ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "wayst") == 0; //Try to load the logo as an image. If it succeeds, print it and return. - if(logoPrintImageIfExists(instance, supportsKitty ? FF_LOGO_TYPE_KITTY : FF_LOGO_TYPE_CHAFA)) + if(logoPrintImageIfExists(instance, supportsKitty ? FF_LOGO_TYPE_IMAGE_KITTY : FF_LOGO_TYPE_IMAGE_CHAFA)) return; //Try to load the logo as a file. If it succeeds, print it and return. From b21cfc127a77d4a133c419afce41a10b3d616b7f Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 12 Dec 2022 13:55:19 +0100 Subject: [PATCH 247/311] Termialshell: ignore sh --- src/detection/terminalshell/terminalshell_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 2c3e7319d..80c0d93d1 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -132,6 +132,7 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) //Common programs that are between terminal and own process, but are not the shell if( + strcasecmp(name, "sh") == 0 || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell strcasecmp(name, "sudo") == 0 || strcasecmp(name, "su") == 0 || strcasecmp(name, "doas") == 0 || @@ -149,7 +150,6 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) //Known shells if( strcasecmp(name, "bash") == 0 || - strcasecmp(name, "sh") == 0 || strcasecmp(name, "zsh") == 0 || strcasecmp(name, "ksh") == 0 || strcasecmp(name, "csh") == 0 || From c242001a77d785f4adf1a41827e203af18568ff3 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Mon, 12 Dec 2022 13:58:16 +0100 Subject: [PATCH 248/311] Fix build without chafa --- src/logo/image/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 1acf09b84..13076d10b 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -507,7 +507,7 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) { //Performance optimisation #ifndef FF_HAVE_CHAFA - if(type == FF_LOGO_TYPE_CHAFA) + if(type == FF_LOGO_TYPE_IMAGE_CHAFA) return false; #endif From 3b2c189083aed9489cefd9aee0f148efab078b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 13 Dec 2022 10:57:40 +0800 Subject: [PATCH 249/311] Packages: split brew-cellar and brew-cask (macOS) `brew info` shows number of `brew-cellar` packages only. Split `brew-cellar` out of `brew` to avoid users from confusion. --- presets/verbose | 2 +- src/detection/packages/packages.h | 1 + src/detection/packages/packages_apple.c | 21 ++++++++------------- src/modules/packages.c | 7 +++++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/presets/verbose b/presets/verbose index 3ab55d1c0..e9f09e939 100644 --- a/presets/verbose +++ b/presets/verbose @@ -3,7 +3,7 @@ --kernel-format Sysname: {}; Release: {}; Version: {} --uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {} --processes-format Count: {} ---packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {} +--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {} --shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {} --resolution-format Width: {}; Height: {}; Refresh rate: {} --de-format Process name: {}; Pretty name: {}; Version: {} diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index 1992b8d8d..ca8b3feea 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -9,6 +9,7 @@ typedef struct FFPackagesResult { uint32_t apk; uint32_t brew; + uint32_t brewCask; uint32_t choco; uint32_t dpkg; uint32_t emerge; diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c index e1323e1e5..b8bc8a682 100644 --- a/src/detection/packages/packages_apple.c +++ b/src/detection/packages/packages_apple.c @@ -25,35 +25,30 @@ static uint32_t getNumElements(const char* dirname, unsigned char type) return num_elements; } -static uint32_t countBrewPackages(const char* dirname) +static void countBrewPackages(const char* dirname, FFPackagesResult* result) { FF_STRBUF_AUTO_DESTROY baseDir; ffStrbufInitS(&baseDir, dirname); - uint32_t result = 0; uint32_t baseDirLength = baseDir.length; ffStrbufAppendS(&baseDir, "/Caskroom"); - result += getNumElements(baseDir.chars, DT_DIR); + result->brewCask += getNumElements(baseDir.chars, DT_DIR); ffStrbufSubstrBefore(&baseDir, baseDirLength); ffStrbufAppendS(&baseDir, "/Cellar"); - result += getNumElements(baseDir.chars, DT_DIR); + result->brew += getNumElements(baseDir.chars, DT_DIR); ffStrbufSubstrBefore(&baseDir, baseDirLength); - - return result; } -static uint32_t getBrewPackages() +static void getBrewPackages(FFPackagesResult* result) { const char* prefix = getenv("HOMEBREW_PREFIX"); if(ffStrSet(prefix)) - return countBrewPackages(prefix); + return countBrewPackages(prefix, result); - uint32_t result = 0; - result += countBrewPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/homebrew"); - result += countBrewPackages(FASTFETCH_TARGET_DIR_ROOT"/usr/local"); - return result; + countBrewPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/homebrew", result); + countBrewPackages(FASTFETCH_TARGET_DIR_ROOT"/usr/local", result); } static uint32_t countMacPortsPackages(const char* dirname) @@ -77,6 +72,6 @@ static uint32_t getMacPortsPackages() void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) { FF_UNUSED(instance); - result->brew = getBrewPackages(); + getBrewPackages(result); result->port = getMacPortsPackages(); } diff --git a/src/modules/packages.c b/src/modules/packages.c index 3f9d6d990..799ab0d3c 100644 --- a/src/modules/packages.c +++ b/src/modules/packages.c @@ -3,7 +3,7 @@ #include "detection/packages/packages.h" #define FF_PACKAGES_MODULE_NAME "Packages" -#define FF_PACKAGES_NUM_FORMAT_ARGS 17 +#define FF_PACKAGES_NUM_FORMAT_ARGS 19 void ffPrintPackages(FFinstance* instance) { @@ -51,6 +51,7 @@ void ffPrintPackages(FFinstance* instance) FF_PRINT_PACKAGE(flatpak) FF_PRINT_PACKAGE(snap) FF_PRINT_PACKAGE(brew) + FF_PRINT_PACKAGE_NAME(brewCask, "brew-cask") FF_PRINT_PACKAGE(port) FF_PRINT_PACKAGE(scoop) FF_PRINT_PACKAGE(choco) @@ -78,8 +79,10 @@ void ffPrintPackages(FFinstance* instance) {FF_FORMAT_ARG_TYPE_UINT, &counts->flatpak}, {FF_FORMAT_ARG_TYPE_UINT, &counts->snap}, {FF_FORMAT_ARG_TYPE_UINT, &counts->brew}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->brewCask}, {FF_FORMAT_ARG_TYPE_UINT, &counts->port}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->scoop} + {FF_FORMAT_ARG_TYPE_UINT, &counts->scoop}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->choco}, }); } } From 7e98fa862654de5780c80a7dc72800d80e38a70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 13 Dec 2022 11:10:50 +0800 Subject: [PATCH 250/311] Vulkan: don't require vulkan-loader (macOS) Which also avoids requiring portability_enumeration extension --- .github/workflows/push.yml | 2 +- README.md | 2 +- src/data/config_user.txt | 2 +- src/detection/vulkan.c | 21 ++++++++++----------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 236cd5cbb..fb7522b7d 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -64,7 +64,7 @@ jobs: uses: actions/checkout@v3 - name: install required packages - run: brew install vulkan-loader molten-vk + run: brew install vulkan-headers molten-vk - name: Initialize CodeQL uses: github/codeql-action/init@v2 diff --git a/README.md b/README.md index 5cc094bf4..18189b67a 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ The following libraries are used if present at runtime: ### macOS * [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system. -* [`libvulkan`](https://www.vulkan.org/): Vulkan module. To get it actually working, both loader (`vulkan-loader`) and driver (`molten-vk`) need to be installed. +* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. ### Windows diff --git a/src/data/config_user.txt b/src/data/config_user.txt index fb231eab0..7a3fb1f9c 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -341,7 +341,7 @@ # Sets an user specific path to a library to load. # Must be a valid path to a library. #--lib-PCI /usr/lib/libpci.so -#--lib-vulkan /usr/lib/libvulkan.so +#--lib-vulkan /usr/lib/libvulkan.so (libMoltenVK.dylib on macOS) #--lib-wayland /usr/lib/libwayland-client.so #--lib-xcb-randr /usr/lib/libxcb-randr.so #--lib-xcb /usr/lib/libxcb.so diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 200785892..4119280a7 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -38,7 +38,13 @@ static void applyDriverName(VkPhysicalDeviceDriverProperties* properties, FFstrb static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* result) { - FF_LIBRARY_LOAD(vulkan, &instance->config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed", "libvulkan"FF_LIBRARY_EXTENSION, 2, "vulkan-1"FF_LIBRARY_EXTENSION, -1) + FF_LIBRARY_LOAD(vulkan, &instance->config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed", + #ifdef __APPLE__ + "libMoltenVK"FF_LIBRARY_EXTENSION, -1 + #else + "libvulkan"FF_LIBRARY_EXTENSION, 2, "vulkan-1"FF_LIBRARY_EXTENSION, -1 + #endif + ) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(vulkan, vkGetInstanceProcAddr) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(vulkan, vkCreateInstance) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(vulkan, vkDestroyInstance) @@ -88,16 +94,9 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu .pApplicationInfo = &applicationInfo, .enabledLayerCount = 0, .ppEnabledLayerNames = NULL, - - #if defined(__APPLE__) && defined(VK_KHR_portability_enumeration) - .enabledExtensionCount = 1, - .ppEnabledExtensionNames = (const char* const[]) { VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME }, - .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR - #else - .enabledExtensionCount = 0, - .ppEnabledExtensionNames = NULL, - .flags = 0 - #endif + .enabledExtensionCount = 0, + .ppEnabledExtensionNames = NULL, + .flags = 0 }; VkInstance vkInstance; From c9bc1f830604b1cd22cfd8199cdb6584505fd922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 13 Dec 2022 13:12:13 +0800 Subject: [PATCH 251/311] Vulkan: build with vulkan-loader (macOS) ... so cmake can find it --- .github/workflows/push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index fb7522b7d..236cd5cbb 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -64,7 +64,7 @@ jobs: uses: actions/checkout@v3 - name: install required packages - run: brew install vulkan-headers molten-vk + run: brew install vulkan-loader molten-vk - name: Initialize CodeQL uses: github/codeql-action/init@v2 From b09aa3240ab7a4af34ab3c7dc61c97a58e1fd090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 11:30:50 +0800 Subject: [PATCH 252/311] Global: support `--stat` option for benchmark --- completions/bash | 1 + src/common/init.c | 1 + src/data/config_user.txt | 6 ++++++ src/data/help.txt | 1 + src/fastfetch.c | 18 ++++++++++++++++++ src/fastfetch.h | 1 + 6 files changed, 28 insertions(+) diff --git a/completions/bash b/completions/bash index 7de2b3edf..31f2f7a3c 100644 --- a/completions/bash +++ b/completions/bash @@ -174,6 +174,7 @@ __fastfetch_completion() "--show-errors" "--logo-print-remaining" "--multithreading" + "--stat" "--allow-slow-operations" "--unbuffered" "--disable-linewrap" diff --git a/src/common/init.c b/src/common/init.c index c86285b70..51de9e18a 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -177,6 +177,7 @@ static void defaultConfig(FFinstance* instance) instance->config.glType = FF_GL_TYPE_AUTO; instance->config.pipe = false; instance->config.multithreading = true; + instance->config.stat = false; initModuleArg(&instance->config.os); initModuleArg(&instance->config.host); diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 7a3fb1f9c..f7a1be09d 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -33,6 +33,12 @@ # Default is true. #--multithreading true +# Print stat option: +# Sets if fastfetch should print time usage (in ms) for individual modules. +# Must be true or false. +# Default is false. +#--stat true + # Disable stdout buffer option: # Sets if fastfetch should disable application buffer of stdout. Mainly for debugging purpose. # Must be true or false. diff --git a/src/data/help.txt b/src/data/help.txt index cd0c36168..40d9fd8d4 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -18,6 +18,7 @@ General options: --nocache : don't use cached values, but also don't overwrite existing ones --load-config : load a config file or a preset (+) --multithreading : use multiple threads to detect values + --stat : print time usage (in ms) for individual modules --allow-slow-operations : allow operations that are usually very slow for more detailed output --unbuffered : disable stdout application buffer --escape-bedrock : on bedrock linux, sets if it should escape the bedrock jail or not diff --git a/src/fastfetch.c b/src/fastfetch.c index 3f7f9f829..aa3401d9e 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -3,10 +3,12 @@ #include "common/printing.h" #include "common/parsing.h" #include "common/io.h" +#include "common/time.h" #include #include #include +#include #ifdef WIN32 #include "util/windows/getline.h" @@ -907,6 +909,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseConfigFile(instance, data, key, value); else if(strcasecmp(key, "--thread") == 0 || strcasecmp(key, "--multithreading") == 0) instance->config.multithreading = optionParseBoolean(value); + else if(strcasecmp(key, "--stat") == 0) + instance->config.stat = optionParseBoolean(value); else if(strcasecmp(key, "--allow-slow-operations") == 0) instance->config.allowSlowOperations = optionParseBoolean(value); else if(strcasecmp(key, "--unbuffered") == 0) @@ -1412,8 +1416,22 @@ int main(int argc, const char** argv) uint32_t colonIndex = ffStrbufNextIndexC(&data.structure, startIndex, ':'); data.structure.chars[colonIndex] = '\0'; + uint64_t ms = 0; + if(__builtin_expect(instance.config.stat, false)) + ms = ffTimeGetTick(); + parseStructureCommand(&instance, &data, data.structure.chars + startIndex); + if(__builtin_expect(instance.config.stat, false)) + { + char str[32]; + int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ffTimeGetTick() - ms); + if(instance.config.pipe) + puts(str); + else + printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load + } + startIndex = colonIndex + 1; } diff --git a/src/fastfetch.h b/src/fastfetch.h index 36bb4131a..bbd19122c 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -94,6 +94,7 @@ typedef struct FFconfig FFGLType glType; bool pipe; //disables logo and all escape sequences bool multithreading; + bool stat; FFModuleArgs os; FFModuleArgs host; From 54912df23768a0bfcdbf5dd76bb0c9f9792e3f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 13:52:16 +0800 Subject: [PATCH 253/311] Option: enable `--show-errors` if `--stat` is set --- src/data/config_user.txt | 3 ++- src/fastfetch.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/data/config_user.txt b/src/data/config_user.txt index f7a1be09d..7194b266b 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -34,7 +34,8 @@ #--multithreading true # Print stat option: -# Sets if fastfetch should print time usage (in ms) for individual modules. +# Sets if fastfetch should print time usage (in ms) for individual modules +# If true, it will also enable --show-errors # Must be true or false. # Default is false. #--stat true diff --git a/src/fastfetch.c b/src/fastfetch.c index aa3401d9e..28a1caa4d 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -910,7 +910,10 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else if(strcasecmp(key, "--thread") == 0 || strcasecmp(key, "--multithreading") == 0) instance->config.multithreading = optionParseBoolean(value); else if(strcasecmp(key, "--stat") == 0) - instance->config.stat = optionParseBoolean(value); + { + if((instance->config.stat = optionParseBoolean(value))) + instance->config.showErrors = true; + } else if(strcasecmp(key, "--allow-slow-operations") == 0) instance->config.allowSlowOperations = optionParseBoolean(value); else if(strcasecmp(key, "--unbuffered") == 0) From c9e9ec3a8026c477f859f22893891b6e03c26b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 14:10:42 +0800 Subject: [PATCH 254/311] CI: print time usage --- .github/workflows/push.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 236cd5cbb..dca1880dc 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -35,10 +35,10 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - name: run flashfetch - run: ./flashfetch + run: time ./flashfetch - name: run tests run: ctest @@ -81,10 +81,10 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - name: run flashfetch - run: ./flashfetch + run: time ./flashfetch - name: run tests run: ctest @@ -113,8 +113,8 @@ jobs: run: | cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . cmake --build . --target package - ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - ./flashfetch + time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + time ./flashfetch ctest - name: upload artifacts @@ -180,10 +180,10 @@ jobs: run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - name: run flashfetch - run: ./flashfetch + run: time ./flashfetch - name: run tests run: ctest @@ -254,10 +254,10 @@ jobs: run: cp /mingw64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered - name: run flashfetch - run: ./flashfetch + run: time ./flashfetch - name: run tests run: ctest From d151901049417aabe44e56a3511e742b86f63506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 15:40:32 +0800 Subject: [PATCH 255/311] Common: improve resolution of `ffTimeGetTick` --- src/common/time.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/common/time.h b/src/common/time.h index a765e7834..797461cbd 100644 --- a/src/common/time.h +++ b/src/common/time.h @@ -6,20 +6,23 @@ #include #ifdef _WIN32 #include - #include + #include #else - #include #include #endif static inline uint64_t ffTimeGetTick() //In msec { #ifdef _WIN32 - return GetTickCount64(); + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + LARGE_INTEGER start; + QueryPerformanceCounter(&start); + return (uint64_t)(start.QuadPart * 1000 / frequency.QuadPart); #else - struct timeval timeNow; - gettimeofday(&timeNow, NULL); - return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000)); + struct timespec timeNow; + clock_gettime(CLOCK_MONOTONIC, &timeNow); + return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000)); #endif } From e4a5194115ebfd1e0e41324516c3ef91b5fc9997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 16:27:04 +0800 Subject: [PATCH 256/311] Rework stdout buffering on Windows. Windows doesn't support line-buffering. We enable full-buffering instead and flush buffers per module. --- .github/workflows/push.yml | 12 ++++++------ CMakeLists.txt | 6 ++++++ completions/bash | 1 - src/common/init.c | 6 ++++++ src/data/config_user.txt | 6 ------ src/data/help.txt | 1 - src/fastfetch.c | 9 ++++----- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index dca1880dc..c798e81d5 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -35,7 +35,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -81,7 +81,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -113,7 +113,7 @@ jobs: run: | cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . cmake --build . --target package - time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all time ./flashfetch ctest @@ -180,7 +180,7 @@ jobs: run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -242,7 +242,7 @@ jobs: languages: c, cpp - name: configure project - run: env PKG_CONFIG_PATH=/mingw64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . + run: env PKG_CONFIG_PATH=/mingw64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_BUFFER=Off . - name: build project run: cmake --build . @@ -254,7 +254,7 @@ jobs: run: cp /mingw64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all --unbuffered + run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch diff --git a/CMakeLists.txt b/CMakeLists.txt index 9932e29a1..c733fbe72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ 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(ENABLE_BUFFER "Enable stdout buffer" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" 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) @@ -639,6 +640,11 @@ if(ENABLE_THREADS) endif() endif() + +if(ENABLE_BUFFER) + target_compile_definitions(libfastfetch PRIVATE FF_ENABLE_BUFFER) +endif() + if(APPLE) target_link_libraries(libfastfetch PRIVATE "-framework CoreFoundation" diff --git a/completions/bash b/completions/bash index 31f2f7a3c..ca9e760ef 100644 --- a/completions/bash +++ b/completions/bash @@ -176,7 +176,6 @@ __fastfetch_completion() "--multithreading" "--stat" "--allow-slow-operations" - "--unbuffered" "--disable-linewrap" "--hide-cursor" "--cpu-temp" diff --git a/src/common/init.c b/src/common/init.c index 51de9e18a..b81b2933f 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -354,6 +354,9 @@ void ffStart(FFinstance* instance) ffHideCursor = instance->config.hideCursor && !instance->config.pipe; #ifdef _WIN32 + #ifdef FF_ENABLE_BUFFER + setvbuf(stdout, NULL, _IOFBF, 4096); + #endif SetConsoleCtrlHandler(consoleHandler, TRUE); HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode = 0; @@ -361,6 +364,9 @@ void ffStart(FFinstance* instance) SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); SetConsoleOutputCP(CP_UTF8); #else + #ifndef FF_ENABLE_BUFFER + setvbuf(stdout, NULL, _IONBF, 0); + #endif struct sigaction action = { .sa_handler = exitSignalHandler }; sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 7194b266b..fe65a9ee4 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -40,12 +40,6 @@ # Default is false. #--stat true -# Disable stdout buffer option: -# Sets if fastfetch should disable application buffer of stdout. Mainly for debugging purpose. -# Must be true or false. -# Default is false. -#--unbuffered false - # Slow operations option: # Sets if fastfetch is allowed to use known slow operations to detect more / better values. # Must be true or false. diff --git a/src/data/help.txt b/src/data/help.txt index 40d9fd8d4..f6579cfde 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -20,7 +20,6 @@ General options: --multithreading : use multiple threads to detect values --stat : print time usage (in ms) for individual modules --allow-slow-operations : allow operations that are usually very slow for more detailed output - --unbuffered : disable stdout application buffer --escape-bedrock : on bedrock linux, sets if it should escape the bedrock jail or not --pipe : disable logo and all escape sequences diff --git a/src/fastfetch.c b/src/fastfetch.c index 28a1caa4d..66c2ebb40 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -916,11 +916,6 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con } else if(strcasecmp(key, "--allow-slow-operations") == 0) instance->config.allowSlowOperations = optionParseBoolean(value); - else if(strcasecmp(key, "--unbuffered") == 0) - { - if(optionParseBoolean(value)) - setvbuf(stdout, NULL, _IONBF, 0); - } else if(strcasecmp(key, "--escape-bedrock") == 0) instance->config.escapeBedrock = optionParseBoolean(value); else if(strcasecmp(key, "--pipe") == 0) @@ -1435,6 +1430,10 @@ int main(int argc, const char** argv) printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load } + #if defined(_WIN32) && defined(FF_ENABLE_BUFFER) + fflush(stdout); + #endif + startIndex = colonIndex + 1; } From 6710967d1932c0a192375e4230c500a9172ab6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 16:46:52 +0800 Subject: [PATCH 257/311] README: update notes for Windows 10- --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 18189b67a..becaae689 100644 --- a/README.md +++ b/README.md @@ -12,16 +12,16 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for ## Customization -With customization and speed being two competing goals, this project actually builds two executables. -The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `~/.config/fastfetch/config.conf`. To view the available options run `fastfetch --help`. -The second executable being built is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c). -At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference. +With customization and speed being two competing goals, this project actually builds two executables. +The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `~/.config/fastfetch/config.conf`. To view the available options run `fastfetch --help`. +The second executable being built is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c). +At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference. There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config `. They may also serve as a good example for format arguments. ## Dependencies -Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions. +Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions. The following libraries are used if present at runtime: @@ -62,7 +62,7 @@ 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. +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). Fastfetch on Windows targets [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment), which is not installed On Windows 10- by default. If you get errors like `ucrtbase.dll is missing`, try upgrading your system with `Windows Update` or downloading `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) which targets the ancient MSVCRT. ### Android @@ -109,7 +109,7 @@ Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, Deepin Te ## Building -fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are: +fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are: ```bash mkdir -p build cd build From 338cc1db40afeeb20b20888d8e928e1895d5dc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 16:50:44 +0800 Subject: [PATCH 258/311] Add back trailing white spaces which are unexpectedly removed by IDE This partially reverts commit 6710967d1932c0a192375e4230c500a9172ab6e6. --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index becaae689..6ad3fb643 100644 --- a/README.md +++ b/README.md @@ -12,16 +12,16 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for ## Customization -With customization and speed being two competing goals, this project actually builds two executables. -The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `~/.config/fastfetch/config.conf`. To view the available options run `fastfetch --help`. -The second executable being built is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c). -At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference. +With customization and speed being two competing goals, this project actually builds two executables. +The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `~/.config/fastfetch/config.conf`. To view the available options run `fastfetch --help`. +The second executable being built is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c). +At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference. There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config `. They may also serve as a good example for format arguments. ## Dependencies -Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions. +Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions. The following libraries are used if present at runtime: @@ -109,7 +109,7 @@ Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, Deepin Te ## Building -fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are: +fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are: ```bash mkdir -p build cd build From d601cc823c6cafa887e0f84b76fbf5d4dd40ee4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 14 Dec 2022 19:03:01 +0800 Subject: [PATCH 259/311] DisplayServer: make 3rd party window manager plugin detection a slow operation (macOS) The display server of macOS is [Quartz Compositor](https://en.wikipedia.org/wiki/Quartz_Compositor), not other 3rd party apps. --- .../displayserver/displayserver_apple.c | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index 96bdf3d2e..4d0d802c2 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -31,7 +31,7 @@ static void detectResolution(FFDisplayServerResult* ds) } } -static void detectWM(FFDisplayServerResult* ds) +static void detectWMPlugin(FFstrbuf* name) { int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; u_int requestLength = sizeof(request) / sizeof(*request); @@ -54,9 +54,8 @@ static void detectWM(FFDisplayServerResult* ds) strcasecmp(comm, "rectangle") != 0 ) continue; - ffStrbufAppendS(&ds->wmProcessName, comm); - ffStrbufAppendS(&ds->wmPrettyName, comm); - ds->wmPrettyName.chars[0] = (char) toupper(ds->wmPrettyName.chars[0]); + ffStrbufAppendS(name, comm); + name->chars[0] = (char) toupper(name->chars[0]); break; } @@ -67,19 +66,21 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins { FF_UNUSED(instance); - ffStrbufInit(&ds->wmProcessName); - ffStrbufInit(&ds->wmPrettyName); - ffStrbufInitA(&ds->wmProtocolName, 0); - detectWM(ds); - if(ds->wmProcessName.length == 0) + ffStrbufInitS(&ds->wmProcessName, "quartz"); + ffStrbufInitS(&ds->wmPrettyName, "Quartz Compositor"); + ffStrbufInit(&ds->wmProtocolName); + + if(instance->config.allowSlowOperations) { - ffStrbufAppendS(&ds->wmProcessName, "quartz"); - ffStrbufAppendS(&ds->wmPrettyName, "Quartz Compositor"); + FF_STRBUF_AUTO_DESTROY name; + detectWMPlugin(&name); + if(name.length) + ffStrbufAppendF(&ds->wmPrettyName, " (with %s)", name.chars); } ffStrbufInit(&ds->deProcessName); ffStrbufInit(&ds->dePrettyName); - ffStrbufInitA(&ds->deVersion, 0); + ffStrbufInit(&ds->deVersion); ffStrbufAppendS(&ds->deProcessName, "aqua"); ffStrbufAppendS(&ds->dePrettyName, "Aqua"); From 7640042905dd103b921eaa847d0ddc26c6f71f00 Mon Sep 17 00:00:00 2001 From: Jack Gannon Date: Thu, 15 Dec 2022 16:31:33 +0000 Subject: [PATCH 260/311] add enso logo Added Enso Logo in `src/logo/builtin.c` Added Enso in `README.md` --- README.md | 2 +- src/logo/builtin.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ad3fb643..8202233b4 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Vanilla, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Devuan, Deepin, Endeavour, Enso, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Vanilla, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 43167ef6a..720d21ede 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -746,6 +746,39 @@ static const FFlogo* getLogoEndeavour() FF_LOGO_RETURN } +static const FFlogo* getLogoEnso() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("enso", "uqc") + FF_LOGO_LINES( + " .:--==--:. \n" + " :=*#############*+-. \n" + " .+##################*##*: \n" + " .*##########+==-==++*####*##- \n" + " =########=: .-+**#***. \n" + " *#######- ++*#**. \n" + " +######+ -*+#** \n" + " :######* .*+**= \n" + " *######: --#*# \n" + " ####### +++#. \n" + " #######. ++=*. \n" + " *######+ .-+*+ \n" + " :#######- -:*+: \n" + " =#######*. :.*+- \n" + " +########*- :*=- \n" + " =###########+=: =+=: \n" + " .+#############. .-==: \n" + " .=###########= ..:--:. \n" + " .-+######+ \n" + ) + FF_LOGO_COLORS( + "37" //white + ) + FF_LOGO_COLOR_KEYS("37"); //white + FF_LOGO_COLOR_TITLE("37"); //white + FF_LOGO_RETURN +} + static const FFlogo* getLogoFedora() { FF_LOGO_INIT @@ -2287,6 +2320,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoDebianSmall, getLogoDeepin, getLogoEndeavour, + getLogoEnso, getLogoFedora, getLogoFedoraSmall, getLogoFedoraOld, From a3cb6608ceaa6980599bcd6e6a0c5c23da7aa74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 16 Dec 2022 11:21:14 +0800 Subject: [PATCH 261/311] Locale: refactor --- CMakeLists.txt | 1 + src/detection/locale/locale.c | 60 +++++++++++++++++++++++++++++++++++ src/detection/locale/locale.h | 10 ++++++ src/modules/locale.c | 60 ++++------------------------------- 4 files changed, 77 insertions(+), 54 deletions(-) create mode 100644 src/detection/locale/locale.c create mode 100644 src/detection/locale/locale.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c733fbe72..e3046731b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,6 +239,7 @@ set(LIBFASTFETCH_SRC src/detection/font/font.c src/detection/gpu/gpu.c src/detection/host/host.c + src/detection/locale/locale.c src/detection/media/media.c src/detection/memory/memory.c src/detection/os/os.c diff --git a/src/detection/locale/locale.c b/src/detection/locale/locale.c new file mode 100644 index 000000000..6108f7e51 --- /dev/null +++ b/src/detection/locale/locale.c @@ -0,0 +1,60 @@ +#include "detection/locale/locale.h" + +#include "common/properties.h" +#include "common/parsing.h" +#include +#include + +static void getLocaleFromEnv(FFstrbuf* locale) +{ + ffStrbufAppendS(locale, getenv("LANG")); + if(locale->length > 0) + return; + + ffStrbufAppendS(locale, getenv("LC_ALL")); + if(locale->length > 0) + return; + + ffStrbufAppendS(locale, getenv("LC_MESSAGES")); +} + +static void getLocaleFromStdFn(FFstrbuf* locale) +{ + ffStrbufAppendS(locale, setlocale(LC_ALL, NULL)); + + #ifdef LC_MESSAGES + if(locale->length > 0) + return; + + ffStrbufAppendS(locale, setlocale(LC_MESSAGES, NULL)); + #endif +} + +void ffDetectLocale(FFstrbuf* result) +{ + #if !(defined(__APPLE__) || defined(_WIN32)) + + //Ubuntu (and deriviates) use a non standard locale file. + //Parse it first, because on distributions where it exists, it takes precedence. + //Otherwise use the standard etc/locale.conf file. + ffParsePropFile(FASTFETCH_TARGET_DIR_ETC"/default/locale", "LANG =", result); + + if(result->length > 0) + return; + + ffParsePropFile(FASTFETCH_TARGET_DIR_ETC"/locale.conf", "LANG =", result); + if(result->length > 0) + return; + + #endif + + #ifndef _WIN32 + + getLocaleFromEnv(result); + if(result->length > 0) + return; + + #endif + + getLocaleFromStdFn(result); +} diff --git a/src/detection/locale/locale.h b/src/detection/locale/locale.h new file mode 100644 index 000000000..6ca84ab6f --- /dev/null +++ b/src/detection/locale/locale.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_locale_locale +#define FF_INCLUDED_detection_locale_locale + +#include "fastfetch.h" + +void ffDetectLocale(FFstrbuf* result); + +#endif diff --git a/src/modules/locale.c b/src/modules/locale.c index dc2b2b650..cd8f0cd5f 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -1,68 +1,20 @@ #include "fastfetch.h" -#include "common/properties.h" -#include "common/printing.h" #include "common/caching.h" -#include "common/parsing.h" - -#include -#include +#include "common/printing.h" +#include "detection/locale/locale.h" #define FF_LOCALE_MODULE_NAME "Locale" #define FF_LOCALE_NUM_FORMAT_ARGS 1 -static void getLocaleFromEnv(FFstrbuf* locale) -{ - ffStrbufAppendS(locale, getenv("LANG")); - if(locale->length > 0) - return; - - ffStrbufAppendS(locale, getenv("LC_ALL")); - if(locale->length > 0) - return; - - ffStrbufAppendS(locale, getenv("LC_MESSAGES")); -} - -static void getLocaleFromCmd(FFstrbuf* locale) -{ - ffStrbufAppendS(locale, setlocale(LC_ALL, NULL)); - - #ifdef LC_MESSAGES - if(locale->length > 0) - return; - - ffStrbufAppendS(locale, setlocale(LC_MESSAGES, NULL)); - #endif -} - void ffPrintLocale(FFinstance* instance) { - if(ffPrintFromCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.locale, FF_LOCALE_NUM_FORMAT_ARGS)) + if(ffPrintFromCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.locale, FF_LOCALE_NUM_FORMAT_ARGS)) return; - FFstrbuf locale; + FFstrbuf locale; ffStrbufInit(&locale); - //Ubuntu (and deriviates) use a non standard locale file. - //Parse it first, because on distributions where it exists, it takes precedence. - //Otherwise use the standard etc/locale.conf file. - ffParsePropFile(FASTFETCH_TARGET_DIR_ETC"/default/locale", "LANG =", &locale); - - if(locale.length == 0) - { - ffParsePropFile(FASTFETCH_TARGET_DIR_ETC"/locale.conf", "LANG =", &locale); - } - - if(locale.length == 0) - { - getLocaleFromEnv(&locale); - } - - if(locale.length == 0) - { - getLocaleFromCmd(&locale); - } - + ffDetectLocale(&locale); if(locale.length == 0) { ffPrintError(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale, "No locale found"); @@ -73,5 +25,5 @@ void ffPrintLocale(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &locale} }); - ffStrbufDestroy(&locale); + ffStrbufDestroy(&locale); } From eeb008f50560768e787506fe60a20f83feaa7517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 17 Dec 2022 12:20:18 +0800 Subject: [PATCH 262/311] Global: replace all ".so" to FF_LIBRARY_EXTENSION ... no matter whether the libraries are linux specific or not --- src/common/settings.c | 8 ++++---- src/detection/displayserver/linux/wayland.c | 2 +- src/detection/displayserver/linux/xcb.c | 4 ++-- src/detection/displayserver/linux/xlib.c | 4 ++-- src/detection/gpu/gpu_linux.c | 2 +- src/detection/media/media_linux.c | 2 +- src/detection/opengl/opengl_linux.c | 6 +++--- src/detection/packages/packages_linux.c | 2 +- src/logo/image/im6.c | 2 +- src/logo/image/im7.c | 2 +- src/logo/image/image.c | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/common/settings.c b/src/common/settings.c index 1222aa490..38cbd4b36 100644 --- a/src/common/settings.c +++ b/src/common/settings.c @@ -91,7 +91,7 @@ typedef struct GSettingsData static const GSettingsData* getGSettingsData(const FFinstance* instance) { - FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0.so", 1); + FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup) FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key) @@ -163,7 +163,7 @@ typedef struct DConfData static const DConfData* getDConfData(const FFinstance* instance) { - FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf.so", 2); + FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2); FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full) FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new) @@ -233,7 +233,7 @@ typedef struct XFConfData static const XFConfData* getXFConfData(const FFinstance* instance) { - FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0.so", 4); + FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4); FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get) FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property) @@ -294,7 +294,7 @@ typedef struct SQLiteData static const SQLiteData* getSQLiteData(const FFinstance* instance) { - FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance->config.libSQLite3, "libsqlite3.so", 1); + FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance->config.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2) FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2) diff --git a/src/detection/displayserver/linux/wayland.c b/src/detection/displayserver/linux/wayland.c index 166ec25b2..37891149c 100644 --- a/src/detection/displayserver/linux/wayland.c +++ b/src/detection/displayserver/linux/wayland.c @@ -102,7 +102,7 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(wayland, &instance->config.libWayland, false, "libwayland-client.so", 1) + FF_LIBRARY_LOAD(wayland, &instance->config.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false) diff --git a/src/detection/displayserver/linux/xcb.c b/src/detection/displayserver/linux/xcb.c index 22d5fa87c..692be7808 100644 --- a/src/detection/displayserver/linux/xcb.c +++ b/src/detection/displayserver/linux/xcb.c @@ -91,7 +91,7 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(xcb, &instance->config.libXcb, , "libxcb.so", 2) + FF_LIBRARY_LOAD(xcb, &instance->config.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,) FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,) FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,) @@ -326,7 +326,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen) void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(xcbRandr, &instance->config.libXcbRandr, , "libxcb-randr.so", 1) + FF_LIBRARY_LOAD(xcbRandr, &instance->config.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,) FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,) FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,) diff --git a/src/detection/displayserver/linux/xlib.c b/src/detection/displayserver/linux/xlib.c index b0748bde8..108de5946 100644 --- a/src/detection/displayserver/linux/xlib.c +++ b/src/detection/displayserver/linux/xlib.c @@ -59,7 +59,7 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(x11, &instance->config.libX11, , "libX11.so", 7, "libX11-xcb.so", 2) + FF_LIBRARY_LOAD(x11, &instance->config.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,) FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,) @@ -263,7 +263,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(xrandr, &instance->config.libXrandr, , "libXrandr.so", 3) + FF_LIBRARY_LOAD(xrandr, &instance->config.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3) FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,) FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,) diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 17b40d28a..50580a898 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -204,7 +204,7 @@ static const char* pciDetectGPUs(const FFinstance* instance, FFlist* gpus) { PCIData pci; - FF_LIBRARY_LOAD(libpci, &instance->config.libPCI, "dlopen libpci.so failed", "libpci.so", 4); + FF_LIBRARY_LOAD(libpci, &instance->config.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus); diff --git a/src/detection/media/media_linux.c b/src/detection/media/media_linux.c index 60b407b99..f8d410593 100644 --- a/src/detection/media/media_linux.c +++ b/src/detection/media/media_linux.c @@ -295,7 +295,7 @@ static const char* getMedia(const FFinstance* instance, FFMediaResult* result) { DBusData data; - FF_LIBRARY_LOAD(dbus, &instance->config.libDBus, "dlopen dbus failed", "libdbus-1.so", 4); + FF_LIBRARY_LOAD(dbus, &instance->config.libDBus, "dlopen dbus failed", "libdbus-1" FF_LIBRARY_EXTENSION, 4); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dbus, dbus_bus_get) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_new_method_call) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_init) diff --git a/src/detection/opengl/opengl_linux.c b/src/detection/opengl/opengl_linux.c index e2d17f03d..d95062ad5 100644 --- a/src/detection/opengl/opengl_linux.c +++ b/src/detection/opengl/opengl_linux.c @@ -120,7 +120,7 @@ static const char* eglPrint(FFinstance* instance, FFOpenGLResult* result) { EGLData eglData; - FF_LIBRARY_LOAD(egl, &instance->config.libEGL, "dlopen egl failed", "libEGL.so", 1); + FF_LIBRARY_LOAD(egl, &instance->config.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize); @@ -238,7 +238,7 @@ static const char* glxPrint(FFinstance* instance, FFOpenGLResult* result) { GLXData data; - FF_LIBRARY_LOAD(glx, &instance->config.libGLX, "dlopen glx failed", "libGLX.so", 1); + FF_LIBRARY_LOAD(glx, &instance->config.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual); @@ -304,7 +304,7 @@ static const char* osMesaPrint(FFinstance* instance, FFOpenGLResult* result) { OSMesaData data; - FF_LIBRARY_LOAD(osmesa, &instance->config.libOSMesa, "dlopen osmesa failed", "libOSMesa.so", 8); + FF_LIBRARY_LOAD(osmesa, &instance->config.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent); diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index e2cab221d..254565ed2 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -217,7 +217,7 @@ static uint32_t getSnap(FFstrbuf* baseDir) static uint32_t getRpmFromLibrpm(const FFinstance* instance) { - FF_LIBRARY_LOAD(rpm, &instance->config.librpm, 0, "librpm.so", 12) + FF_LIBRARY_LOAD(rpm, &instance->config.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12) FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0) FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0) FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0) diff --git a/src/logo/image/im6.c b/src/logo/image/im6.c index f6cbf2de0..a235bb867 100644 --- a/src/logo/image/im6.c +++ b/src/logo/image/im6.c @@ -14,7 +14,7 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex FFLogoImageResult ffLogoPrintImageIM6(FFinstance* instance, FFLogoRequestData* requestData) { - FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI.so", 8, "libMagickCore-6.Q16.so", 8) + FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR); FFIMData imData; diff --git a/src/logo/image/im7.c b/src/logo/image/im7.c index db4043465..2d1408f23 100644 --- a/src/logo/image/im7.c +++ b/src/logo/image/im7.c @@ -14,7 +14,7 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex FFLogoImageResult ffLogoPrintImageIM7(FFinstance* instance, FFLogoRequestData* requestData) { - FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI.so", 11, "libMagickCore-7.Q16.so", 11) + FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR); FFIMData imData; diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 13076d10b..87523dc95 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -25,7 +25,7 @@ static bool compressBlob(const FFinstance* instance, void** blob, size_t* length) { - FF_LIBRARY_LOAD(zlib, &instance->config.libZ, false, "libz.so", 2) + FF_LIBRARY_LOAD(zlib, &instance->config.libZ, false, "libz" FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL(zlib, compressBound, false) FF_LIBRARY_LOAD_SYMBOL(zlib, compress2, false) @@ -216,7 +216,7 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData #include static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) { - FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa.so", 1) + FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_add_by_tags, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_new, false) From 047b32e7d93f85eb2b7490cfc3e6bd1f092d3e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 16 Dec 2022 00:14:21 +0800 Subject: [PATCH 263/311] CpuUsage: make the result more accurate --- src/detection/cpuUsage/cpuUsage_windows.c | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/detection/cpuUsage/cpuUsage_windows.c b/src/detection/cpuUsage/cpuUsage_windows.c index bf4cc7644..d4ffbd2ca 100644 --- a/src/detection/cpuUsage/cpuUsage_windows.c +++ b/src/detection/cpuUsage/cpuUsage_windows.c @@ -1,6 +1,45 @@ #include "fastfetch.h" #include "cpuUsage.h" +#ifdef FF_USE_WIN_NTAPI + +#include "util/mallocHelper.h" + +#include +#include + +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) +{ + ULONG size = 0; + if(NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH) + return "NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL) failed"; + + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* FF_AUTO_FREE pinfo = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)malloc(size); + if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessorPerformanceInformation, pinfo, size, &size))) + return "NtQuerySystemInformation(SystemProcessorPerformanceInformation, size) failed"; + + *inUseAll = *totalAll = 0; + + for (uint32_t i = 0; i < size / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); ++i) + { + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* coreInfo = pinfo + i; + + // KernelTime includes idle time. + LONGLONG dpcTime = coreInfo->Reserved1[0].QuadPart; + LONGLONG interruptTime = coreInfo->Reserved1[1].QuadPart; + coreInfo->KernelTime.QuadPart -= coreInfo->IdleTime.QuadPart; + coreInfo->KernelTime.QuadPart += dpcTime + interruptTime; + + LONGLONG inUse = coreInfo->UserTime.QuadPart + coreInfo->KernelTime.QuadPart; + *inUseAll += (uint64_t)inUse; + *totalAll += (uint64_t)(inUse + coreInfo->IdleTime.QuadPart); + } + + return NULL; +} + +#else + #include static inline uint64_t fileTimeToUint64(const FILETIME* ft) { @@ -19,3 +58,5 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) *inUseAll = *totalAll - fileTimeToUint64(&idleTime); return NULL; } + +#endif From 27fb0c6c061aa67e362498a6a66ebc019bc151fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 16 Dec 2022 02:12:13 +0800 Subject: [PATCH 264/311] Battery: improve performance (Windows) --- CMakeLists.txt | 1 + src/detection/battery/battery_windows.c | 221 +++++++++++++----------- 2 files changed, 124 insertions(+), 98 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3046731b..7f49a1265 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -671,6 +671,7 @@ elseif(WIN32) PRIVATE "setupapi" PRIVATE "dxgi" PRIVATE "wtsapi32" + PRIVATE "powrprof" ) if(USE_WIN_NTAPI) target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI) diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c index 37822fe5e..ca8c60991 100644 --- a/src/detection/battery/battery_windows.c +++ b/src/detection/battery/battery_windows.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include static inline void wrapCloseHandle(HANDLE* handle) { @@ -19,114 +21,137 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* 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++) + if(instance->config.allowSlowOperations) { - 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"); + //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++) { - 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)) - ffStrbufSetWS(&battery->modelName, name); - } + SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) }; + if(!SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did)) + break; - { - 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)) - ffStrbufSetWS(&battery->manufacturer, name); - } + 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 - 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; - } + pdidd->cbSize = sizeof(*pdidd); + if(!SetupDiGetDeviceInterfaceDetailW(hdev, &did, pdidd, cbRequired, &cbRequired, NULL)) + continue; - { - 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; + 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 - battery->capacity = 0; + ffStrbufInitS(&battery->technology, "Unknown"); - 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, ','); + { + 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)) + ffStrbufSetWS(&battery->modelName, name); + } + + { + 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)) + ffStrbufSetWS(&battery->manufacturer, name); + } + + 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_CHARGING) + ffStrbufAppendS(&battery->status, "Charging"); + if(bs.PowerState & BATTERY_CRITICAL) + ffStrbufAppendS(&battery->status, "Critical, "); + ffStrbufTrimRight(&battery->status, ' '); + ffStrbufTrimRight(&battery->status, ','); + } } + } + else + { + SYSTEM_BATTERY_STATE info; + if (NT_SUCCESS(CallNtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent) + { + BatteryResult* battery = (BatteryResult*)ffListAdd(results); + ffStrbufInit(&battery->modelName); + ffStrbufInit(&battery->manufacturer); + ffStrbufInit(&battery->technology); + ffStrbufInit(&battery->status); + battery->temperature = 0.0/0.0; + battery->capacity = info.RemainingCapacity * 100.0 / info.MaxCapacity; + if(info.AcOnLine) + { + ffStrbufAppendS(&battery->status, "AC Connected"); + if(info.Charging) + ffStrbufAppendS(&battery->status, ", Charging"); + } + else if(info.Discharging) + ffStrbufAppendS(&battery->status, "Discharging"); + } } return NULL; From 6a49ae60a13579f8e6a522cbb62f9069ba513087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 17 Dec 2022 12:34:21 +0800 Subject: [PATCH 265/311] Locale: silence warnings (Windows) --- src/detection/locale/locale.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/locale/locale.c b/src/detection/locale/locale.c index 6108f7e51..7b9e085cf 100644 --- a/src/detection/locale/locale.c +++ b/src/detection/locale/locale.c @@ -5,6 +5,7 @@ #include #include +__attribute__((__unused__)) static void getLocaleFromEnv(FFstrbuf* locale) { ffStrbufAppendS(locale, getenv("LANG")); From ff6e98205004225d6c7271dbcfb9a21f417c75f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 17 Dec 2022 11:39:10 +0800 Subject: [PATCH 266/311] Global: remove caching except image caching --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/workflows/push.yml | 10 +- CMakeLists.txt | 1 - completions/bash | 2 - presets/devinfo | 1 - src/common/caching.c | 327 --------------------------- src/common/caching.h | 33 --- src/common/init.c | 37 --- src/data/config_user.txt | 1 - src/data/help.txt | 2 - src/detection/cpu/cpu.c | 27 +-- src/detection/cpu/cpu_apple.c | 35 ++- src/detection/cpu/cpu_bsd.c | 5 +- src/detection/cpu/cpu_linux.c | 5 +- src/detection/cpu/cpu_windows.c | 6 +- src/fastfetch.c | 9 +- src/fastfetch.h | 1 - src/modules/bios.c | 24 +- src/modules/board.c | 22 +- src/modules/cpu.c | 1 - src/modules/gpu.c | 70 +++--- src/modules/host.c | 59 ++--- src/modules/locale.c | 18 +- 23 files changed, 133 insertions(+), 565 deletions(-) delete mode 100644 src/common/caching.c delete mode 100644 src/common/caching.h diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 5492b9ea2..0fb775db3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -39,5 +39,5 @@ Output of `fastfetch --list-features`: diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index c798e81d5..3e40c83b2 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -35,7 +35,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -81,7 +81,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -113,7 +113,7 @@ jobs: run: | cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . cmake --build . --target package - time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all time ./flashfetch ctest @@ -180,7 +180,7 @@ jobs: run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -254,7 +254,7 @@ jobs: run: cp /mingw64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - name: run fastfetch - run: time ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - name: run flashfetch run: time ./flashfetch diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f49a1265..c7f8bcb34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,7 +221,6 @@ configure_file(src/fastfetch_config.h.in fastfetch_config.h) set(LIBFASTFETCH_SRC src/common/bar.c - src/common/caching.c src/common/font.c src/common/format.c src/common/init.c diff --git a/completions/bash b/completions/bash index ca9e760ef..10356ce85 100644 --- a/completions/bash +++ b/completions/bash @@ -169,8 +169,6 @@ __fastfetch_completion() local FF_OPTIONS_BOOL=( "-r" - "--recache" - "--nocache" "--show-errors" "--logo-print-remaining" "--multithreading" diff --git a/presets/devinfo b/presets/devinfo index 57859baad..2ddf030b5 100644 --- a/presets/devinfo +++ b/presets/devinfo @@ -1,4 +1,3 @@ --disable-linewrap false --multithreading false --show-errors ---recache diff --git a/src/common/caching.c b/src/common/caching.c deleted file mode 100644 index 14551b120..000000000 --- a/src/common/caching.c +++ /dev/null @@ -1,327 +0,0 @@ -#include "fastfetch.h" -#include "common/caching.h" -#include "common/io.h" -#include "common/printing.h" - -#include -#include - -#define FF_CACHE_VERSION_NAME "cacheversion" -#define FF_CACHE_VERSION_EXTENSION "ffv" - -#define FF_CACHE_VALUE_EXTENSION "ffcv" -#define FF_CACHE_SPLIT_EXTENSION "ffcs" - -#define FF_CACHE_EXTENSION_V1 "ffc1" - -static void getCacheFilePath(const FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer) -{ - ffStrbufAppend(buffer, &instance->state.cacheDir); - ffStrbufAppendS(buffer, moduleName); - - if(extension != NULL) - { - ffStrbufAppendC(buffer, '.'); - ffStrbufAppendS(buffer, extension); - } -} - -static void readCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer) -{ - FFstrbuf path; - ffStrbufInitA(&path, 64); - getCacheFilePath(instance, moduleName, extension, &path); - ffAppendFileBuffer(path.chars, buffer); - ffStrbufDestroy(&path); -} - -static void writeCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* content) -{ - FFstrbuf path; - ffStrbufInitA(&path, 64); - getCacheFilePath(instance, moduleName, extension, &path); - ffWriteFileBuffer(path.chars, content); - ffStrbufDestroy(&path); -} - -void ffCacheValidate(FFinstance* instance) -{ - FFstrbuf content; - ffStrbufInit(&content); - readCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &content); - - const char exactVersion[] = FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK; - - bool isSameVersion = ffStrbufCompS(&content, exactVersion) == 0; - ffStrbufDestroy(&content); - if(isSameVersion) - return; - - instance->config.recache = true; - - FFstrbuf version; - ffStrbufInitA(&version, sizeof(exactVersion)); - ffStrbufAppendS(&version, exactVersion); - writeCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &version); - ffStrbufDestroy(&version); -} - -void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache) -{ - FFstrbuf cacheFileValue; - ffStrbufInitA(&cacheFileValue, 64); - getCacheFilePath(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &cacheFileValue); - cache->value = fopen(cacheFileValue.chars, "w"); - ffStrbufDestroy(&cacheFileValue); - - FFstrbuf cacheFileSplit; - ffStrbufInitA(&cacheFileSplit, 64); - getCacheFilePath(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &cacheFileSplit); - cache->split = fopen(cacheFileSplit.chars, "w"); - ffStrbufDestroy(&cacheFileSplit); -} - -void ffCacheClose(FFcache* cache) -{ - if(cache->value != NULL) - fclose(cache->value); - - if(cache->split != NULL) - fclose(cache->split); -} - -static bool printCachedValue(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs) -{ - FFstrbuf content; - ffStrbufInitA(&content, 512); - readCacheFile(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &content); - - ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length - - if(content.length == 0) - { - ffStrbufDestroy(&content); - return false; - } - - uint8_t moduleCounter = 1; - - uint32_t startIndex = 0; - while(startIndex < content.length) - { - uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0'); - uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter; - ffPrintLogoAndKey(instance, moduleName, moduleIndex, &moduleArgs->key); - puts(content.chars + startIndex); - startIndex = nullByteIndex + 1; - ++moduleCounter; - } - - ffStrbufDestroy(&content); - - return moduleCounter > 1; -} - -static bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs) -{ - FFstrbuf content; - ffStrbufInitA(&content, 512); - readCacheFile(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &content); - - ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length - - if(content.length == 0) - return false; - - uint8_t moduleCounter = 1; - - FFformatarg* arguments = calloc(numArgs, sizeof(FFformatarg)); - uint32_t argumentCounter = 0; - - uint32_t startIndex = 0; - while(startIndex < content.length) - { - arguments[argumentCounter].type = FF_FORMAT_ARG_TYPE_STRING; - arguments[argumentCounter].value = &content.chars[startIndex]; - ++argumentCounter; - - uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0'); - - if(argumentCounter == numArgs) - { - uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter; - ffPrintFormat(instance, moduleName, moduleIndex, moduleArgs, numArgs, arguments); - ++moduleCounter; - argumentCounter = 0; - } - - startIndex = nullByteIndex + 1; - } - - free(arguments); - ffStrbufDestroy(&content); - - return moduleCounter > 1; -} - -bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs) -{ - if(instance->config.recache) - return false; - - if(moduleArgs->outputFormat.length == 0) - return printCachedValue(instance, moduleName, moduleArgs); - else - return printCachedFormat(instance, moduleName, moduleArgs, numArgs); -} - -void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments) -{ - if(moduleArgs->outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, moduleName, moduleIndex, &moduleArgs->key); - ffStrbufPutTo(value, stdout); - } - else - { - ffPrintFormat(instance, moduleName, moduleIndex, moduleArgs, numArgs, arguments); - } - - if(cache->value != NULL) - { - ffStrbufWriteTo(value, cache->value); - fputc('\0', cache->value); - } - - if(cache->split == NULL) - return; - - for(uint32_t i = 0; i < numArgs; i++) - { - FFstrbuf buffer; - ffStrbufInitA(&buffer, 64); - ffFormatAppendFormatArg(&buffer, &arguments[i]); - ffStrbufWriteTo(&buffer, cache->split); - ffStrbufDestroy(&buffer); - fputc('\0', cache->split); - } -} - -void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments) -{ - FFcache cache; - ffCacheOpenWrite(instance, moduleName, &cache); - ffPrintAndAppendToCache(instance, moduleName, 0, moduleArgs, &cache, value, numArgs, arguments); - ffCacheClose(&cache); -} - -typedef struct FFCacheRead -{ - FFstrbuf data; - uint32_t position; -} FFCacheRead; - -static bool cacheReadStrbuf(FFCacheRead* cacheRead, FFstrbuf* strbuf) -{ - if(cacheRead->position >= cacheRead->data.length) - return false; - - ffStrbufAppendS(strbuf, cacheRead->data.chars + cacheRead->position); - cacheRead->position += strbuf->length + 1; // skip the null byte too - return true; -} - -static bool cacheReadData(FFCacheRead* cacheRead, size_t dataSize, void* data) -{ - if(cacheRead->position + dataSize > cacheRead->data.length) - return false; - - memcpy(data, cacheRead->data.chars + cacheRead->position, dataSize); - cacheRead->position += (uint32_t) dataSize; - return true; -} - -static bool cacheResetStrbuf(FFCache* cache, FFstrbuf* strbuf) -{ - FF_UNUSED(cache); - ffStrbufClear(strbuf); - return true; -} - -static bool cacheResetData(FFCache* cacheRead, size_t dataSize, void* data) -{ - FF_UNUSED(cacheRead, dataSize, data); - return true; -} - -bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback) -{ - if(instance->config.recache) - return false; - - FFCacheRead cache; - bool result; - - FFstrbuf path; - ffStrbufInitA(&path, 128); - getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path); - - cache.position = 0; - - ffStrbufInitA(&cache.data, 256); - result = ffAppendFileBuffer(path.chars, &cache.data); - - if(result) - result = callback(obj, &cache, (FFCacheMethodStrbuf) cacheReadStrbuf, (FFCacheMethodData) cacheReadData); - - if(result) - result = cache.position == cache.data.length; - - if(!result) - callback(obj, NULL, (FFCacheMethodStrbuf) cacheResetStrbuf, (FFCacheMethodData) cacheResetData); - - ffStrbufDestroy(&cache.data); - ffStrbufDestroy(&path); - - return result; -} - -typedef struct FFCacheWrite -{ - FFstrbuf data; -} FFCacheWrite; - -static bool cacheWriteStrbuf(FFCacheWrite* cacheWrite, FFstrbuf* strbuf) -{ - ffStrbufEnsureFree(&cacheWrite->data, strbuf->length); - memcpy(cacheWrite->data.chars + cacheWrite->data.length, strbuf->chars, strbuf->length +1); //Copy the nullbyte too - cacheWrite->data.length += strbuf->length + 1; - return true; -} - -static bool cacheWriteData(FFCacheWrite* cacheWrite, size_t dataSize, const void* data) -{ - ffStrbufEnsureFree(&cacheWrite->data, (uint32_t) dataSize); - memcpy(cacheWrite->data.chars + cacheWrite->data.length, data, dataSize); - cacheWrite->data.length += (uint32_t) dataSize; - return true; -} - -void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback) -{ - if(!instance->config.cacheSave) - return; - - FFCacheWrite cache; - - FFstrbuf path; - ffStrbufInitA(&path, 128); - getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path); - - ffStrbufInitA(&cache.data, 256); - callback(obj, &cache, (FFCacheMethodStrbuf) cacheWriteStrbuf, (FFCacheMethodData) cacheWriteData); - ffWriteFileBuffer(path.chars, &cache.data); - - ffStrbufDestroy(&cache.data); - ffStrbufDestroy(&path); -} diff --git a/src/common/caching.h b/src/common/caching.h deleted file mode 100644 index d8e17d473..000000000 --- a/src/common/caching.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#ifndef FF_INCLUDED_common_caching -#define FF_INCLUDED_common_caching - -#include "fastfetch.h" -#include "common/format.h" - -typedef struct FFcache -{ - FILE* value; - FILE* split; -} FFcache; - -void ffCacheValidate(FFinstance* instance); - -void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache); -void ffCacheClose(FFcache* cache); - -bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs); -void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments); -void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments); - -typedef void FFCache; - -typedef bool(*FFCacheMethodStrbuf)(FFCache* cache, FFstrbuf* strbuf); -typedef bool(*FFCacheMethodData)(FFCache* cache, size_t dataSize, void* data); -typedef bool(*FFCacheMethodCallback)(void* data, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod); - -bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback); -void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback); - -#endif diff --git a/src/common/init.c b/src/common/init.c index b81b2933f..948d5ab88 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -1,5 +1,4 @@ #include "fastfetch.h" -#include "common/caching.h" #include "common/parsing.h" #include "common/thread.h" #include "detection/qt.h" @@ -88,34 +87,6 @@ static void initConfigDirs(FFstate* state) #undef FF_ENSURE_ONLY_ONCE_IN_LIST } -static void initCacheDir(FFstate* state) -{ - ffStrbufInitA(&state->cacheDir, 64); - - ffStrbufAppendS(&state->cacheDir, getenv("XDG_CACHE_HOME")); - - if(state->cacheDir.length == 0) - { - ffStrbufAppendS(&state->cacheDir, state->passwd->pw_dir); - ffStrbufAppendS(&state->cacheDir, "/.cache/"); - } - else - ffStrbufEnsureEndsWithC(&state->cacheDir, '/'); - - mkdir(state->cacheDir.chars - #ifndef WIN32 - , S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH - #endif - ); //I hope everybody has a cache folder, but who knows - - ffStrbufAppendS(&state->cacheDir, "fastfetch/"); - mkdir(state->cacheDir.chars - #ifndef WIN32 - , S_IRWXU | S_IRGRP | S_IROTH - #endif - ); -} - static void initState(FFstate* state) { #ifdef WIN32 @@ -138,7 +109,6 @@ static void initState(FFstate* state) #endif initConfigDirs(state); - initCacheDir(state); } static void initModuleArg(FFModuleArgs* args) @@ -168,7 +138,6 @@ static void defaultConfig(FFinstance* instance) instance->config.showErrors = false; instance->config.recache = false; - instance->config.cacheSave = true; instance->config.allowSlowOperations = false; instance->config.disableLinewrap = true; instance->config.hideCursor = true; @@ -373,10 +342,6 @@ void ffStart(FFinstance* instance) sigaction(SIGQUIT, &action, NULL); #endif - //We do the cache validation here, so we can skip it if --recache is given - if(!instance->config.recache) - ffCacheValidate(instance); - //reset everything to default before we start printing if(!instance->config.pipe) fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); @@ -495,8 +460,6 @@ static void destroyState(FFinstance* instance) for(uint32_t i = 0; i < instance->state.configDirs.length; ++i) ffStrbufDestroy((FFstrbuf*)ffListGet(&instance->state.configDirs, i)); ffListDestroy(&instance->state.configDirs); - - ffStrbufDestroy(&instance->state.cacheDir); } void ffDestroyInstance(FFinstance* instance) diff --git a/src/data/config_user.txt b/src/data/config_user.txt index fe65a9ee4..2fc0b41fa 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -185,7 +185,6 @@ # OS file option # Sets the path to the file containing the operating system information. # Should be a valid path to an existing file. -# Note that you might need to run fastfetch with --recache once for it to take affect. # Default is /etc/os-release. #--os-file /etc/os-release diff --git a/src/data/help.txt b/src/data/help.txt index f6579cfde..d65071462 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -14,8 +14,6 @@ Informative options: --print-structure: prints the default stucture and exits General options: - -r,--recache : generate new cached values - --nocache : don't use cached values, but also don't overwrite existing ones --load-config : load a config file or a preset (+) --multithreading : use multiple threads to detect values --stat : print time usage (in ms) for individual modules diff --git a/src/detection/cpu/cpu.c b/src/detection/cpu/cpu.c index 3bfe92e87..62537aaa8 100644 --- a/src/detection/cpu/cpu.c +++ b/src/detection/cpu/cpu.c @@ -1,34 +1,13 @@ #include "cpu.h" -#include "common/caching.h" #include "detection/internal.h" -#define FF_CPU_CACHE_NAME "cpu" - -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached); - -static bool cacheCallback(FFCPUResult* cpu, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod) -{ - return - strbufMethod(cache, &cpu->vendor) && - strbufMethod(cache, &cpu->name) && - dataMethod(cache, sizeof(cpu->coresPhysical), &cpu->coresPhysical) && - dataMethod(cache, sizeof(cpu->coresLogical), &cpu->coresLogical) && - dataMethod(cache, sizeof(cpu->coresOnline), &cpu->coresOnline) && - dataMethod(cache, sizeof(cpu->frequencyMin), &cpu->frequencyMin) && - dataMethod(cache, sizeof(cpu->frequencyMax), &cpu->frequencyMax); -} - +void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu); static void detectCPU(const FFinstance* instance, FFCPUResult* cpu) { ffStrbufInit(&cpu->name); ffStrbufInit(&cpu->vendor); - bool cached = ffCacheRead(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback); - - ffDetectCPUImpl(instance, cpu, cached); - - if(cached) - return; + ffDetectCPUImpl(instance, cpu); const char* removeStrings[] = { " CPU", " FPU", " APU", " Processor", @@ -39,8 +18,6 @@ static void detectCPU(const FFinstance* instance, FFCPUResult* cpu) ffStrbufRemoveStringsA(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it - - ffCacheWrite(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback); } const FFCPUResult* ffDetectCPU(const FFinstance* instance) diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 5f1b35494..3de61f93d 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -41,32 +41,29 @@ static double detectCpuTemp(const FFstrbuf* cpuName) return result; } -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) +void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) { FF_UNUSED(instance); - if(!cached) - { - ffSysctlGetString("machdep.cpu.brand_string", &cpu->name); - ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor); + ffSysctlGetString("machdep.cpu.brand_string", &cpu->name); + ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor); - cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1); - if(cpu->coresPhysical == 1) - cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu", 1); + cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1); + if(cpu->coresPhysical == 1) + cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu", 1); - cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.logicalcpu_max", 1); - if(cpu->coresLogical == 1) - cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); + cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.logicalcpu_max", 1); + if(cpu->coresLogical == 1) + cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); - cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.logicalcpu", 1); - if(cpu->coresOnline == 1) - cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.activecpu", 1); + cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.logicalcpu", 1); + if(cpu->coresOnline == 1) + cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.activecpu", 1); - cpu->frequencyMin = getFrequency("hw.cpufrequency_min"); - cpu->frequencyMax = getFrequency("hw.cpufrequency_max"); - if(cpu->frequencyMax == 0.0) - cpu->frequencyMax = getFrequency("hw.cpufrequency"); - } + cpu->frequencyMin = getFrequency("hw.cpufrequency_min"); + cpu->frequencyMax = getFrequency("hw.cpufrequency_max"); + if(cpu->frequencyMax == 0.0) + cpu->frequencyMax = getFrequency("hw.cpufrequency"); if (instance->config.cpuTemp) cpu->temperature = detectCpuTemp(&cpu->name); diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 6f71f1ef6..2308c8985 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -1,7 +1,7 @@ #include "cpu.h" #include "common/sysctl.h" -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) +void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) { FF_UNUSED(instance); @@ -17,9 +17,6 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) else cpu->temperature = FF_CPU_TEMP_UNSET; - if(cached) - return; - ffSysctlGetString("hw.model", &cpu->name); cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index ea1c45a69..ee68f1e6f 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -82,16 +82,13 @@ static double detectCPUTemp(const FFinstance* instance) return FF_CPU_TEMP_UNSET; } -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) +void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) { if(instance->config.cpuTemp) cpu->temperature = detectCPUTemp(instance); else cpu->temperature = FF_CPU_TEMP_UNSET; - if(cached) - return; - FFstrbuf physicalCoresBuffer; ffStrbufInit(&physicalCoresBuffer); diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index acef000bc..84af8ecfb 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -2,15 +2,11 @@ #include "util/windows/registry.h" #include "util/mallocHelper.h" -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached) +void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) { 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); diff --git a/src/fastfetch.c b/src/fastfetch.c index 66c2ebb40..be62bb4ad 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -895,16 +895,9 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con /////////////////// else if(strcasecmp(key, "-r") == 0 || strcasecmp(key, "--recache") == 0) - { - //Set cacheSave as well, because the user expects the values to be cached when expliciting using --recache instance->config.recache = optionParseBoolean(value); - instance->config.cacheSave = instance->config.recache; - } else if(strcasecmp(key, "--nocache") == 0) - { - instance->config.recache = optionParseBoolean(value); - instance->config.cacheSave = false; - } + fputs("`--nocache` are obsoleted. Caching functions other than image caching are removed.\n\n", stderr); else if(strcasecmp(key, "--load-config") == 0) optionParseConfigFile(instance, data, key, value); else if(strcasecmp(key, "--thread") == 0 || strcasecmp(key, "--multithreading") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index bbd19122c..1198b4fcf 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -85,7 +85,6 @@ typedef struct FFconfig bool showErrors; bool recache; - bool cacheSave; bool allowSlowOperations; bool disableLinewrap; bool hideCursor; diff --git a/src/modules/bios.c b/src/modules/bios.c index 3e443a389..7b3853355 100644 --- a/src/modules/bios.c +++ b/src/modules/bios.c @@ -1,6 +1,5 @@ #include "fastfetch.h" #include "common/printing.h" -#include "common/caching.h" #include "detection/bios/bios.h" #define FF_BIOS_MODULE_NAME "Bios" @@ -8,9 +7,6 @@ void ffPrintBios(FFinstance* instance) { - if(ffPrintFromCache(instance, FF_BIOS_MODULE_NAME, &instance->config.bios, FF_BIOS_NUM_FORMAT_ARGS)) - return; - FFBiosResult result; ffDetectBios(&result); @@ -26,12 +22,20 @@ void ffPrintBios(FFinstance* instance) goto exit; } - ffPrintAndWriteToCache(instance, FF_BIOS_MODULE_NAME, &instance->config.bios, &result.biosRelease, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosDate}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosRelease}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVersion}, - }); + if(instance->config.bios.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios.key); + puts(result.biosRelease.chars); + } + else + { + ffPrintFormat(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosDate}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosRelease}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVersion}, + }); + } exit: ffStrbufDestroy(&result.biosDate); diff --git a/src/modules/board.c b/src/modules/board.c index 8fe85735d..558653892 100644 --- a/src/modules/board.c +++ b/src/modules/board.c @@ -1,6 +1,5 @@ #include "fastfetch.h" #include "common/printing.h" -#include "common/caching.h" #include "detection/board/board.h" #define FF_BOARD_MODULE_NAME "Board" @@ -8,9 +7,6 @@ void ffPrintBoard(FFinstance* instance) { - if(ffPrintFromCache(instance, FF_BOARD_MODULE_NAME, &instance->config.board, FF_BOARD_NUM_FORMAT_ARGS)) - return; - FFBoardResult result; ffDetectBoard(&result); @@ -26,11 +22,19 @@ void ffPrintBoard(FFinstance* instance) goto exit; } - ffPrintAndWriteToCache(instance, FF_BOARD_MODULE_NAME, &instance->config.board, &result.boardName, FF_BOARD_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVersion}, - }); + if(instance->config.board.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board.key); + puts(result.boardName.chars); + } + else + { + ffPrintFormat(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, FF_BOARD_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVersion}, + }); + } exit: ffStrbufDestroy(&result.boardName); diff --git a/src/modules/cpu.c b/src/modules/cpu.c index 89c40fb99..eb38a9805 100644 --- a/src/modules/cpu.c +++ b/src/modules/cpu.c @@ -1,6 +1,5 @@ #include "fastfetch.h" #include "common/printing.h" -#include "common/caching.h" #include "detection/cpu/cpu.h" #define FF_CPU_MODULE_NAME "CPU" diff --git a/src/modules/gpu.c b/src/modules/gpu.c index 905fd9774..0d0ae8266 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -1,6 +1,5 @@ #include "fastfetch.h" #include "common/printing.h" -#include "common/caching.h" #include "detection/host/host.h" #include "detection/gpu/gpu.h" @@ -9,41 +8,47 @@ #define FF_GPU_MODULE_NAME "GPU" #define FF_GPU_NUM_FORMAT_ARGS 5 -static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, FFGPUResult* gpu) +static void printGPUResult(FFinstance* instance, uint8_t index, FFGPUResult* gpu) { - FFstrbuf output; - ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length); - - if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor)) + if(instance->config.gpu.outputFormat.length == 0) { - ffStrbufAppend(&output, &gpu->vendor); - ffStrbufAppendC(&output, ' '); + ffPrintLogoAndKey(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu.key); + + FFstrbuf output; + ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length); + + if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor)) + { + ffStrbufAppend(&output, &gpu->vendor); + ffStrbufAppendC(&output, ' '); + } + + ffStrbufAppend(&output, &gpu->name); + + if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET) + ffStrbufAppendF(&output, " (%d)", gpu->coreCount); + + if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET + ffStrbufAppendF(&output, " - %.1f°C", gpu->temperature); + + ffStrbufPutTo(&output, stdout); + + ffStrbufDestroy(&output); + } + else + { + ffPrintFormat(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}, + {FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount}, + }); } - - ffStrbufAppend(&output, &gpu->name); - - if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET) - ffStrbufAppendF(&output, " (%d)", gpu->coreCount); - - if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET - ffStrbufAppendF(&output, " - %.1f°C", gpu->temperature); - - ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, cache, &output, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}, //FIXME: temperature shouldn't be cached - {FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount}, - }); - - ffStrbufDestroy(&output); } void ffPrintGPU(FFinstance* instance) { - if(ffPrintFromCache(instance, FF_GPU_MODULE_NAME, &instance->config.gpu, FF_GPU_NUM_FORMAT_ARGS)) - return; - const FFlist* gpus = ffDetectGPU(instance); if(gpus->length == 0) @@ -52,11 +57,6 @@ void ffPrintGPU(FFinstance* instance) return; } - FFcache cache; - ffCacheOpenWrite(instance, FF_GPU_MODULE_NAME, &cache); - for(uint8_t i = 0; i < (uint8_t) gpus->length; i++) - printGPUResult(instance, gpus->length == 1 ? 0 : (uint8_t) (i + 1), &cache, ffListGet(gpus, i)); - - ffCacheClose(&cache); + printGPUResult(instance, gpus->length == 1 ? 0 : (uint8_t) (i + 1), ffListGet(gpus, i)); } diff --git a/src/modules/host.c b/src/modules/host.c index cd4f50106..f253ceee4 100644 --- a/src/modules/host.c +++ b/src/modules/host.c @@ -1,6 +1,5 @@ #include "fastfetch.h" #include "common/printing.h" -#include "common/caching.h" #include "detection/host/host.h" #define FF_HOST_MODULE_NAME "Host" @@ -8,9 +7,6 @@ void ffPrintHost(FFinstance* instance) { - if(ffPrintFromCache(instance, FF_HOST_MODULE_NAME, &instance->config.host, FF_HOST_NUM_FORMAT_ARGS)) - return; - const FFHostResult* host = ffDetectHost(); if(host->error.length > 0) @@ -25,29 +21,38 @@ void ffPrintHost(FFinstance* instance) return; } - FFstrbuf output; - ffStrbufInit(&output); - - if(host->productName.length > 0) - ffStrbufAppend(&output, &host->productName); - else - ffStrbufAppend(&output, &host->productFamily); - - if(host->productVersion.length > 0) + if(instance->config.host.outputFormat.length == 0) { - ffStrbufAppendF(&output, " (%s)", host->productVersion.chars); + ffPrintLogoAndKey(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host.key); + + FFstrbuf output; + ffStrbufInit(&output); + + if(host->productName.length > 0) + ffStrbufAppend(&output, &host->productName); + else + ffStrbufAppend(&output, &host->productFamily); + + if(host->productVersion.length > 0) + { + ffStrbufAppendF(&output, " (%s)", host->productVersion.chars); + } + + ffStrbufPutTo(&output, stdout); + + ffStrbufDestroy(&output); + } + else + { + ffPrintFormat(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productFamily}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisType}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->sysVendor} + }); } - - ffPrintAndWriteToCache(instance, FF_HOST_MODULE_NAME, &instance->config.host, &output, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productFamily}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisType}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->sysVendor} - }); - - ffStrbufDestroy(&output); } diff --git a/src/modules/locale.c b/src/modules/locale.c index cd8f0cd5f..8c56b0638 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -1,5 +1,4 @@ #include "fastfetch.h" -#include "common/caching.h" #include "common/printing.h" #include "detection/locale/locale.h" @@ -8,9 +7,6 @@ void ffPrintLocale(FFinstance* instance) { - if(ffPrintFromCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.locale, FF_LOCALE_NUM_FORMAT_ARGS)) - return; - FFstrbuf locale; ffStrbufInit(&locale); @@ -21,9 +17,17 @@ void ffPrintLocale(FFinstance* instance) return; } - ffPrintAndWriteToCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.locale, &locale, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &locale} - }); + if(instance->config.locale.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale.key); + ffStrbufPutTo(&locale, stdout); + } + else + { + ffPrintFormat(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &locale} + }); + } ffStrbufDestroy(&locale); } From c7bec3d0c9ca99dc5ec7b68d3d35b2b056e67ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 19 Dec 2022 20:38:31 +0800 Subject: [PATCH 267/311] Image: enable imagemagick 6 on macOS Program crashed when imagemagick 7 used, for some reason. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f49a1265..c5102ad73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF) cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD" OFF) +cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD OR APPLE" OFF) cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) From d4ec500b1bea4f31db41d2f80bd44a23f17ae4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 19 Dec 2022 20:41:33 +0800 Subject: [PATCH 268/311] Image: fix compile error when building with chafa enabled It should be `#include ` because `pkg-config chafa --cflags` prints `-I/usr/include/chafa` even in Linux. It was working because `chafa` folder was installed in the standard `/usr/include` directory, but it was not the case for macOS (brew) --- src/logo/image/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 87523dc95..dec706ffe 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -213,7 +213,7 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData } #ifdef FF_HAVE_CHAFA -#include +#include static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) { FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1) From 10584eb01a7a39080c3426708d765af95305f678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 19 Dec 2022 20:56:03 +0800 Subject: [PATCH 269/311] Image: document macOS support; update CI --- .github/workflows/push.yml | 2 +- README.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index c798e81d5..73295d73a 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -64,7 +64,7 @@ jobs: uses: actions/checkout@v3 - name: install required packages - run: brew install vulkan-loader molten-vk + run: brew install vulkan-loader molten-vk imagemagick@6 chafa - name: Initialize CodeQL uses: github/codeql-action/init@v2 diff --git a/README.md b/README.md index 8202233b4..bec602e92 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,11 @@ The following libraries are used if present at runtime: ### macOS * [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system. -* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. +* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb) +* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick@6`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick@6.rb) +* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb) + +For image logo, iTerm with sixel protocol should work. Apple Terminal is not supported. ### Windows From 1b2a61ed49fdd8d260e91b3e89fabe5e1feb8ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 11:01:13 +0800 Subject: [PATCH 270/311] Image: init MagickCore environment before using it I don't know why im6 works without initialization, but im7 doesn't. --- src/logo/image/image.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index dec706ffe..4d8d68b0f 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -273,6 +273,8 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* requestData, const FFIMData* imData) { + FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreGenesis, FF_LOGO_IMAGE_RESULT_INIT_ERROR); + FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreTerminus, FF_LOGO_IMAGE_RESULT_INIT_ERROR); FF_LIBRARY_LOAD_SYMBOL(imData->library, AcquireExceptionInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR) FF_LIBRARY_LOAD_SYMBOL(imData->library, DestroyExceptionInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR) FF_LIBRARY_LOAD_SYMBOL(imData->library, AcquireImageInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR) @@ -286,14 +288,20 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* FF_LIBRARY_LOAD_SYMBOL_VAR(imData->library, imageData, ImageToBlob, FF_LOGO_IMAGE_RESULT_INIT_ERROR) FF_LIBRARY_LOAD_SYMBOL_VAR(imData->library, imageData, Base64Encode, FF_LOGO_IMAGE_RESULT_INIT_ERROR) + ffMagickCoreGenesis(NULL, MagickFalse); + imageData.exceptionInfo = ffAcquireExceptionInfo(); if(imageData.exceptionInfo == NULL) + { + ffMagickCoreTerminus(); return FF_LOGO_IMAGE_RESULT_RUN_ERROR; + } ImageInfo* imageInfoIn = ffAcquireImageInfo(); if(imageInfoIn == NULL) { ffDestroyExceptionInfo(imageData.exceptionInfo); + ffMagickCoreTerminus(); return FF_LOGO_IMAGE_RESULT_RUN_ERROR; } @@ -305,6 +313,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* if(imageData.image == NULL) { ffDestroyExceptionInfo(imageData.exceptionInfo); + ffMagickCoreTerminus(); return FF_LOGO_IMAGE_RESULT_RUN_ERROR; } @@ -325,6 +334,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* { ffDestroyImage(imageData.image); ffDestroyExceptionInfo(imageData.exceptionInfo); + ffMagickCoreTerminus(); return FF_LOGO_IMAGE_RESULT_RUN_ERROR; } @@ -333,6 +343,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* if(resized == NULL) { ffDestroyExceptionInfo(imageData.exceptionInfo); + ffMagickCoreTerminus(); return FF_LOGO_IMAGE_RESULT_RUN_ERROR; } imageData.image = resized; @@ -342,6 +353,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* { ffDestroyImage(imageData.image); ffDestroyExceptionInfo(imageData.exceptionInfo); + ffMagickCoreTerminus(); return FF_LOGO_IMAGE_RESULT_RUN_ERROR; } @@ -360,6 +372,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* ffDestroyImageInfo(imageData.imageInfo); ffDestroyImage(imageData.image); ffDestroyExceptionInfo(imageData.exceptionInfo); + ffMagickCoreTerminus(); return printSuccessful ? FF_LOGO_IMAGE_RESULT_SUCCESS : FF_LOGO_IMAGE_RESULT_RUN_ERROR; } From 01d2d77efdaeec66c0ceaf60e4c373f57d8db489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 11:01:42 +0800 Subject: [PATCH 271/311] Image: fix resource leaks --- src/logo/image/image.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 4d8d68b0f..2fb5824d5 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -234,7 +234,10 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData size_t length; void* blob = imageData->ffImageToBlob(imageData->imageInfo, imageData->image, &length, imageData->exceptionInfo); if(!checkAllocationResult(blob, length)) + { + dlclose(chafa); return false; + } ChafaSymbolMap* symbolMap = ffchafa_symbol_map_new(); ffchafa_symbol_map_add_by_tags(symbolMap, CHAFA_SYMBOL_TAG_ALL); @@ -266,6 +269,7 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ffchafa_canvas_unref(canvas); ffchafa_canvas_config_unref(canvasConfig); ffchafa_symbol_map_unref(symbolMap); + dlclose(chafa); return true; } From 2f5cbfb03a6c27e27412e227abe575341fbc093c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 11:04:57 +0800 Subject: [PATCH 272/311] Image: enable im7 on macOS --- .github/workflows/push.yml | 2 +- CMakeLists.txt | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 73295d73a..6b063b5ab 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -64,7 +64,7 @@ jobs: uses: actions/checkout@v3 - name: install required packages - run: brew install vulkan-loader molten-vk imagemagick@6 chafa + run: brew install vulkan-loader molten-vk imagemagick chafa - name: Initialize CodeQL uses: github/codeql-action/init@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index c5102ad73..cff56404a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF) -cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD" OFF) +cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD OR APPLE" OFF) cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD OR APPLE" OFF) cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) diff --git a/README.md b/README.md index bec602e92..73326a654 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ The following libraries are used if present at runtime: * [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system. * [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb) -* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick@6`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick@6.rb) +* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb) * [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb) For image logo, iTerm with sixel protocol should work. Apple Terminal is not supported. From 75341e81722c79e40515725ac6dd333910a20ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 11:37:54 +0800 Subject: [PATCH 273/311] Image: make it compile on Windows Doesn't work yet. --- src/logo/image/image.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 2fb5824d5..e8fde9351 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -16,7 +16,17 @@ #include #include #include + +#ifndef _WIN32 #include +#else +#include + +inline char* realpath(const char* restrict file_name, char* restrict resolved_name) +{ + return _fullpath(resolved_name, file_name, _MAX_PATH); +} +#endif #ifdef FF_HAVE_ZLIB #include "common/library.h" @@ -498,6 +508,8 @@ static bool printCached(FFinstance* instance, FFLogoRequestData* requestData) static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) { + #ifndef _WIN32 + struct winsize winsize; //Initialize every member to 0, because it isn't guaranteed that every terminal sets them all @@ -517,6 +529,17 @@ static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) requestData->characterPixelWidth = winsize.ws_xpixel / (double) winsize.ws_col; requestData->characterPixelHeight = winsize.ws_ypixel / (double) winsize.ws_row; + #else + + CONSOLE_FONT_INFO cfi; + if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi) == FALSE) // Only works for ConHost + return false; + + requestData->characterPixelWidth = cfi.dwFontSize.X; + requestData->characterPixelHeight = cfi.dwFontSize.Y; + + #endif + return requestData->characterPixelWidth > 1.0 && requestData->characterPixelHeight > 1.0; } From 1153d29099e6d3b0f9a9bfa164fe94f948f8b948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 12:03:05 +0800 Subject: [PATCH 274/311] TerminalFont: improve conhost font detection (Windows) --- .../terminalfont/terminalfont_windows.c | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index 590aa9339..ea41f018e 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -2,7 +2,9 @@ #include "common/io.h" #include "detection/terminalshell/terminalshell.h" #include "terminalfont.h" -#include "util/windows/registry.h" +#include "util/windows/unicode.h" + +#include static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { @@ -28,23 +30,17 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term { FF_UNUSED(instance); - //Current font of conhost doesn't seem to be detectable, we detect default font instead - - FF_HKEY_AUTO_DESTROY hKey = NULL; - if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Console", &hKey, &terminalFont->error)) + CONSOLE_FONT_INFOEX cfi = { .cbSize = sizeof(cfi) }; + if(!GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi)) + { + ffStrbufAppendS(&terminalFont->error, "GetCurrentConsoleFontEx() failed"); return; + } - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); - if(!ffRegReadStrbuf(hKey, L"FaceName", &fontName, &terminalFont->error)) - return; - - uint32_t fontSizeNum = 0; - if(!ffRegReadUint(hKey, L"FontSize", &fontSizeNum, &terminalFont->error)) - return; + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreateWS(cfi.FaceName); char fontSize[16]; - _ultoa((unsigned long)(fontSizeNum >> 16), fontSize, 10); + _ultoa((unsigned long)(cfi.dwFontSize.Y), fontSize, 10); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize); } From d21ce9b10f2461a3035df9501eb74a6f5976a8fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 22:37:15 +0800 Subject: [PATCH 275/311] Image: tidy --- src/logo/image/image.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index e8fde9351..0de2d1cf0 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -22,7 +22,7 @@ #else #include -inline char* realpath(const char* restrict file_name, char* restrict resolved_name) +static inline char* realpath(const char* restrict file_name, char* restrict resolved_name) { return _fullpath(resolved_name, file_name, _MAX_PATH); } @@ -226,7 +226,10 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData #include static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) { - FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD(glib, &instance->config.libChafa, false, "libglib-2.0-0" FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD_SYMBOL(glib, g_string_free, false) + + FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa-0" FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_add_by_tags, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_new, false) @@ -238,7 +241,6 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_unref, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_unref, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_unref, false) - FF_LIBRARY_LOAD_SYMBOL(chafa, g_string_free, false) imageData->ffCopyMagickString(imageData->imageInfo->magick, "RGBA", 5); size_t length; @@ -271,8 +273,8 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData result.allocated = (uint32_t) str->allocated_len; result.length = (uint32_t) str->len; result.chars = str->str; - - ffLogoPrintChars(instance, result.chars, false); + puts(result.chars); + // ffLogoPrintChars(instance, result.chars, false); writeCacheStrbuf(requestData, &result, FF_CACHE_FILE_CHAFA); ffg_string_free(str, TRUE); @@ -280,6 +282,7 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ffchafa_canvas_config_unref(canvasConfig); ffchafa_symbol_map_unref(symbolMap); dlclose(chafa); + dlclose(glib); return true; } @@ -531,12 +534,20 @@ static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) #else + setmode (fileno (stdin), O_BINARY); + setmode (fileno (stdout), O_BINARY); + CONSOLE_FONT_INFO cfi; - if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi) == FALSE) // Only works for ConHost - return false; - - requestData->characterPixelWidth = cfi.dwFontSize.X; - requestData->characterPixelHeight = cfi.dwFontSize.Y; + if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi) != FALSE) // Only works for ConHost + { + requestData->characterPixelWidth = cfi.dwFontSize.X; + requestData->characterPixelHeight = cfi.dwFontSize.Y; + } + else + { + requestData->characterPixelWidth = 8; + requestData->characterPixelHeight = 16; + } #endif From 8f3900a9dff4bb88d8a52ad3b239659d2c544006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 22:40:06 +0800 Subject: [PATCH 276/311] Windows: add manifest file to indicate that we use UTF-8 and support Windows 10+ --- src/util/windows/manifest.xml | 23 +++++++++++++++++++++++ src/util/windows/version.rc | 6 +++++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/util/windows/manifest.xml diff --git a/src/util/windows/manifest.xml b/src/util/windows/manifest.xml new file mode 100644 index 000000000..420545ded --- /dev/null +++ b/src/util/windows/manifest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + UTF-8 + true + SegmentHeap + + + diff --git a/src/util/windows/version.rc b/src/util/windows/version.rc index a8ea2519c..e130a65e9 100644 --- a/src/util/windows/version.rc +++ b/src/util/windows/version.rc @@ -1,6 +1,7 @@ // // Include the necessary resources // +#include #include #include #include "fastfetch_config.h" @@ -16,7 +17,10 @@ #define VER_DEBUG 0 #endif -#define FF_TO_STR(str) #str +#define FF_TO_STR1(str) #str +#define FF_TO_STR(str) FF_TO_STR1(str) + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "manifest.xml" // ------- version info ------------------------------------------------------- From 985fc991e85fdbf71eaa01fa59cbf9c4bf3ed95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 22:44:45 +0800 Subject: [PATCH 277/311] Revert "Image: tidy" This reverts commit d21ce9b10f2461a3035df9501eb74a6f5976a8fd. --- src/logo/image/image.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 0de2d1cf0..ccbaae7df 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -226,10 +226,7 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData #include static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) { - FF_LIBRARY_LOAD(glib, &instance->config.libChafa, false, "libglib-2.0-0" FF_LIBRARY_EXTENSION, 1) - FF_LIBRARY_LOAD_SYMBOL(glib, g_string_free, false) - - FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa-0" FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_add_by_tags, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_new, false) @@ -241,6 +238,7 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_unref, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_unref, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_unref, false) + FF_LIBRARY_LOAD_SYMBOL(chafa, g_string_free, false) imageData->ffCopyMagickString(imageData->imageInfo->magick, "RGBA", 5); size_t length; @@ -273,8 +271,8 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData result.allocated = (uint32_t) str->allocated_len; result.length = (uint32_t) str->len; result.chars = str->str; - puts(result.chars); - // ffLogoPrintChars(instance, result.chars, false); + + ffLogoPrintChars(instance, result.chars, false); writeCacheStrbuf(requestData, &result, FF_CACHE_FILE_CHAFA); ffg_string_free(str, TRUE); @@ -282,7 +280,6 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ffchafa_canvas_config_unref(canvasConfig); ffchafa_symbol_map_unref(symbolMap); dlclose(chafa); - dlclose(glib); return true; } @@ -534,20 +531,12 @@ static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) #else - setmode (fileno (stdin), O_BINARY); - setmode (fileno (stdout), O_BINARY); - CONSOLE_FONT_INFO cfi; - if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi) != FALSE) // Only works for ConHost - { - requestData->characterPixelWidth = cfi.dwFontSize.X; - requestData->characterPixelHeight = cfi.dwFontSize.Y; - } - else - { - requestData->characterPixelWidth = 8; - requestData->characterPixelHeight = 16; - } + if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi) == FALSE) // Only works for ConHost + return false; + + requestData->characterPixelWidth = cfi.dwFontSize.X; + requestData->characterPixelHeight = cfi.dwFontSize.Y; #endif From 225d1dd4d2b3e98a532879de34c8ae0a8b16a8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Dec 2022 23:29:23 +0800 Subject: [PATCH 278/311] Init: don't try to find config files in XDG folders on platforms other than Linux and BSD --- src/common/init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/common/init.c b/src/common/init.c index b81b2933f..8c380b3ca 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -21,6 +21,8 @@ static void initConfigDirs(FFstate* state) { ffListInit(&state->configDirs, sizeof(FFstrbuf)); + #if !(defined(_WIN32) || defined(__APPLE__) || defined(__ANDROID__)) + const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); if(ffStrSet(xdgConfigHome)) { @@ -30,6 +32,8 @@ static void initConfigDirs(FFstate* state) ffStrbufEnsureEndsWithC(buffer, '/'); } + #endif + #define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \ if(ffListFirstIndexComp(&state->configDirs, element, (bool(*)(const void*, const void*))ffStrbufEqual) < state->configDirs.length - 1) \ { \ @@ -49,6 +53,8 @@ static void initConfigDirs(FFstate* state) ffStrbufEnsureEndsWithC(userHome, '/'); FF_ENSURE_ONLY_ONCE_IN_LIST(userHome) + #if !(defined(_WIN32) || defined(__APPLE__) || defined(__ANDROID__)) + FFstrbuf xdgConfigDirs; ffStrbufInitA(&xdgConfigDirs, 64); ffStrbufAppendS(&xdgConfigDirs, getenv("XDG_CONFIG_DIRS")); @@ -80,6 +86,8 @@ static void initConfigDirs(FFstate* state) ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ETC"/xdg/"); FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigHome) + #endif + FFstrbuf* systemConfig = ffListAdd(&state->configDirs); ffStrbufInitA(systemConfig, 64); ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ETC"/"); From c9918035ed6a5c6aaf139f77b7aa14c8f7bbb2b9 Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 03:31:23 -0500 Subject: [PATCH 279/311] Update help.txt --- src/data/help.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/data/help.txt b/src/data/help.txt index f6579cfde..84b44c77b 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -11,7 +11,7 @@ Informative options: --print-logos: show available logos and exits --print-config-system: prints the default system config and exits --print-config-user: prints the default user config and exits - --print-structure: prints the default stucture and exits + --print-structure: prints the default structure and exits General options: -r,--recache : generate new cached values @@ -20,7 +20,7 @@ General options: --multithreading : use multiple threads to detect values --stat : print time usage (in ms) for individual modules --allow-slow-operations : allow operations that are usually very slow for more detailed output - --escape-bedrock : on bedrock linux, sets if it should escape the bedrock jail or not + --escape-bedrock : on Bedrock Linux, sets if it should escape the bedrock jail or not --pipe : disable logo and all escape sequences Logo options: @@ -43,14 +43,14 @@ Logo options: Display options: -s,--structure : sets the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. - --color-keys : sers the color of the keys + --color-keys : sets the color of the keys --color-title : sets the color of the title -c,--color : sets the color of both the keys and the title --separator : sets the separator between key and value. Default is a colon with a space --set : hard set the value of a key --set-keyless : hard set the value of a key, but don't print the key or the separator - --show-errors : print occuring errors - --disable-linewrap : weather to disable linewrap during the run + --show-errors : print occurring errors + --disable-linewrap : weather to disable line wrap during the run --hide-cursor : weather to hide the cursor during the run --binary-prefix : sets the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC @@ -92,7 +92,7 @@ Library options: Set the path of a library to load Module specific options: --title-fqdn : Sets if the title should use fully qualified domain name. Default is false. --separator-string : Set the string printed by the separator module - --os-file : Set the path to the file containing OS informations + --os-file : Set the path to the file containing OS information --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) --disk-show-removable : Sets if removable volume should be printed. Default is true. --disk-show-hidden : Sets if hidden volumes should be printed. Default is false @@ -100,16 +100,16 @@ Module specific options: --cpu-temp : Detect and display CPU temperature if supported. Default is false --gpu-temp : Detect and display GPU temperature if supported. Default is false --battery-temp : Detect and display Battery temperature if supported. Default is false - --localip-show-ipv4 : Show ipv4 addresses in local ip module. Default is true - --localip-show-ipv6 : Show ipv6 addresses in local ip module. Default is false + --localip-show-ipv4 : Show IPv4 addresses in local ip module. Default is true + --localip-show-ipv6 : Show IPv6 addresses in local ip module. Default is false --localip-show-loop : Show loop back addresses (127.0.0.1) in local ip module. Default is false - --localip-name-prefix : Show ips with given name prefix only. Default is empty + --localip-name-prefix : Show IPs with given name prefix only. Default is empty --public-ip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0) --public-ip-url: The URL of public IP detection server to be used. --weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0) --weather-output-format: The output weather format to be used. It must be URI encoded. --player-name: The name of the player to use - --gl : Sets the opengl context creation library to use. Must be auto, egl, glx or osmesa. Default is auto + --gl : Sets the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto --percent-type : Sets the percentage output type. 1 for percentage number, 2 for bar, 3 for both. Default is 1 Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci" From 89983a28b4ab0ad84d45fc16bcee8f1313d3ffd7 Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 03:44:48 -0500 Subject: [PATCH 280/311] Update help.txt --- src/data/help.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/help.txt b/src/data/help.txt index 84b44c77b..0a32ceafa 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -32,7 +32,7 @@ Logo options: --logo-padding : set the padding on the left and the right of the logo --logo-padding-left : set the padding on the left of the logo --logo-padding-right : set the padding on the right of the logo - --logo-print-remaining : weather to print the remaining logo, if it has more lines than modules to display + --logo-print-remaining : whether to print the remaining logo, if it has more lines than modules to display --file : short for --logo-type file --logo --file-raw : short for --logo-type file-raw --logo --data : short for --logo-type data --logo @@ -50,8 +50,8 @@ Display options: --set : hard set the value of a key --set-keyless : hard set the value of a key, but don't print the key or the separator --show-errors : print occurring errors - --disable-linewrap : weather to disable line wrap during the run - --hide-cursor : weather to hide the cursor during the run + --disable-linewrap : whether to disable line wrap during the run + --hide-cursor : whether to hide the cursor during the run --binary-prefix : sets the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC General module options: From 265b98311a86cfcb506ce16d18fd02fe06788dd7 Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 03:51:02 -0500 Subject: [PATCH 281/311] Update help.txt --- src/data/help.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/help.txt b/src/data/help.txt index 0a32ceafa..ce45ec2fc 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -20,7 +20,7 @@ General options: --multithreading : use multiple threads to detect values --stat : print time usage (in ms) for individual modules --allow-slow-operations : allow operations that are usually very slow for more detailed output - --escape-bedrock : on Bedrock Linux, sets if it should escape the bedrock jail or not + --escape-bedrock : whether to escape the bedrock jail on Bedrock Linux --pipe : disable logo and all escape sequences Logo options: From afe56a36c9dcf95a858e5a0dde5e20bacd4a8bda Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 03:52:16 -0500 Subject: [PATCH 282/311] Update help.txt --- src/data/help.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/help.txt b/src/data/help.txt index ce45ec2fc..f20ad0f25 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -20,7 +20,7 @@ General options: --multithreading : use multiple threads to detect values --stat : print time usage (in ms) for individual modules --allow-slow-operations : allow operations that are usually very slow for more detailed output - --escape-bedrock : whether to escape the bedrock jail on Bedrock Linux + --escape-bedrock : on Bedrock Linux, whether to escape the bedrock jail --pipe : disable logo and all escape sequences Logo options: From d5b3ae90561780d7a9a864535c5f410c87c8f631 Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 04:02:02 -0500 Subject: [PATCH 283/311] Update help.txt --- src/data/help.txt | 108 +++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/src/data/help.txt b/src/data/help.txt index f20ad0f25..ff9b09926 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -1,68 +1,68 @@ Usage: fastfetch Informative options: - -h,--help: shows this message and exits - -h,--help : shows help for a specific command and exits - -v,--version: prints the version of fastfetch and exits - --list-logos: list available logos and exits - --list-modules: lists available modules and exits - --list-presets: list presets fastfetch knows about and exits. They can be loaded with --load-config. (+) - --list-features: list the supported features fastfetch was compiled with and exits. Mainly for development. - --print-logos: show available logos and exits - --print-config-system: prints the default system config and exits - --print-config-user: prints the default user config and exits - --print-structure: prints the default structure and exits + -h,--help: Show this message and exit + -h,--help : Show help for a specific command and exit + -v,--version: Print the version of fastfetch and exit + --list-logos: List available logos and exit + --list-modules: List available modules and exit + --list-presets: List presets fastfetch knows about and exit; they can be loaded with --load-config (+) + --list-features: List the supported features fastfetch was compiled with and exit (mainly for development) + --print-logos: Show available logos and exit + --print-config-system: Print the default system config and exit + --print-config-user: Print the default user config and exit + --print-structure: Print the default structure and exit General options: - -r,--recache : generate new cached values - --nocache : don't use cached values, but also don't overwrite existing ones - --load-config : load a config file or a preset (+) - --multithreading : use multiple threads to detect values - --stat : print time usage (in ms) for individual modules - --allow-slow-operations : allow operations that are usually very slow for more detailed output - --escape-bedrock : on Bedrock Linux, whether to escape the bedrock jail - --pipe : disable logo and all escape sequences + -r,--recache : Generate new cached values + --nocache : Don't use cached values, but also don't overwrite existing ones + --load-config : Load a config file or a preset (+) + --multithreading : Use multiple threads to detect values + --stat : Print time usage (in ms) for individual modules + --allow-slow-operations : Allow operations that are usually very slow for more detailed output + --escape-bedrock : On Bedrock Linux, whether to escape the bedrock jail + --pipe : Disable logo and all escape sequences Logo options: - -l,--logo : set the logo to use. The type is specified by --logo-type. If default: the name of a builtin logo or a path to a file - --logo-type : set the type of the logo given. Must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa. - --logo-width : set the width of the logo (in characters), if it is an image - --logo-height : set the height of the logo (in characters), if it is an image - --logo-color-[1-9] : overwrite a color in the logo - --logo-padding : set the padding on the left and the right of the logo - --logo-padding-left : set the padding on the left of the logo - --logo-padding-right : set the padding on the right of the logo - --logo-print-remaining : whether to print the remaining logo, if it has more lines than modules to display - --file : short for --logo-type file --logo - --file-raw : short for --logo-type file-raw --logo - --data : short for --logo-type data --logo - --data-raw : short for --logo-type data-raw --logo - --sixel : short for --logo-type sixel --logo - --kitty : short for --logo-type kitty --logo - --chafa : short for --logo-type chafa --logo + -l,--logo : Set the logo to use. The type is specified by --logo-type. If default: the name of a builtin logo or a path to a file + --logo-type : Set the type of the logo given. Must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa. + --logo-width : Set the width of the logo (in characters), if it is an image + --logo-height : Set the height of the logo (in characters), if it is an image + --logo-color-[1-9] : Overwrite a color in the logo + --logo-padding : Set the padding on the left and the right of the logo + --logo-padding-left : Set the padding on the left of the logo + --logo-padding-right : Set the padding on the right of the logo + --logo-print-remaining : Whether to print the remaining logo, if it has more lines than modules to display + --file : Short for --logo-type file --logo + --file-raw : Short for --logo-type file-raw --logo + --data : Short for --logo-type data --logo + --data-raw : Short for --logo-type data-raw --logo + --sixel : Short for --logo-type sixel --logo + --kitty : Short for --logo-type kitty --logo + --chafa : Short for --logo-type chafa --logo Display options: - -s,--structure : sets the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. - --color-keys : sets the color of the keys - --color-title : sets the color of the title - -c,--color : sets the color of both the keys and the title - --separator : sets the separator between key and value. Default is a colon with a space - --set : hard set the value of a key - --set-keyless : hard set the value of a key, but don't print the key or the separator - --show-errors : print occurring errors - --disable-linewrap : whether to disable line wrap during the run - --hide-cursor : whether to hide the cursor during the run - --binary-prefix : sets the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC + -s,--structure : Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. + --color-keys : Set the color of the keys + --color-title : Set the color of the title + -c,--color : Set the color of both the keys and title + --separator : Set the separator between key and value. Default is a colon with a space + --set : Hard set the value of a key + --set-keyless : Hard set the value of a key, but don't print the key or the separator + --show-errors : Print occurring errors + --disable-linewrap : Whether to disable line wrap during the run + --hide-cursor : Whether to hide the cursor during the run + --binary-prefix : Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC General module options: - ---format : Sets the format string to use for each specific module. + ---format : Set the format string to use for each specific module. To see how a format string works, use fastfetch --help format. To see help about a specific format string, use fastfetch --help -format. - ---key : Sets the key to use for each specific module. + ---key : Set the key to use for each specific module. For modules which print multiple lines, the string is parsed as a format string with the index as first character. - ---error : Sets the error format string to use for each specific module. + ---error : Set the error format string to use for each specific module. The error is given as the first and only argument. Setting this for a module will cause it to appear, even if --show-errors is not given. @@ -90,12 +90,12 @@ Library options: Set the path of a library to load --lib-cjson Module specific options: - --title-fqdn : Sets if the title should use fully qualified domain name. Default is false. + --title-fqdn : Set if the title should use fully qualified domain name. Default is false. --separator-string : Set the string printed by the separator module --os-file : Set the path to the file containing OS information --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) - --disk-show-removable : Sets if removable volume should be printed. Default is true. - --disk-show-hidden : Sets if hidden volumes should be printed. Default is false + --disk-show-removable : Set if removable volume should be printed. Default is true. + --disk-show-hidden : Set if hidden volumes should be printed. Default is false --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ --cpu-temp : Detect and display CPU temperature if supported. Default is false --gpu-temp : Detect and display GPU temperature if supported. Default is false @@ -109,8 +109,8 @@ Module specific options: --weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0) --weather-output-format: The output weather format to be used. It must be URI encoded. --player-name: The name of the player to use - --gl : Sets the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto - --percent-type : Sets the percentage output type. 1 for percentage number, 2 for bar, 3 for both. Default is 1 + --gl : Set the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto + --percent-type : Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both. Default is 1 Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci" If a value starts with a ?, it is optional. "true" will be used if not set. From 620adc0ec65feece0bfde1b312d19174050171bc Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 04:10:33 -0500 Subject: [PATCH 284/311] Update help.txt --- src/data/help.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/data/help.txt b/src/data/help.txt index ff9b09926..421eda98f 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -14,9 +14,7 @@ Informative options: --print-structure: Print the default structure and exit General options: - -r,--recache : Generate new cached values - --nocache : Don't use cached values, but also don't overwrite existing ones - --load-config : Load a config file or a preset (+) + --load-config : Load a config file or preset (+) --multithreading : Use multiple threads to detect values --stat : Print time usage (in ms) for individual modules --allow-slow-operations : Allow operations that are usually very slow for more detailed output @@ -24,8 +22,8 @@ General options: --pipe : Disable logo and all escape sequences Logo options: - -l,--logo : Set the logo to use. The type is specified by --logo-type. If default: the name of a builtin logo or a path to a file - --logo-type : Set the type of the logo given. Must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa. + -l,--logo : Set the logo; if default, the name of a builtin logo or a path to a file + --logo-type : Set the type of the logo given; must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa --logo-width : Set the width of the logo (in characters), if it is an image --logo-height : Set the height of the logo (in characters), if it is an image --logo-color-[1-9] : Overwrite a color in the logo @@ -52,7 +50,7 @@ Display options: --show-errors : Print occurring errors --disable-linewrap : Whether to disable line wrap during the run --hide-cursor : Whether to hide the cursor during the run - --binary-prefix : Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC + --binary-prefix : Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC. General module options: ---format : Set the format string to use for each specific module. From a247a8d6babce405c068e50a651b72bd274ff8b8 Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 04:23:57 -0500 Subject: [PATCH 285/311] Update help.txt --- src/data/help.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/data/help.txt b/src/data/help.txt index 421eda98f..bdd65c4e8 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -1,22 +1,22 @@ Usage: fastfetch Informative options: - -h,--help: Show this message and exit - -h,--help : Show help for a specific command and exit - -v,--version: Print the version of fastfetch and exit - --list-logos: List available logos and exit - --list-modules: List available modules and exit - --list-presets: List presets fastfetch knows about and exit; they can be loaded with --load-config (+) - --list-features: List the supported features fastfetch was compiled with and exit (mainly for development) - --print-logos: Show available logos and exit - --print-config-system: Print the default system config and exit - --print-config-user: Print the default user config and exit - --print-structure: Print the default structure and exit + -h,--help: Show this message + -h,--help : Show help for a specific command + -v,--version: Show the version of fastfetch + --list-logos: List available logos + --list-modules: List available modules + --list-presets: List presets fastfetch knows about; they can be loaded with --load-config (+) + --list-features: List the supported features fastfetch was compiled with (mainly for development) + --print-logos: Print available logos + --print-config-system: Print the default system config + --print-config-user: Print the default user config + --print-structure: Print the default structure General options: --load-config : Load a config file or preset (+) --multithreading : Use multiple threads to detect values - --stat : Print time usage (in ms) for individual modules + --stat : Show time usage (in ms) for individual modules --allow-slow-operations : Allow operations that are usually very slow for more detailed output --escape-bedrock : On Bedrock Linux, whether to escape the bedrock jail --pipe : Disable logo and all escape sequences From bcc7b630aedf3330e2df2677b687ebc979904bff Mon Sep 17 00:00:00 2001 From: kojq <106934605+kojq@users.noreply.github.com> Date: Wed, 21 Dec 2022 04:38:28 -0500 Subject: [PATCH 286/311] Update help.txt --- src/data/help.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/help.txt b/src/data/help.txt index bdd65c4e8..a7a18a547 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -88,11 +88,11 @@ Library options: Set the path of a library to load --lib-cjson Module specific options: - --title-fqdn : Set if the title should use fully qualified domain name. Default is false. + --title-fqdn : Set if the title should use fully qualified domain name. Default is false --separator-string : Set the string printed by the separator module --os-file : Set the path to the file containing OS information --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) - --disk-show-removable : Set if removable volume should be printed. Default is true. + --disk-show-removable : Set if removable volume should be printed. Default is true --disk-show-hidden : Set if hidden volumes should be printed. Default is false --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ --cpu-temp : Detect and display CPU temperature if supported. Default is false From c9c2526f0899a322e117be55acfb72537c2818dc Mon Sep 17 00:00:00 2001 From: AloneER0 Date: Wed, 21 Dec 2022 17:27:00 +0100 Subject: [PATCH 287/311] Added OpenMandriva --- src/logo/builtin.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 720d21ede..d876cc5ac 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1726,6 +1726,45 @@ static const FFlogo* getLogoOpenSuseTumbleweed() FF_LOGO_RETURN } +static const FFlogo* getLogoOpenMandriva() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("openmandriva", "open-mandriva", "open_mandriva") + FF_LOGO_LINES( + " ``````\n" + " `-:/+++++++//:-.`\n" + " .:+++oooo+/:.`` ``\n" + " `:+ooooooo+:. `-:/++++++/:.`\n" + " -+oooooooo:` `-++o+/::::://+o+/-\n" + " `/ooooooooo- -+oo/.` `-/oo+.\n" + " `+ooooooooo. :os/` .+so:\n" + " +sssssssss/ :ss/ `+ss-\n" + " :ssssssssss` sss` .sso\n" + " ossssssssss `yyo sys\n" + "`sssssssssss` `yys `yys\n" + "`sssssssssss: +yy/ +yy:\n" + " oyyyyyyyyyys. `oyy/` `+yy+\n" + " :yyyyyyyyyyyo. `+yhs:. `./shy/\n" + " oyyyyyyyyyyys:` .oyhys+:----/+syhy+. `\n" + " `syyyyyyyyyyyyo-` .:osyhhhhhyys+:``.:`\n" + " `oyyyyyyyyyyyyys+-`` `.----.```./oo.\n" + " /yhhhhhhhhhhhhhhyso+//://+osyhy/`\n" + " `/yhhhhhhhhhhhhhhhhhhhhhhhhy/`\n" + " `:oyhhhhhhhhhhhhhhhhhhyo:`\n" + " .:+syhhhhhhhhys+:-`\n" + " ``....``" + + + + ) + FF_LOGO_COLORS( + "34" //blue + ) + FF_LOGO_COLOR_KEYS("34"); //blue + FF_LOGO_COLOR_TITLE("34"); //blue + FF_LOGO_RETURN +} + static const FFlogo* getLogoPop() { FF_LOGO_INIT @@ -2353,6 +2392,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoOpenSuseSmall, getLogoOpenSuseLeap, getLogoOpenSuseTumbleweed, + getLogoOpenMandriva, getLogoPop, getLogoPopSmall, getLogoParabola, From 0cacedfc5ddce74824fba6bbee6de7c6afe9250b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Dec 2022 02:07:35 +0800 Subject: [PATCH 288/311] Image: enable Chafa on Windows It's not built by default, as imagemagick requires too many dlls. --- CMakeLists.txt | 2 +- src/common/init.c | 4 ++++ src/data/help.txt | 2 ++ src/fastfetch.c | 8 ++++++++ src/fastfetch.h | 3 +++ src/logo/image/im7.c | 6 +++++- src/logo/image/image.c | 27 ++++++++++++++++++++++++--- 7 files changed, 47 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 148d21e5f..4e6361229 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF) -cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD OR APPLE" OFF) +cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD OR APPLE OR WIN32" OFF) cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD OR APPLE" OFF) cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) diff --git a/src/common/init.c b/src/common/init.c index 3f8915377..68f123fbe 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -138,6 +138,9 @@ static void defaultConfig(FFinstance* instance) instance->config.logo.paddingRight = 4; instance->config.logo.printRemaining = true; + instance->config.logo.chafaFgOnly = true; + ffStrbufInitS(&instance->config.logo.chafaSymbols, "block+border+space-wide-inverted"); // Chafa default + ffStrbufInit(&instance->config.colorKeys); ffStrbufInit(&instance->config.colorTitle); @@ -381,6 +384,7 @@ static void destroyModuleArg(FFModuleArgs* args) static void destroyConfig(FFinstance* instance) { ffStrbufDestroy(&instance->config.logo.source); + ffStrbufDestroy(&instance->config.logo.chafaSymbols); for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) ffStrbufDestroy(&instance->config.logo.colors[i]); ffStrbufDestroy(&instance->config.colorKeys); diff --git a/src/data/help.txt b/src/data/help.txt index d65071462..ca4edde2f 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -38,6 +38,8 @@ Logo options: --sixel : short for --logo-type sixel --logo --kitty : short for --logo-type kitty --logo --chafa : short for --logo-type chafa --logo + --chafa-symbols : specify character symbols to employ in final output. See chafa document for detail + --chafa-fg-only : produces character-cell output using foreground colors only. See chafa document for detail Display options: -s,--structure : sets the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. diff --git a/src/fastfetch.c b/src/fastfetch.c index be62bb4ad..27dd55b2f 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1017,6 +1017,14 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.logo.source); instance->config.logo.type = FF_LOGO_TYPE_IMAGE_CHAFA; } + else if(strcasecmp(key, "--chafa-fg-only") == 0) + { + instance->config.logo.chafaFgOnly = optionParseBoolean(value); + } + else if(strcasecmp(key, "--chafa-symbols") == 0) + { + optionParseString(key, value, &instance->config.logo.chafaSymbols); + } /////////////////// //Display options// diff --git a/src/fastfetch.h b/src/fastfetch.h index 1198b4fcf..81c4bb05a 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -75,6 +75,9 @@ typedef struct FFconfig uint32_t paddingLeft; uint32_t paddingRight; bool printRemaining; + + bool chafaFgOnly; + FFstrbuf chafaSymbols; } logo; //If one of those is empty, ffLogoPrint will set them diff --git a/src/logo/image/im7.c b/src/logo/image/im7.c index 2d1408f23..d7cf4b6d0 100644 --- a/src/logo/image/im7.c +++ b/src/logo/image/im7.c @@ -14,7 +14,11 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex FFLogoImageResult ffLogoPrintImageIM7(FFinstance* instance, FFLogoRequestData* requestData) { - FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11) + FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, + "libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11, + "libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11, + "libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, -1 // Required for Windows + ) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR); FFIMData imData; diff --git a/src/logo/image/image.c b/src/logo/image/image.c index ccbaae7df..fe888ccc2 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -226,19 +226,30 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData #include static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) { - FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, + "libchafa" FF_LIBRARY_EXTENSION, 1, + "libchafa-0" FF_LIBRARY_EXTENSION, -1 // Required for Windows + ) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_new, false) - FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_add_by_tags, false) + FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_apply_selectors, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_geometry, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_symbol_map, false) + FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_color_space, false) + FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_canvas_mode, false) + FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_fg_only_enabled, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_draw_all_pixels, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_print, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_unref, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_unref, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_unref, false) + + #ifndef _WIN32 + // FIXME: These functions must be imported from `libglib` dlls. Leak them for now FF_LIBRARY_LOAD_SYMBOL(chafa, g_string_free, false) + FF_LIBRARY_LOAD_SYMBOL(chafa, g_error_free, false) + #endif imageData->ffCopyMagickString(imageData->imageInfo->magick, "RGBA", 5); size_t length; @@ -250,11 +261,17 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData } ChafaSymbolMap* symbolMap = ffchafa_symbol_map_new(); - ffchafa_symbol_map_add_by_tags(symbolMap, CHAFA_SYMBOL_TAG_ALL); + GError* error = NULL; + if(!ffchafa_symbol_map_apply_selectors(symbolMap, instance->config.logo.chafaSymbols.chars, &error)) + fputs(error->message, stderr); ChafaCanvasConfig* canvasConfig = ffchafa_canvas_config_new(); ffchafa_canvas_config_set_geometry(canvasConfig, (gint) requestData->logoCharacterWidth, (gint) requestData->logoCharacterHeight); ffchafa_canvas_config_set_symbol_map(canvasConfig, symbolMap); + ffchafa_canvas_config_set_color_space(canvasConfig, CHAFA_COLOR_SPACE_DIN99D); + ffchafa_canvas_config_set_canvas_mode(canvasConfig, CHAFA_CANVAS_MODE_TRUECOLOR); + ffchafa_canvas_config_set_fg_only_enabled(canvasConfig, instance->config.logo.chafaFgOnly); + // TODO: expose more chafa configs to fastfetch flags ChafaCanvas* canvas = ffchafa_canvas_new(canvasConfig); ffchafa_canvas_draw_all_pixels( @@ -275,7 +292,11 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ffLogoPrintChars(instance, result.chars, false); writeCacheStrbuf(requestData, &result, FF_CACHE_FILE_CHAFA); + #ifndef _WIN32 ffg_string_free(str, TRUE); + ffg_error_free(error); + #endif + ffchafa_canvas_unref(canvas); ffchafa_canvas_config_unref(canvasConfig); ffchafa_symbol_map_unref(symbolMap); From f50b4789668797547928110d6f6c742b2de795f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Dec 2022 02:40:56 +0800 Subject: [PATCH 289/311] Image: try fixing caching --- src/common/init.c | 2 +- src/fastfetch.h | 1 - src/logo/image/image.c | 23 ++++++++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 68f123fbe..5acd02581 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -138,7 +138,7 @@ static void defaultConfig(FFinstance* instance) instance->config.logo.paddingRight = 4; instance->config.logo.printRemaining = true; - instance->config.logo.chafaFgOnly = true; + instance->config.logo.chafaFgOnly = false; ffStrbufInitS(&instance->config.logo.chafaSymbols, "block+border+space-wide-inverted"); // Chafa default ffStrbufInit(&instance->config.colorKeys); diff --git a/src/fastfetch.h b/src/fastfetch.h index 81c4bb05a..632a23daa 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -210,7 +210,6 @@ typedef struct FFstate #endif FFlist configDirs; - FFstrbuf cacheDir; } FFstate; typedef struct FFinstance diff --git a/src/logo/image/image.c b/src/logo/image/image.c index fe888ccc2..13cdbcf1f 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -24,7 +24,12 @@ static inline char* realpath(const char* restrict file_name, char* restrict resolved_name) { - return _fullpath(resolved_name, file_name, _MAX_PATH); + char* result = _fullpath(resolved_name, file_name, _MAX_PATH); + if(result) + { + resolved_name[1] = resolved_name[0]; // Drive Name + resolved_name[0] = '/'; + } } #endif @@ -270,7 +275,7 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ffchafa_canvas_config_set_symbol_map(canvasConfig, symbolMap); ffchafa_canvas_config_set_color_space(canvasConfig, CHAFA_COLOR_SPACE_DIN99D); ffchafa_canvas_config_set_canvas_mode(canvasConfig, CHAFA_CANVAS_MODE_TRUECOLOR); - ffchafa_canvas_config_set_fg_only_enabled(canvasConfig, instance->config.logo.chafaFgOnly); + // ffchafa_canvas_config_set_fg_only_enabled(canvasConfig, instance->config.logo.chafaFgOnly); // TODO: expose more chafa configs to fastfetch flags ChafaCanvas* canvas = ffchafa_canvas_new(canvasConfig); @@ -587,7 +592,19 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) requestData.logoPixelHeight = simpleCeil((double) instance->config.logo.height * requestData.characterPixelHeight); ffStrbufInitA(&requestData.cacheDir, PATH_MAX * 2); - ffStrbufAppend(&requestData.cacheDir, &instance->state.cacheDir); + + #if !(defined(_WIN32) || defined(__APPLE__) || defined(__ANDROID__)) + ffStrbufAppendS(&requestData.cacheDir, getenv("XDG_CACHE_HOME")); + #endif + + if(requestData.cacheDir.length == 0) + { + ffStrbufAppendS(&requestData.cacheDir, instance->state.passwd->pw_dir); + ffStrbufAppendS(&requestData.cacheDir, "/.cache/"); + } + else + ffStrbufEnsureEndsWithC(&requestData.cacheDir, '/'); + ffStrbufAppendS(&requestData.cacheDir, "images"); ffStrbufEnsureFree(&requestData.cacheDir, PATH_MAX); From c45ef0892662b842a96d74960b0f338f4a03a18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Dec 2022 11:36:13 +0800 Subject: [PATCH 290/311] Image: expose more chafa settings --- src/common/init.c | 3 +++ src/common/library.h | 3 +++ src/data/help.txt | 5 +++- src/fastfetch.c | 10 ++++---- src/fastfetch.h | 3 +++ src/logo/image/image.c | 52 ++++++++++++++++++++++++++++-------------- 6 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 5acd02581..beb34aaee 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -140,6 +140,9 @@ static void defaultConfig(FFinstance* instance) instance->config.logo.chafaFgOnly = false; ffStrbufInitS(&instance->config.logo.chafaSymbols, "block+border+space-wide-inverted"); // Chafa default + instance->config.logo.chafaCanvasMode = UINT32_MAX; + instance->config.logo.chafaColorSpace = UINT32_MAX; + instance->config.logo.chafaDitherMode = UINT32_MAX; ffStrbufInit(&instance->config.colorKeys); ffStrbufInit(&instance->config.colorTitle); diff --git a/src/common/library.h b/src/common/library.h index fbbbdac44..c23aa7b53 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -43,6 +43,9 @@ #define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \ __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue); +#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \ + __typeof__(&symbolName) ff ## symbolName = dlsym(library, #symbolName); + #define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \ __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed"); diff --git a/src/data/help.txt b/src/data/help.txt index f247833fd..a9afb0b9f 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -38,8 +38,11 @@ Logo options: --sixel : Short for --logo-type sixel --logo --kitty : Short for --logo-type kitty --logo --chafa : Short for --logo-type chafa --logo - --chafa-symbols : Specify character symbols to employ in final output. See chafa document for detail --chafa-fg-only : Produce character-cell output using foreground colors only. See chafa document for detail + --chafa-symbols : Specify character symbols to employ in final output. See chafa document for detail + --chafa-canvas-mode : Determine how colors are used in the output. This value maps the int value of enum ChafaCanvasMode. See chafa document for detail + --chafa-color-space : Set color space used for quantization. 0 for RGB; 1 for DIN99d. See chafa document for detail + --chafa-dither-mode : Set output dither mode (No effect with 24-bit color). This value maps the int value of enum ChafaDitherMode. See chafa document for detail Display options: -s,--structure : Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. diff --git a/src/fastfetch.c b/src/fastfetch.c index 27dd55b2f..70077bc26 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1018,13 +1018,15 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.logo.type = FF_LOGO_TYPE_IMAGE_CHAFA; } else if(strcasecmp(key, "--chafa-fg-only") == 0) - { instance->config.logo.chafaFgOnly = optionParseBoolean(value); - } else if(strcasecmp(key, "--chafa-symbols") == 0) - { optionParseString(key, value, &instance->config.logo.chafaSymbols); - } + else if(strcasecmp(key, "--chafa-canvas-mode") == 0) + instance->config.logo.chafaCanvasMode = optionParseUInt32(key, value); + else if(strcasecmp(key, "--chafa-color-space") == 0) + instance->config.logo.chafaColorSpace = optionParseUInt32(key, value); + else if(strcasecmp(key, "--chafa-dither-mode") == 0) + instance->config.logo.chafaDitherMode = optionParseUInt32(key, value); /////////////////// //Display options// diff --git a/src/fastfetch.h b/src/fastfetch.h index 632a23daa..40de9db0b 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -78,6 +78,9 @@ typedef struct FFconfig bool chafaFgOnly; FFstrbuf chafaSymbols; + uint32_t chafaCanvasMode; + uint32_t chafaColorSpace; + uint32_t chafaDitherMode; } logo; //If one of those is empty, ffLogoPrint will set them diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 13cdbcf1f..90e6920cb 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -240,9 +240,6 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_geometry, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_symbol_map, false) - FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_color_space, false) - FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_canvas_mode, false) - FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_set_fg_only_enabled, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_new, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_draw_all_pixels, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_print, false) @@ -250,12 +247,6 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_unref, false) FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_unref, false) - #ifndef _WIN32 - // FIXME: These functions must be imported from `libglib` dlls. Leak them for now - FF_LIBRARY_LOAD_SYMBOL(chafa, g_string_free, false) - FF_LIBRARY_LOAD_SYMBOL(chafa, g_error_free, false) - #endif - imageData->ffCopyMagickString(imageData->imageInfo->magick, "RGBA", 5); size_t length; void* blob = imageData->ffImageToBlob(imageData->imageInfo, imageData->image, &length, imageData->exceptionInfo); @@ -273,10 +264,31 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ChafaCanvasConfig* canvasConfig = ffchafa_canvas_config_new(); ffchafa_canvas_config_set_geometry(canvasConfig, (gint) requestData->logoCharacterWidth, (gint) requestData->logoCharacterHeight); ffchafa_canvas_config_set_symbol_map(canvasConfig, symbolMap); - ffchafa_canvas_config_set_color_space(canvasConfig, CHAFA_COLOR_SPACE_DIN99D); - ffchafa_canvas_config_set_canvas_mode(canvasConfig, CHAFA_CANVAS_MODE_TRUECOLOR); - // ffchafa_canvas_config_set_fg_only_enabled(canvasConfig, instance->config.logo.chafaFgOnly); - // TODO: expose more chafa configs to fastfetch flags + + if(instance->config.logo.chafaFgOnly) + { + FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_fg_only_enabled); + if(ffchafa_canvas_config_set_fg_only_enabled) + ffchafa_canvas_config_set_fg_only_enabled(canvasConfig, true); + } + if(instance->config.logo.chafaCanvasMode < CHAFA_CANVAS_MODE_MAX) + { + FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_canvas_mode); + if(ffchafa_canvas_config_set_canvas_mode) + ffchafa_canvas_config_set_canvas_mode(canvasConfig, (ChafaCanvasMode) instance->config.logo.chafaCanvasMode); + } + if(instance->config.logo.chafaColorSpace < CHAFA_COLOR_SPACE_MAX) + { + FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_color_space) + if(ffchafa_canvas_config_set_color_space) + ffchafa_canvas_config_set_color_space(canvasConfig, (ChafaColorSpace) instance->config.logo.chafaColorSpace); + } + if(instance->config.logo.chafaDitherMode < CHAFA_DITHER_MODE_MAX) + { + FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_dither_mode) + if(ffchafa_canvas_config_set_dither_mode) + ffchafa_canvas_config_set_dither_mode(canvasConfig, (ChafaDitherMode) instance->config.logo.chafaDitherMode); + } ChafaCanvas* canvas = ffchafa_canvas_new(canvasConfig); ffchafa_canvas_draw_all_pixels( @@ -297,10 +309,16 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ffLogoPrintChars(instance, result.chars, false); writeCacheStrbuf(requestData, &result, FF_CACHE_FILE_CHAFA); - #ifndef _WIN32 - ffg_string_free(str, TRUE); - ffg_error_free(error); - #endif + // FIXME: These functions must be imported from `libglib` dlls on Windows + FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, g_string_free); + if(ffg_string_free) + ffg_string_free(str, TRUE); + if(error) + { + FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, g_error_free) + if(ffg_error_free) + ffg_error_free(error); + } ffchafa_canvas_unref(canvas); ffchafa_canvas_config_unref(canvasConfig); From 89347b7bee61f3753ced92875e04b54f198c8719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Dec 2022 21:37:16 +0800 Subject: [PATCH 291/311] Image: add dirty support of iTerm image protocol iTerm image protocol supports most commonly used image formats so we don't need image magick to convert image format. However, since we don't know anything about the image, `--logo-width` `--logo-height` must be specified to make sure that logo will not be covered by texts. --- src/common/init.c | 1 + src/data/help.txt | 44 +++++++++++++++++---------------- src/fastfetch.c | 7 ++++++ src/fastfetch.h | 2 ++ src/logo/image/image.c | 56 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index beb34aaee..1e42252bc 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -137,6 +137,7 @@ static void defaultConfig(FFinstance* instance) instance->config.logo.paddingLeft = 0; instance->config.logo.paddingRight = 4; instance->config.logo.printRemaining = true; + instance->config.logo.preserveAspectRadio = false; instance->config.logo.chafaFgOnly = false; ffStrbufInitS(&instance->config.logo.chafaSymbols, "block+border+space-wide-inverted"); // Chafa default diff --git a/src/data/help.txt b/src/data/help.txt index a9afb0b9f..dea266a24 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -22,27 +22,29 @@ General options: --pipe : Disable logo and all escape sequences Logo options: - -l,--logo : Set the logo; if default, the name of a builtin logo or a path to a file - --logo-type : Set the type of the logo given; must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa - --logo-width : Set the width of the logo (in characters), if it is an image - --logo-height : Set the height of the logo (in characters), if it is an image - --logo-color-[1-9] : Overwrite a color in the logo - --logo-padding : Set the padding on the left and the right of the logo - --logo-padding-left : Set the padding on the left of the logo - --logo-padding-right : Set the padding on the right of the logo - --logo-print-remaining : Whether to print the remaining logo, if it has more lines than modules to display - --file : Short for --logo-type file --logo - --file-raw : Short for --logo-type file-raw --logo - --data : Short for --logo-type data --logo - --data-raw : Short for --logo-type data-raw --logo - --sixel : Short for --logo-type sixel --logo - --kitty : Short for --logo-type kitty --logo - --chafa : Short for --logo-type chafa --logo - --chafa-fg-only : Produce character-cell output using foreground colors only. See chafa document for detail - --chafa-symbols : Specify character symbols to employ in final output. See chafa document for detail - --chafa-canvas-mode : Determine how colors are used in the output. This value maps the int value of enum ChafaCanvasMode. See chafa document for detail - --chafa-color-space : Set color space used for quantization. 0 for RGB; 1 for DIN99d. See chafa document for detail - --chafa-dither-mode : Set output dither mode (No effect with 24-bit color). This value maps the int value of enum ChafaDitherMode. See chafa document for detail + -l,--logo : Set the logo; if default, the name of a builtin logo or a path to a file + --logo-type : Set the type of the logo given; must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty, iterm or chafa + --logo-width : Set the width of the logo (in characters), if it is an image. Required for iTerm image protocol + --logo-height : Set the height of the logo (in characters), if it is an image. Required for iTerm image protocol + --logo-preserve-aspect-radio : Set if the logo should fill the specified width and height as much as possible without stretching. Supported by iTerm image protocol + --logo-color-[1-9] : Overwrite a color in the logo + --logo-padding : Set the padding on the left and the right of the logo + --logo-padding-left : Set the padding on the left of the logo + --logo-padding-right : Set the padding on the right of the logo + --logo-print-remaining : Whether to print the remaining logo, if it has more lines than modules to display + --file : Short for --logo-type file --logo + --file-raw : Short for --logo-type file-raw --logo + --data : Short for --logo-type data --logo + --data-raw : Short for --logo-type data-raw --logo + --sixel : Short for --logo-type sixel --logo + --kitty : Short for --logo-type kitty --logo + --iterm : Short for --logo-type iterm --logo + --chafa : Short for --logo-type chafa --logo + --chafa-fg-only : Produce character-cell output using foreground colors only. See chafa document for detail + --chafa-symbols : Specify character symbols to employ in final output. See chafa document for detail + --chafa-canvas-mode : Determine how colors are used in the output. This value maps the int value of enum ChafaCanvasMode. See chafa document for detail + --chafa-color-space : Set color space used for quantization. 0 for RGB; 1 for DIN99d. See chafa document for detail + --chafa-dither-mode : Set output dither mode (No effect with 24-bit color). This value maps the int value of enum ChafaDitherMode. See chafa document for detail Display options: -s,--structure : Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. diff --git a/src/fastfetch.c b/src/fastfetch.c index 70077bc26..8112b9a54 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -979,6 +979,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.logo.paddingRight = optionParseUInt32(key, value); else if(strcasecmp(subkey, "-print-remaining") == 0) instance->config.logo.printRemaining = optionParseBoolean(value); + else if(strcasecmp(subkey, "-preserve-aspect-radio") == 0) + instance->config.logo.preserveAspectRadio = optionParseBoolean(value); else goto error; } @@ -1017,6 +1019,11 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.logo.source); instance->config.logo.type = FF_LOGO_TYPE_IMAGE_CHAFA; } + else if(strcasecmp(key, "--iterm") == 0) + { + optionParseString(key, value, &instance->config.logo.source); + instance->config.logo.type = FF_LOGO_TYPE_IMAGE_ITERM; + } else if(strcasecmp(key, "--chafa-fg-only") == 0) instance->config.logo.chafaFgOnly = optionParseBoolean(value); else if(strcasecmp(key, "--chafa-symbols") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index 40de9db0b..d38b9b48d 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -38,6 +38,7 @@ typedef enum FFLogoType FF_LOGO_TYPE_DATA_RAW, //text data, printed as is FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes. FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol + FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa } FFLogoType; @@ -75,6 +76,7 @@ typedef struct FFconfig uint32_t paddingLeft; uint32_t paddingRight; bool printRemaining; + bool preserveAspectRadio; bool chafaFgOnly; FFstrbuf chafaSymbols; diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 90e6920cb..9cd1756f9 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -2,6 +2,56 @@ #include "common/io.h" #include "common/printing.h" +static FFstrbuf base64Encode(FFstrbuf* in) +{ + const char* base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + FFstrbuf out; + ffStrbufInitA(&out, 8 * (1 + in->length / 6)); + + unsigned val = 0; + int valb = -6; + for (uint32_t i = 0; i < in->length; ++i) + { + unsigned char c = (unsigned char) in->chars[i]; + val = (val << 8) + c; + valb += 8; + while (valb >= 0) + { + ffStrbufAppendC(&out, base64Chars[(val>>valb)&0x3F]); + valb -= 6; + } + } + if (valb > -6) ffStrbufAppendC(&out, base64Chars[((val<<8)>>(valb+8))&0x3F]); + while (out.length % 4) ffStrbufAppendC(&out, '='); + return out; +} + +static bool printImageIterm(FFinstance* instance) +{ + if(instance->config.logo.width == 0 || instance->config.logo.height == 0) + return false; + + FFstrbuf buf; + ffStrbufInit(&buf); + if(!ffAppendFileBuffer(instance->config.logo.source.chars, &buf)) + return false; + + ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + FFstrbuf base64 = base64Encode(&buf); + printf("\033]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\033[9999999D\n\033[%uA", + instance->config.logo.width, + instance->config.logo.height, + (unsigned) instance->config.logo.preserveAspectRadio, + base64.chars, + instance->config.logo.height + ); + instance->state.logoWidth = instance->config.logo.width + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; + instance->state.logoHeight = instance->config.logo.height; + + return true; +} + #if defined(FF_HAVE_IMAGEMAGICK7) || defined(FF_HAVE_IMAGEMAGICK6) #define FF_KITTY_MAX_CHUNK_SIZE 4096 @@ -589,6 +639,9 @@ static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) { + if(type == FF_LOGO_TYPE_IMAGE_ITERM) + return printImageIterm(instance); + //Performance optimisation #ifndef FF_HAVE_CHAFA if(type == FF_LOGO_TYPE_IMAGE_CHAFA) @@ -664,7 +717,8 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) #else //FF_HAVE_IMAGEMAGICK{6, 7} bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) { - FF_UNUSED(instance, type); + if(type == FF_LOGO_TYPE_IMAGE_ITERM) + return printImageIterm(instance); return false; } #endif //FF_HAVE_IMAGEMAGICK{6, 7} From 3e607680e2823d1c20a84118620c58a4fe213f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Dec 2022 21:47:30 +0800 Subject: [PATCH 292/311] Image: dont leak memories --- src/logo/image/image.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 9cd1756f9..2f9794f33 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -40,15 +40,18 @@ static bool printImageIterm(FFinstance* instance) ffPrintCharTimes(' ', instance->config.logo.paddingLeft); FFstrbuf base64 = base64Encode(&buf); printf("\033]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\033[9999999D\n\033[%uA", - instance->config.logo.width, - instance->config.logo.height, + (unsigned) instance->config.logo.width, + (unsigned) instance->config.logo.height, (unsigned) instance->config.logo.preserveAspectRadio, base64.chars, - instance->config.logo.height + (unsigned) instance->config.logo.height ); instance->state.logoWidth = instance->config.logo.width + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; instance->state.logoHeight = instance->config.logo.height; + ffStrbufDestroy(&buf); + ffStrbufDestroy(&base64); + return true; } From e0c6c462a6b12aafe4fdf214f6d10eef16fc251c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Dec 2022 22:00:02 +0800 Subject: [PATCH 293/311] README: update document of Windows 10- and image logo support --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 73326a654..d8a611bc6 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ The following libraries are used if present at runtime: * [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb) * [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb) -For image logo, iTerm with sixel protocol should work. Apple Terminal is not supported. +For image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported. ### Windows @@ -66,7 +66,12 @@ For image logo, iTerm with sixel protocol should work. Apple Terminal is not sup * [`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). Fastfetch on Windows targets [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment), which is not installed On Windows 10- by default. If you get errors like `ucrtbase.dll is missing`, try upgrading your system with `Windows Update` or downloading `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) which targets the ancient MSVCRT. +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). In addition, special build `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) is provided to support these old systems, which + +1. Build with the ancient MSVCRT C runtime library, instead of the modern [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library +2. Disable stdout application buffer, which seems to problematic for ConEmu. + +For image logo, only chafa is supported due to [the design flaw of ConPTY](https://github.com/microsoft/terminal/issues/1173). In addition, chafa support is not built by default due to the massive dependencies of imagemagick. You must built it yourself. ### Android @@ -89,7 +94,7 @@ AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, C * Some logos have an old variant. Access it by appending _old to the logo name. * To disable the logo, use `--logo none`. * Get a list of all available logos with `fastfetch --print-logos`. -* Printing images as logo is supported using Sixel / Kitty graphics protocol or chafas image to text conversion. +* Printing images as logo is supported using Sixel / Kitty / iTerm graphics protocol or chafas image to text conversion. ##### Package managers ``` From ecc6b477dcbad91bb2370c2864f7006f27ec3df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Dec 2022 11:11:27 +0800 Subject: [PATCH 294/311] TerminalFont: support Kitty --- README.md | 2 +- src/detection/terminalfont/terminalfont.c | 31 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d8a611bc6..326e2b7ca 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt ##### Terminal fonts ``` -Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, Deepin Terminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu +Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, Kitty, LXTerminal, Deepin Terminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu ``` ## Building diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index aeff09318..5716b720d 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -291,12 +291,43 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu #endif #endif //defined(_WIN32) || defined(__linux__) +static bool detectKitty(const FFinstance* instance, FFTerminalFontResult* result) +{ + FFstrbuf fontName; + ffStrbufInit(&fontName); + + FFstrbuf fontSize; + ffStrbufInit(&fontSize); + + FFpropquery fontQuery[] = { + {"font_family ", &fontName}, + {"font_size ", &fontSize}, + }; + + if(!ffParsePropFileConfigValues(instance, "kitty/kitty.conf", 2, fontQuery)) + return false; + + if(fontName.length == 0) + ffStrbufSetS(&fontName, "monospace"); + if(fontSize.length == 0) + ffStrbufSetS(&fontSize, "11.0"); + + ffFontInitValues(&result->font, fontName.chars, fontSize.chars); + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&fontSize); + + return true; +} + void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); static bool detectTerminalFontCommon(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "alacritty") == 0) detectAlacritty(instance, terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "kitty") == 0) + detectKitty(instance, terminalFont); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) detectTTY(terminalFont); From a336145ed91451a26bd130b582b5ba461ce4bf44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Dec 2022 12:34:30 +0800 Subject: [PATCH 295/311] Image: add fast path for kitty protocol --- src/logo/image/image.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 2f9794f33..f079d4215 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -55,6 +55,33 @@ static bool printImageIterm(FFinstance* instance) return true; } +static bool printImageKittyDirect(FFinstance* instance) +{ + if(instance->config.logo.width == 0 || instance->config.logo.height == 0) + return false; + + if(!ffFileExists(instance->config.logo.source.chars, S_IFREG)) + return false; + + if(!ffStrbufEndsWithIgnCaseS(&instance->config.logo.source, ".png")) + return false; + + ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + FFstrbuf base64 = base64Encode(&instance->config.logo.source); + printf("\033_Ga=T,f=100,t=f,c=%u,r=%u,C=1;%s\033\\\033[9999999D", + (unsigned) instance->config.logo.width, + (unsigned) instance->config.logo.height, + base64.chars + ); + + instance->state.logoWidth = instance->config.logo.width + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; + instance->state.logoHeight = instance->config.logo.height; + + ffStrbufDestroy(&base64); + + return true; +} + #if defined(FF_HAVE_IMAGEMAGICK7) || defined(FF_HAVE_IMAGEMAGICK6) #define FF_KITTY_MAX_CHUNK_SIZE 4096 @@ -722,6 +749,8 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) { if(type == FF_LOGO_TYPE_IMAGE_ITERM) return printImageIterm(instance); + if(type == FF_LOGO_TYPE_IMAGE_KITTY) + return printImageKittyDirect(instance); return false; } #endif //FF_HAVE_IMAGEMAGICK{6, 7} From 47e01a71573749c7a83e9db1c570d07be3b1ed0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Dec 2022 12:44:19 +0800 Subject: [PATCH 296/311] Image: print more debug info when errored --- src/logo/image/image.c | 72 +++++++++++++++++++++++++++--------------- src/logo/image/image.h | 2 +- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index f079d4215..f34738669 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -57,15 +57,6 @@ static bool printImageIterm(FFinstance* instance) static bool printImageKittyDirect(FFinstance* instance) { - if(instance->config.logo.width == 0 || instance->config.logo.height == 0) - return false; - - if(!ffFileExists(instance->config.logo.source.chars, S_IFREG)) - return false; - - if(!ffStrbufEndsWithIgnCaseS(&instance->config.logo.source, ".png")) - return false; - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); FFstrbuf base64 = base64Encode(&instance->config.logo.source); printf("\033_Ga=T,f=100,t=f,c=%u,r=%u,C=1;%s\033\\\033[9999999D", @@ -667,17 +658,8 @@ static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) return requestData->characterPixelWidth > 1.0 && requestData->characterPixelHeight > 1.0; } -bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) +static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type) { - if(type == FF_LOGO_TYPE_IMAGE_ITERM) - return printImageIterm(instance); - - //Performance optimisation - #ifndef FF_HAVE_CHAFA - if(type == FF_LOGO_TYPE_IMAGE_CHAFA) - return false; - #endif - FFLogoRequestData requestData; requestData.type = type; requestData.characterPixelWidth = 1; @@ -686,8 +668,10 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) if( (type != FF_LOGO_TYPE_IMAGE_CHAFA || instance->config.logo.width == 0 || instance->config.logo.height == 0) && !getCharacterPixelDimensions(&requestData) - ) + ) { + fputs("Logo: getCharacterPixelDimensions() failed", stderr); return false; + } requestData.logoPixelWidth = simpleCeil((double) instance->config.logo.width * requestData.characterPixelWidth); requestData.logoPixelHeight = simpleCeil((double) instance->config.logo.height * requestData.characterPixelHeight); @@ -713,6 +697,7 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) { //We can safely return here, because if realpath failed, we surely won't be able to read the file ffStrbufDestroy(&requestData.cacheDir); + fputs("Logo: Querying realpath of the image source failed", stderr); return false; } ffStrbufRecalculateLength(&requestData.cacheDir); @@ -741,16 +726,53 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) #endif ffStrbufDestroy(&requestData.cacheDir); - return result == FF_LOGO_IMAGE_RESULT_SUCCESS; + + switch(result) + { + case FF_LOGO_IMAGE_RESULT_INIT_ERROR: + fputs("Logo: Init Image Magick library failed\n", stderr); + return false; + case FF_LOGO_IMAGE_RESULT_RUN_ERROR: + fputs("Logo: Failed to load / convert the image source\n", stderr); + return false; + default + return true; + } } -#else //FF_HAVE_IMAGEMAGICK{6, 7} +#endif //FF_HAVE_IMAGEMAGICK{6, 7} + bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) { + if(!ffFileExists(instance->config.logo.source.chars, S_IFREG)) + { + fputs("Logo: Image file not found\n", stderr); + return false; + } + if(type == FF_LOGO_TYPE_IMAGE_ITERM) return printImageIterm(instance); - if(type == FF_LOGO_TYPE_IMAGE_KITTY) + + if( + type == FF_LOGO_TYPE_IMAGE_KITTY && + ffStrbufEndsWithIgnCaseS(&instance->config.logo.source, ".png") && + instance->config.logo.width && + instance->config.logo.height + ) return printImageKittyDirect(instance); - return false; + + #ifndef FF_HAVE_CHAFA + if(type == FF_LOGO_TYPE_IMAGE_CHAFA) + { + fputs("Logo: Fastfetch was built without Chafa support\n", stderr); + return false; + } + #endif + + #if defined(FF_HAVE_IMAGEMAGICK7) || defined(FF_HAVE_IMAGEMAGICK6) + return printImageIfExistsSlowPath() + #else + fputs("Logo: Fastfetch was built without ImageMagick support\n", stderr); + return false; + #endif } -#endif //FF_HAVE_IMAGEMAGICK{6, 7} diff --git a/src/logo/image/image.h b/src/logo/image/image.h index 67fbbcdc1..83d77131a 100644 --- a/src/logo/image/image.h +++ b/src/logo/image/image.h @@ -11,7 +11,7 @@ typedef enum FFLogoImageResult { FF_LOGO_IMAGE_RESULT_SUCCESS, //Logo printed FF_LOGO_IMAGE_RESULT_INIT_ERROR, //Failed to load library, try again with next IM version - FF_LOGO_IMAGE_RESULT_RUN_ERROR //Failed to load / convert image, cancle whole sixel code + FF_LOGO_IMAGE_RESULT_RUN_ERROR //Failed to load / convert image, cancel whole sixel code } FFLogoImageResult; typedef struct FFLogoRequestData From 051f6643a61acfe69bfa6228ebd1fa53d13322e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Dec 2022 15:23:37 +0800 Subject: [PATCH 297/311] Image: fix build --- src/logo/image/image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index f34738669..5c363506f 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -735,7 +735,7 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type) case FF_LOGO_IMAGE_RESULT_RUN_ERROR: fputs("Logo: Failed to load / convert the image source\n", stderr); return false; - default + default: return true; } } @@ -770,7 +770,7 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) #endif #if defined(FF_HAVE_IMAGEMAGICK7) || defined(FF_HAVE_IMAGEMAGICK6) - return printImageIfExistsSlowPath() + return printImageIfExistsSlowPath(instance, type); #else fputs("Logo: Fastfetch was built without ImageMagick support\n", stderr); return false; From 3d19388086dfdb502ca7f6c3fd900754417e85d0 Mon Sep 17 00:00:00 2001 From: Daniel Coughlan Date: Fri, 23 Dec 2022 22:17:40 +0000 Subject: [PATCH 298/311] Spelling and grammer fixes --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 326e2b7ca..39b1e5a42 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 7+ 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. @@ -57,7 +57,7 @@ The following libraries are used if present at runtime: * [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb) * [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb) -For image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported. +For the image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported. ### Windows @@ -66,12 +66,12 @@ For image logo, iTerm with iterm image protocol should work. Apple Terminal is n * [`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). In addition, special build `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) is provided to support these old systems, which +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). In addition, special build `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) is provided to support these old systems, which 1. Build with the ancient MSVCRT C runtime library, instead of the modern [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library 2. Disable stdout application buffer, which seems to problematic for ConEmu. -For image logo, only chafa is supported due to [the design flaw of ConPTY](https://github.com/microsoft/terminal/issues/1173). In addition, chafa support is not built by default due to the massive dependencies of imagemagick. You must built it yourself. +For the image logo, only chafa is supported due to [the design flaw of ConPTY](https://github.com/microsoft/terminal/issues/1173). In addition, chafa support is not built by default due to the massive dependencies of imagemagick. You must built it yourself. ### Android @@ -146,7 +146,7 @@ Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 s ## FAQ Q: Why do you need a very performant version of neofetch? -> I like putting neofetch in my ~/.bashrc to have a system overwiew whenever i use the terminal, but the slow speed annoyed me, so i created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration. +> I like putting neofetch in my ~/.bashrc to have a system overwiew whenever I use the terminal, but the slow speed annoyed me, so I created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration. -Q: It does not display [*] correctly for me, what can i do? -> This is most likely because your system is not implemented (yet). At the moment i am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration +Q: It does not display [*] correctly for me, what can I do? +> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration From 947923567f932fa6558c82ec5a3117e3da137fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Dec 2022 12:52:13 +0800 Subject: [PATCH 299/311] TerminalShell: fix mintty detection (Windows) --- src/detection/terminalshell/terminalshell_windows.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index a475643df..2bde57cbd 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -242,6 +242,9 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) getenv("ALACRITTY_WINDOW_ID") != nullptr )) term = "Alacritty"; + if(!term) + term = getenv("TERM_PROGRAM"); + //Normal Terminal if(!term) term = getenv("TERM"); From dc35fedd746e1efc26d19047399a06d049707a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Dec 2022 13:00:43 +0800 Subject: [PATCH 300/311] TerminalShell: detect Windows Terminal Preview --- src/detection/terminalshell/terminalshell_windows.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 2bde57cbd..abc22a007 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -203,7 +203,10 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) } if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "WindowsTerminal")) - ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal"); + ffStrbufSetS(&result->terminalPrettyName, ffStrbufContainIgnCaseS(&result->terminalExe, ".WindowsTerminalPreview_") + ? "Windows Terminal Preview" + : "Windows Terminal" + ); else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "conhost")) ffStrbufSetS(&result->terminalPrettyName, "Console Window Host"); else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "Code")) From 83c6e809c69cfe95aac185429139336ba29197e4 Mon Sep 17 00:00:00 2001 From: Daniel Coughlan Date: Sat, 24 Dec 2022 12:09:11 +0000 Subject: [PATCH 301/311] Correct Windows version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39b1e5a42..5a6942ade 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ For the image logo, iTerm with iterm image protocol should work. Apple Terminal * [`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). In addition, special build `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) is provided to support these old systems, which +Note: In Windows 7, 8 and 8.1, [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). In addition, special build `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) is provided to support these old systems, which 1. Build with the ancient MSVCRT C runtime library, instead of the modern [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library 2. Disable stdout application buffer, which seems to problematic for ConEmu. From cb48c1277a30bcd99ac2a80971dd1182a9443d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Dec 2022 22:48:10 +0800 Subject: [PATCH 302/311] Chassis: seperate module It's only supported on Linux --- CMakeLists.txt | 6 +++ presets/all | 2 +- presets/verbose | 2 +- src/common/init.c | 1 + src/data/config_user.txt | 3 ++ src/data/modules.txt | 12 +++-- src/detection/chassis/chassis.h | 18 ++++++++ src/detection/chassis/chassis_linux.c | 55 +++++++++++++++++++++++ src/detection/chassis/chassis_nosupport.c | 10 +++++ src/detection/host/host.h | 3 -- src/detection/host/host_android.c | 3 -- src/detection/host/host_apple.c | 4 -- src/detection/host/host_bsd.c | 4 -- src/detection/host/host_linux.c | 9 ---- src/detection/host/host_windows.c | 3 -- src/fastfetch.c | 11 +++++ src/fastfetch.h | 2 + src/flashfetch.c | 1 + src/modules/chassis.c | 53 ++++++++++++++++++++++ src/modules/host.c | 5 +-- 20 files changed, 171 insertions(+), 36 deletions(-) create mode 100644 src/detection/chassis/chassis.h create mode 100644 src/detection/chassis/chassis_linux.c create mode 100644 src/detection/chassis/chassis_nosupport.c create mode 100644 src/modules/chassis.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e6361229..8ce915f1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,6 +257,7 @@ set(LIBFASTFETCH_SRC src/modules/bios.c src/modules/board.c src/modules/break.c + src/modules/chassis.c src/modules/colors.c src/modules/cpu.c src/modules/cpuUsage.c @@ -310,6 +311,7 @@ if(LINUX) src/detection/battery/battery_linux.c src/detection/bios/bios_linux.c src/detection/board/board_linux.c + src/detection/chassis/chassis_linux.c src/detection/cpu/cpu_linux.c src/detection/cpuUsage/cpuUsage_linux.c src/detection/cursor/cursor_linux.c @@ -348,6 +350,7 @@ elseif(ANDROID) src/detection/battery/battery_nosupport.c src/detection/bios/bios_nosupport.c src/detection/board/board_nosupport.c + src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_linux.c src/detection/cursor/cursor_nosupport.c src/detection/cpuUsage/cpuUsage_linux.c @@ -381,6 +384,7 @@ elseif(BSD) src/detection/battery/battery_nosupport.c src/detection/bios/bios_nosupport.c src/detection/board/board_nosupport.c + src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_bsd.c src/detection/cpuUsage/cpuUsage_bsd.c src/detection/cursor/cursor_linux.c @@ -420,6 +424,7 @@ elseif(APPLE) src/detection/battery/battery_apple.c src/detection/bios/bios_nosupport.c src/detection/board/board_nosupport.c + src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_apple.c src/detection/cpuUsage/cpuUsage_apple.c src/detection/cursor/cursor_nosupport.c @@ -455,6 +460,7 @@ elseif(WIN32) src/detection/battery/battery_windows.c src/detection/bios/bios_windows.c src/detection/board/board_windows.c + src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_windows.c src/detection/cpuUsage/cpuUsage_windows.c src/detection/cursor/cursor_windows.c diff --git a/presets/all b/presets/all index ac42d20c6..d28a033a4 100644 --- a/presets/all +++ b/presets/all @@ -1 +1 @@ ---structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors +--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors diff --git a/presets/verbose b/presets/verbose index e9f09e939..912e5baf4 100644 --- a/presets/verbose +++ b/presets/verbose @@ -1,5 +1,5 @@ --os-format System: {}; Name: {}; Pretty name: {}; ID: {}; ID like: {}; Variant: {}; Variant ID: {}; Version: {}; Version ID: {}; Version codename: {}; Build ID: {}; Architecture: {} ---host-format Family: product_family: {}; product_name: {}; product_version: {}; product_sku: {}; bios_date: {}; bios_release: {}; bios_vendor: {}; bios_version: {}; board_name: {}; board_vendor: {}; board_version: {}; chassis_type: {}; chassis_vendor: {}; chassis_version: {}; sys_vendor: {} +--host-format Family: product_family: {}; product_name: {}; product_version: {}; product_sku: {}; sys_vendor: {} --kernel-format Sysname: {}; Release: {}; Version: {} --uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {} --processes-format Count: {} diff --git a/src/common/init.c b/src/common/init.c index 1e42252bc..88ad09a66 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -167,6 +167,7 @@ static void defaultConfig(FFinstance* instance) initModuleArg(&instance->config.host); initModuleArg(&instance->config.bios); initModuleArg(&instance->config.board); + initModuleArg(&instance->config.chassis); initModuleArg(&instance->config.kernel); initModuleArg(&instance->config.uptime); initModuleArg(&instance->config.processes); diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 2fc0b41fa..acf7f2117 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -217,6 +217,7 @@ # Can be any string. Some of theme take an argument like a format string. See "fastfetch --help format" for help. #--os-key OS #--host-key Host +#--chassis-key Chassis #--kernel-key Kernel #--uptime-key Uptime #--processes-key Processes @@ -260,6 +261,7 @@ # An empty format string (As they are currently below) will behave as if it was not set. #--os-format #--host-format +#--chassis-format #--kernel-format #--uptime-format #--processes-format @@ -302,6 +304,7 @@ # If one of them is set, the module will appear, even if --show-errors is not given. #--os-error #--host-error +#--chassis-error #--kernel-error #--uptime-error #--processes-error diff --git a/src/data/modules.txt b/src/data/modules.txt index 0177c4b5d..4420e2c91 100644 --- a/src/data/modules.txt +++ b/src/data/modules.txt @@ -1,5 +1,8 @@ Battery +Bios +Board Break +Chassis Colors CPU CPUUsage @@ -15,19 +18,18 @@ Icons Kernel Locale LocalIP -Media Memory -OS -OpenCL OpenGL +OS Packages Player +PowerAdapter Processes PublicIP -PowerAdapter Resolution Separator Shell +Song Swap Terminal TerminalFont @@ -36,5 +38,7 @@ Time Title Uptime Vulkan +Weather +Wifi WM WMTheme diff --git a/src/detection/chassis/chassis.h b/src/detection/chassis/chassis.h new file mode 100644 index 000000000..eb6ce4c6c --- /dev/null +++ b/src/detection/chassis/chassis.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_chassis_chassis +#define FF_INCLUDED_detection_chassis_chassis + +#include "fastfetch.h" + +typedef struct FFChassisResult +{ + FFstrbuf chassisType; + FFstrbuf chassisVendor; + FFstrbuf chassisVersion; + FFstrbuf error; +} FFChassisResult; + +void ffDetectChassis(FFChassisResult* result); + +#endif diff --git a/src/detection/chassis/chassis_linux.c b/src/detection/chassis/chassis_linux.c new file mode 100644 index 000000000..192747e7d --- /dev/null +++ b/src/detection/chassis/chassis_linux.c @@ -0,0 +1,55 @@ +#include "chassis.h" +#include "common/io.h" + +#include + +static bool hostValueSet(FFstrbuf* value) +{ + return + value->length > 0 && + ffStrbufStartsWithIgnCaseS(value, "To be filled") != true && + ffStrbufStartsWithIgnCaseS(value, "To be set") != true && + ffStrbufStartsWithIgnCaseS(value, "OEM") != true && + ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true && + ffStrbufIgnCaseCompS(value, "None") != 0 && + ffStrbufIgnCaseCompS(value, "System Product") != 0 && + ffStrbufIgnCaseCompS(value, "System Product Name") != 0 && + ffStrbufIgnCaseCompS(value, "System Product Version") != 0 && + ffStrbufIgnCaseCompS(value, "System Name") != 0 && + ffStrbufIgnCaseCompS(value, "System Version") != 0 && + ffStrbufIgnCaseCompS(value, "Default string") != 0 && + ffStrbufIgnCaseCompS(value, "Undefined") != 0 && + ffStrbufIgnCaseCompS(value, "Not Specified") != 0 && + ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 && + ffStrbufIgnCaseCompS(value, "INVALID") != 0 && + ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 && + ffStrbufIgnCaseCompS(value, "All Series") != 0 + ; +} + +static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) +{ + ffReadFileBuffer(devicesPath, buffer); + if(hostValueSet(buffer)) + return; + + ffReadFileBuffer(classPath, buffer); + if(hostValueSet(buffer)) + return; + + ffStrbufClear(buffer); +} + +void ffDetectChassis(FFChassisResult* result) +{ + ffStrbufInit(&result->error); + + ffStrbufInit(&result->chassisType); + getHostValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->chassisType); + + ffStrbufInit(&result->chassisVendor); + getHostValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->chassisVendor); + + ffStrbufInit(&result->chassisVersion); + getHostValue("/sys/devices/virtual/dmi/id/chassis_version", "/sys/class/dmi/id/chassis_version", &result->chassisVersion); +} diff --git a/src/detection/chassis/chassis_nosupport.c b/src/detection/chassis/chassis_nosupport.c new file mode 100644 index 000000000..42c182567 --- /dev/null +++ b/src/detection/chassis/chassis_nosupport.c @@ -0,0 +1,10 @@ +#include "chassis.h" + +void ffDetectChassis(FFChassisResult* result) +{ + ffStrbufInitS(&result->error, "Not supported on this platform"); + + ffStrbufInit(&result->chassisType); + ffStrbufInit(&result->chassisVendor); + ffStrbufInit(&result->chassisVersion); +} diff --git a/src/detection/host/host.h b/src/detection/host/host.h index e49e8faad..c8b47b6b2 100644 --- a/src/detection/host/host.h +++ b/src/detection/host/host.h @@ -11,9 +11,6 @@ typedef struct FFHostResult FFstrbuf productName; FFstrbuf productVersion; FFstrbuf productSku; - FFstrbuf chassisType; - FFstrbuf chassisVendor; - FFstrbuf chassisVersion; FFstrbuf sysVendor; FFstrbuf error; } FFHostResult; diff --git a/src/detection/host/host_android.c b/src/detection/host/host_android.c index b45283eb3..edeb9cb47 100644 --- a/src/detection/host/host_android.c +++ b/src/detection/host/host_android.c @@ -34,7 +34,4 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInitA(&host->productVersion, 0); ffStrbufInitA(&host->productSku, 0); - ffStrbufInitA(&host->chassisType, 0); - ffStrbufInitA(&host->chassisVendor, 0); - ffStrbufInitA(&host->chassisVersion, 0); } diff --git a/src/detection/host/host_apple.c b/src/detection/host/host_apple.c index a63976d10..d768d83e4 100644 --- a/src/detection/host/host_apple.c +++ b/src/detection/host/host_apple.c @@ -151,11 +151,7 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productFamily); ffStrbufInit(&host->productVersion); ffStrbufInit(&host->productSku); - ffStrbufInitS(&host->sysVendor, "Apple"); - ffStrbufInit(&host->chassisType); - ffStrbufInit(&host->chassisVendor); - ffStrbufInit(&host->chassisVersion); ffStrbufAppendS(&host->error, ffSysctlGetString("hw.model", &host->productFamily)); if(host->error.length == 0) diff --git a/src/detection/host/host_bsd.c b/src/detection/host/host_bsd.c index 13a43acda..8be64b6c3 100644 --- a/src/detection/host/host_bsd.c +++ b/src/detection/host/host_bsd.c @@ -9,11 +9,7 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productFamily); ffStrbufInit(&host->productVersion); ffStrbufInit(&host->productSku); - ffStrbufInit(&host->sysVendor); - ffStrbufInit(&host->chassisType); - ffStrbufInit(&host->chassisVendor); - ffStrbufInit(&host->chassisVersion); ffStrbufAppendS(&host->error, ffSysctlGetString("hw.fdt.model", &host->productName)); } diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c index 483313103..e4e7dfef1 100644 --- a/src/detection/host/host_linux.c +++ b/src/detection/host/host_linux.c @@ -75,15 +75,6 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productSku); getHostValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku); - ffStrbufInit(&host->chassisType); - getHostValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &host->chassisType); - - ffStrbufInit(&host->chassisVendor); - getHostValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &host->chassisVendor); - - ffStrbufInit(&host->chassisVersion); - getHostValue("/sys/devices/virtual/dmi/id/chassis_version", "/sys/class/dmi/id/chassis_version", &host->chassisVersion); - ffStrbufInit(&host->sysVendor); getHostValue("/sys/devices/virtual/dmi/id/sys_vendor", "/sys/class/dmi/id/sys_vendor", &host->sysVendor); diff --git a/src/detection/host/host_windows.c b/src/detection/host/host_windows.c index 5d0ae363b..75afd0563 100644 --- a/src/detection/host/host_windows.c +++ b/src/detection/host/host_windows.c @@ -10,9 +10,6 @@ void ffDetectHostImpl(FFHostResult* host) ffStrbufInit(&host->productVersion); ffStrbufInit(&host->productSku); ffStrbufInit(&host->sysVendor); - ffStrbufInit(&host->chassisType); - ffStrbufInit(&host->chassisVendor); - ffStrbufInit(&host->chassisVersion); FF_HKEY_AUTO_DESTROY hKey = NULL; diff --git a/src/fastfetch.c b/src/fastfetch.c index 8112b9a54..d38bc3d2e 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -106,6 +106,14 @@ static inline void printCommandHelp(const char* command) "board version" ); } + else if(strcasecmp(command, "chassis-format") == 0) + { + constructAndPrintCommandHelpFormat("chassis", "{2} {3}", 4, + "chassis type", + "chassis vendor", + "chassis version" + ); + } else if(strcasecmp(command, "kernel-format") == 0) { constructAndPrintCommandHelpFormat("kernel", "{2}", 3, @@ -1080,6 +1088,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else if(optionParseModuleArgs(key, value, "host", &instance->config.host)) {} else if(optionParseModuleArgs(key, value, "bios", &instance->config.bios)) {} else if(optionParseModuleArgs(key, value, "board", &instance->config.board)) {} + else if(optionParseModuleArgs(key, value, "chassis", &instance->config.chassis)) {} else if(optionParseModuleArgs(key, value, "kernel", &instance->config.kernel)) {} else if(optionParseModuleArgs(key, value, "uptime", &instance->config.uptime)) {} else if(optionParseModuleArgs(key, value, "processes", &instance->config.processes)) {} @@ -1307,6 +1316,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char ffPrintBios(instance); else if(strcasecmp(line, "board") == 0) ffPrintBoard(instance); + else if(strcasecmp(line, "chassis") == 0) + ffPrintChassis(instance); else if(strcasecmp(line, "kernel") == 0) ffPrintKernel(instance); else if(strcasecmp(line, "uptime") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index d38b9b48d..3f592156d 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -106,6 +106,7 @@ typedef struct FFconfig FFModuleArgs os; FFModuleArgs host; FFModuleArgs bios; + FFModuleArgs chassis; FFModuleArgs board; FFModuleArgs kernel; FFModuleArgs uptime; @@ -268,6 +269,7 @@ void ffPrintOS(FFinstance* instance); void ffPrintHost(FFinstance* instance); void ffPrintBios(FFinstance* instance); void ffPrintBoard(FFinstance* instance); +void ffPrintChassis(FFinstance* instance); void ffPrintKernel(FFinstance* instance); void ffPrintUptime(FFinstance* instance); void ffPrintProcesses(FFinstance* instance); diff --git a/src/flashfetch.c b/src/flashfetch.c index 6b961dfa3..769cdfc5d 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -24,6 +24,7 @@ int main(int argc, char** argv) ffPrintHost(&instance); //ffPrintBios(&instance); //ffPrintBoard(&instance); + //ffPrintChassis(&instance); ffPrintKernel(&instance); ffPrintUptime(&instance); //ffPrintProcesses(&instance); diff --git a/src/modules/chassis.c b/src/modules/chassis.c new file mode 100644 index 000000000..93d14eb52 --- /dev/null +++ b/src/modules/chassis.c @@ -0,0 +1,53 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/chassis/chassis.h" + +#define FF_CHASSIS_MODULE_NAME "Chassis" +#define FF_CHASSIS_NUM_FORMAT_ARGS 3 + +void ffPrintChassis(FFinstance* instance) +{ + FFChassisResult result; + ffDetectChassis(&result); + + if(result.error.length > 0) + { + ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, "%*s", result.error.length, result.error.chars); + goto exit; + } + + if(result.chassisType.length == 0) + { + ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.host, "chassis_type is not set by O.E.M."); + return; + } + + if(instance->config.chassis.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.host.key); + + FFstrbuf output; + ffStrbufInitCopy(&output, &result.chassisType); + + if(result.chassisVersion.length > 0) + ffStrbufAppendF(&output, " (%s)", &result.chassisVersion); + + ffStrbufPutTo(&output, stdout); + + ffStrbufDestroy(&output); + } + else + { + ffPrintFormat(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, FF_CHASSIS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisType}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVersion}, + }); + } + +exit: + ffStrbufDestroy(&result.chassisType); + ffStrbufDestroy(&result.chassisVendor); + ffStrbufDestroy(&result.chassisVersion); + ffStrbufDestroy(&result.error); +} diff --git a/src/modules/host.c b/src/modules/host.c index f253ceee4..e8d8e6044 100644 --- a/src/modules/host.c +++ b/src/modules/host.c @@ -3,7 +3,7 @@ #include "detection/host/host.h" #define FF_HOST_MODULE_NAME "Host" -#define FF_HOST_NUM_FORMAT_ARGS 8 +#define FF_HOST_NUM_FORMAT_ARGS 5 void ffPrintHost(FFinstance* instance) { @@ -49,9 +49,6 @@ void ffPrintHost(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisType}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->chassisVersion}, {FF_FORMAT_ARG_TYPE_STRBUF, &host->sysVendor} }); } From 21c76f31c44e8e0391c9eab3a338dc21158250f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 25 Dec 2022 12:43:48 +0800 Subject: [PATCH 303/311] Chassis: fix compiler warnings --- src/modules/chassis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/chassis.c b/src/modules/chassis.c index 93d14eb52..2b73b390d 100644 --- a/src/modules/chassis.c +++ b/src/modules/chassis.c @@ -30,7 +30,7 @@ void ffPrintChassis(FFinstance* instance) ffStrbufInitCopy(&output, &result.chassisType); if(result.chassisVersion.length > 0) - ffStrbufAppendF(&output, " (%s)", &result.chassisVersion); + ffStrbufAppendF(&output, " (%s)", &result.chassisVersion.chars); ffStrbufPutTo(&output, stdout); From 7a6a2ad53057d72e922be78bf9fee9bb6ba17048 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 25 Dec 2022 23:24:50 +0800 Subject: [PATCH 304/311] Chassis: fix compiler warnings My fault --- src/modules/chassis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/chassis.c b/src/modules/chassis.c index 2b73b390d..03a030c85 100644 --- a/src/modules/chassis.c +++ b/src/modules/chassis.c @@ -30,7 +30,7 @@ void ffPrintChassis(FFinstance* instance) ffStrbufInitCopy(&output, &result.chassisType); if(result.chassisVersion.length > 0) - ffStrbufAppendF(&output, " (%s)", &result.chassisVersion.chars); + ffStrbufAppendF(&output, " (%s)", result.chassisVersion.chars); ffStrbufPutTo(&output, stdout); From d956bd2643b373e2a4863e4233d8fb69f0e6c96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 27 Dec 2022 17:25:19 +0800 Subject: [PATCH 305/311] Image: update cache folder's name --- src/logo/image/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 5c363506f..aed67ca6a 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -690,7 +690,7 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type) else ffStrbufEnsureEndsWithC(&requestData.cacheDir, '/'); - ffStrbufAppendS(&requestData.cacheDir, "images"); + ffStrbufAppendS(&requestData.cacheDir, "fastfetch"); ffStrbufEnsureFree(&requestData.cacheDir, PATH_MAX); if(realpath(instance->config.logo.source.chars, requestData.cacheDir.chars + requestData.cacheDir.length) == NULL) From 51606440167b3e3e36edaa8dbab9ea8b5fd39b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 27 Dec 2022 17:25:54 +0800 Subject: [PATCH 306/311] Logo: add Solus logo (#360) --- README.md | 2 +- src/logo/builtin.c | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5a6942ade..53268059f 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Sh ##### Logos ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Devuan, Deepin, Endeavour, Enso, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Vanilla, Void, Windows 11, Windows 8, Windows, Zorin +AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Devuan, Deepin, Endeavour, Enso, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Solus, Ubuntu, Vanilla, Void, Windows 11, Windows 8, Windows, Zorin ``` * Most of the logos have a small variant. Access it by appending _small to the logo name. * Some logos have an old variant. Access it by appending _old to the logo name. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index d876cc5ac..d13b7e4f8 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2120,6 +2120,41 @@ static const FFlogo* getLogoSlackwareSmall() FF_LOGO_RETURN } +static const FFlogo* getLogoSolus() +{ + FF_LOGO_INIT + FF_LOGO_NAMES("solus", "solus-linux") + FF_LOGO_LINES( +"$2 -```````````\n" +" `-+/------------.`\n" +" .---:mNo---------------.\n" +" .-----yMMMy:---------------.\n" +" `------oMMMMMm/----------------`\n" +" .------/MMMMMMMN+----------------.\n" +" .------/NMMMMMMMMm-+/--------------.\n" +"`------/NMMMMMMMMMN-:mh/-------------`\n" +".-----/NMMMMMMMMMMM:-+MMd//oso/:-----.\n" +"-----/NMMMMMMMMMMMM+--mMMMh::smMmyo:--\n" +"----+NMMMMMMMMMMMMMo--yMMMMNo-:yMMMMd/.\n" +".--oMMMMMMMMMMMMMMMy--yMMMMMMh:-yMMMy-`\n" +"`-sMMMMMMMMMMMMMMMMh--dMMMMMMMd:/Ny+y.\n" +"`-/+osyhhdmmNNMMMMMm-/MMMMMMMmh+/ohm+\n" +" .------------:://+-/++++++$1oshddys:\n" +" -hhhhyyyyyyyyyyyhhhhddddhysssso-\n" +" `:ossssssyysssssssssssssssso:`\n" +" `:+ssssssssssssssssssss+-\n" +" `-/+ssssssssssso+/-`\n" +" `.-----..`\n" + ) + FF_LOGO_COLORS( + "34", //blue + "37" //white + ) + FF_LOGO_COLOR_KEYS("34"); //blue + FF_LOGO_COLOR_TITLE("37"); //white + FF_LOGO_RETURN +} + static const FFlogo* getLogoUbuntu() { FF_LOGO_INIT @@ -2146,8 +2181,6 @@ static const FFlogo* getLogoUbuntu() " .':loooooo; ,oooooooooc\n" " ..';::c' .;loooo:'\n" " ." - - ) FF_LOGO_COLORS( "31", //red @@ -2405,6 +2438,7 @@ GetLogoMethod* ffLogoBuiltinGetAll() getLogoRosaLinux, getLogoSlackware, getLogoSlackwareSmall, + getLogoSolus, getLogoUbuntu, getLogoUbuntuOld, getLogoUbuntuSmall, From 0a83423731a56ffb1bf5cb542dcab6ab0bcf7d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 27 Dec 2022 17:36:58 +0800 Subject: [PATCH 307/311] Packages: support eopkg for Solus (#360) UNTESTED --- README.md | 2 +- presets/verbose | 2 +- src/detection/packages/packages.h | 1 + src/detection/packages/packages_linux.c | 1 + src/fastfetch.c | 9 ++++++--- src/modules/packages.c | 4 +++- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 53268059f..9d17386d1 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, C ##### Package managers ``` -Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop, Chocolatey +Pacman, dpkg, rpm, emerge, eopkg, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop, Chocolatey ``` ##### WM themes diff --git a/presets/verbose b/presets/verbose index 912e5baf4..5a9f2f0e5 100644 --- a/presets/verbose +++ b/presets/verbose @@ -3,7 +3,7 @@ --kernel-format Sysname: {}; Release: {}; Version: {} --uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {} --processes-format Count: {} ---packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {} +--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; eopkg: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {} --shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {} --resolution-format Width: {}; Height: {}; Refresh rate: {} --de-format Process name: {}; Pretty name: {}; Version: {} diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index ca8b3feea..9665b5695 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -13,6 +13,7 @@ typedef struct FFPackagesResult uint32_t choco; uint32_t dpkg; uint32_t emerge; + uint32_t eopkg; uint32_t flatpak; uint32_t nixDefault; uint32_t nixSystem; diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index 254565ed2..f4b363d54 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -266,6 +266,7 @@ static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, FFPa packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q"); packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: "); packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE"); + packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR); packageCounts->flatpak += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR); packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default"); packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system"); diff --git a/src/fastfetch.c b/src/fastfetch.c index d38bc3d2e..ac74ab500 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -139,13 +139,14 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "packages-format") == 0) { - constructAndPrintCommandHelpFormat("packages", "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (xbps), {8} (nix-system), {9} (nix-user), {10} (nix-default), {11} (apk), {12} (pkg), {13} (flatpak), {14} (snap), {15} (brew), {16} (port), {17} (scoop)", 17, + constructAndPrintCommandHelpFormat("packages", "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (eopkg), {8} (xbps), {9} (nix-system), {10} (nix-user), {11} (nix-default), {12} (apk), {13} (pkg), {14} (flatpak), {15} (snap), {16} (brew), {17} (brew-cask), {18} (port), {19} (scoop), {20} (choco)", 20, "Number of all packages", "Number of pacman packages", "Pacman branch on manjaro", "Number of dpkg packages", "Number of rpm packages", "Number of emerge packages", + "Number of eopkg packages", "Number of xbps packages", "Number of nix-system packages", "Number of nix-user packages", @@ -155,8 +156,10 @@ static inline void printCommandHelp(const char* command) "Number of flatpak packages", "Number of snap packages", "Number of brew packages", - "Number of macports packages" - "Number of scoop packages" + "Number of brew-cask packages", + "Number of macports packages", + "Number of scoop packages", + "Number of choco packages" ); } else if(strcasecmp(command, "shell-format") == 0) diff --git a/src/modules/packages.c b/src/modules/packages.c index 799ab0d3c..d22a2476f 100644 --- a/src/modules/packages.c +++ b/src/modules/packages.c @@ -3,7 +3,7 @@ #include "detection/packages/packages.h" #define FF_PACKAGES_MODULE_NAME "Packages" -#define FF_PACKAGES_NUM_FORMAT_ARGS 19 +#define FF_PACKAGES_NUM_FORMAT_ARGS 20 void ffPrintPackages(FFinstance* instance) { @@ -42,6 +42,7 @@ void ffPrintPackages(FFinstance* instance) FF_PRINT_PACKAGE(dpkg) FF_PRINT_PACKAGE(rpm) FF_PRINT_PACKAGE(emerge) + FF_PRINT_PACKAGE(eopkg) FF_PRINT_PACKAGE(xbps) FF_PRINT_PACKAGE_NAME(nixSystem, "nix-system") FF_PRINT_PACKAGE_NAME(nixUser, "nix-user") @@ -70,6 +71,7 @@ void ffPrintPackages(FFinstance* instance) {FF_FORMAT_ARG_TYPE_UINT, &counts->dpkg}, {FF_FORMAT_ARG_TYPE_UINT, &counts->rpm}, {FF_FORMAT_ARG_TYPE_UINT, &counts->emerge}, + {FF_FORMAT_ARG_TYPE_UINT, &counts->eopkg}, {FF_FORMAT_ARG_TYPE_UINT, &counts->xbps}, {FF_FORMAT_ARG_TYPE_UINT, &counts->nixSystem}, {FF_FORMAT_ARG_TYPE_UINT, &counts->nixUser}, From 6ff67e87eb79d70824fa501714f49a93ca0fe509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 28 Dec 2022 15:55:31 +0800 Subject: [PATCH 308/311] Memory: refactor, don't cache results --- CMakeLists.txt | 2 -- src/detection/memory/memory.c | 13 ------------- src/detection/memory/memory.h | 2 +- src/detection/memory/memory_apple.c | 2 +- src/detection/memory/memory_bsd.c | 2 +- src/detection/memory/memory_linux.c | 12 ++++++------ src/detection/memory/memory_windows.c | 2 +- src/detection/storage.h | 1 - src/detection/swap/swap.c | 13 ------------- src/detection/swap/swap.h | 2 +- src/detection/swap/swap_apple.c | 2 +- src/detection/swap/swap_bsd.c | 2 +- src/detection/swap/swap_linux.c | 2 +- src/detection/swap/swap_windows.cpp | 2 +- src/fastfetch.h | 1 + src/modules/memory.c | 12 ++++++++++-- 16 files changed, 26 insertions(+), 46 deletions(-) delete mode 100644 src/detection/memory/memory.c delete mode 100644 src/detection/swap/swap.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ce915f1c..866e5d0aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,10 +240,8 @@ set(LIBFASTFETCH_SRC src/detection/host/host.c src/detection/locale/locale.c src/detection/media/media.c - src/detection/memory/memory.c src/detection/os/os.c src/detection/packages/packages.c - src/detection/swap/swap.c src/detection/terminalfont/terminalfont.c src/detection/terminalshell/terminalshell.c src/detection/title.c diff --git a/src/detection/memory/memory.c b/src/detection/memory/memory.c deleted file mode 100644 index 107e7d716..000000000 --- a/src/detection/memory/memory.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "memory.h" -#include "detection/internal.h" - -void ffDetectMemoryImpl(FFMemoryStorage* memory); - -const FFMemoryStorage* ffDetectMemory() -{ - FF_DETECTION_INTERNAL_GUARD(FFMemoryStorage, - ffStrbufInit(&result.error); - - ffDetectMemoryImpl(&result); - ); -} diff --git a/src/detection/memory/memory.h b/src/detection/memory/memory.h index 1114ff4cb..ee34c8038 100644 --- a/src/detection/memory/memory.h +++ b/src/detection/memory/memory.h @@ -5,6 +5,6 @@ #include "detection/storage.h" -const FFMemoryStorage* ffDetectMemory(); +void ffDetectMemory(FFMemoryStorage* result); #endif diff --git a/src/detection/memory/memory_apple.c b/src/detection/memory/memory_apple.c index b3616ec59..f86f52cd4 100644 --- a/src/detection/memory/memory_apple.c +++ b/src/detection/memory/memory_apple.c @@ -4,7 +4,7 @@ #include #include -void ffDetectMemoryImpl(FFMemoryStorage* ram) +void ffDetectMemory(FFMemoryStorage* ram) { ram->bytesTotal = (uint64_t) ffSysctlGetInt64("hw.memsize", 0); if(ram->bytesTotal == 0) diff --git a/src/detection/memory/memory_bsd.c b/src/detection/memory/memory_bsd.c index 881b3dfb3..52d19a0c9 100644 --- a/src/detection/memory/memory_bsd.c +++ b/src/detection/memory/memory_bsd.c @@ -1,7 +1,7 @@ #include "memory.h" #include "common/sysctl.h" -void ffDetectMemoryImpl(FFMemoryStorage* ram) +void ffDetectMemory(FFMemoryStorage* ram) { uint32_t pageSize = (uint32_t) ffSysctlGetInt("hw.pagesize", 0); if(pageSize == 0) diff --git a/src/detection/memory/memory_linux.c b/src/detection/memory/memory_linux.c index 3a5d55ee0..339dda4fe 100644 --- a/src/detection/memory/memory_linux.c +++ b/src/detection/memory/memory_linux.c @@ -3,12 +3,12 @@ #include #include -void ffDetectMemoryImpl(FFMemoryStorage* swap) +void ffDetectMemory(FFMemoryStorage* ram) { FILE* meminfo = fopen("/proc/meminfo", "r"); if(meminfo == NULL) { - ffStrbufAppendS(&swap->error, "Failed to open /proc/meminfo"); + ffStrbufAppendS(&ram->error, "Failed to open /proc/meminfo"); return; } @@ -37,9 +37,9 @@ void ffDetectMemoryImpl(FFMemoryStorage* swap) fclose(meminfo); - swap->bytesTotal = memTotal * (uint64_t) 1024; - if(swap->bytesTotal == 0) - ffStrbufAppendS(&swap->error, "Failed to read MemTotal"); + ram->bytesTotal = memTotal * (uint64_t) 1024; + if(ram->bytesTotal == 0) + ffStrbufAppendS(&ram->error, "Failed to read MemTotal"); else - swap->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024; + ram->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024; } diff --git a/src/detection/memory/memory_windows.c b/src/detection/memory/memory_windows.c index 2072d7232..ef3153843 100644 --- a/src/detection/memory/memory_windows.c +++ b/src/detection/memory/memory_windows.c @@ -1,6 +1,6 @@ #include "memory.h" -void ffDetectMemoryImpl(FFMemoryStorage* ram) +void ffDetectMemory(FFMemoryStorage* ram) { MEMORYSTATUSEX statex = { .dwLength = sizeof(statex), diff --git a/src/detection/storage.h b/src/detection/storage.h index c4cce7ede..c8cf7ed0d 100644 --- a/src/detection/storage.h +++ b/src/detection/storage.h @@ -10,7 +10,6 @@ typedef struct FFMemoryStorage FFstrbuf error; uint64_t bytesUsed; uint64_t bytesTotal; - uint8_t percentage; } FFMemoryStorage; #endif diff --git a/src/detection/swap/swap.c b/src/detection/swap/swap.c deleted file mode 100644 index 0a790c9f7..000000000 --- a/src/detection/swap/swap.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "swap.h" -#include "detection/internal.h" - -void ffDetectSwapImpl(FFMemoryStorage* swap); - -const FFMemoryStorage* ffDetectSwap() -{ - FF_DETECTION_INTERNAL_GUARD(FFMemoryStorage, - ffStrbufInit(&result.error); - - ffDetectSwapImpl(&result); - ); -} diff --git a/src/detection/swap/swap.h b/src/detection/swap/swap.h index a0374cf2b..246b2bfa3 100644 --- a/src/detection/swap/swap.h +++ b/src/detection/swap/swap.h @@ -5,6 +5,6 @@ #include "detection/storage.h" -const FFMemoryStorage* ffDetectSwap(); +void ffDetectSwap(FFMemoryStorage* result); #endif diff --git a/src/detection/swap/swap_apple.c b/src/detection/swap/swap_apple.c index 19ea32c00..34e72802a 100644 --- a/src/detection/swap/swap_apple.c +++ b/src/detection/swap/swap_apple.c @@ -3,7 +3,7 @@ #include -void ffDetectSwapImpl(FFMemoryStorage* swap) +void ffDetectSwap(FFMemoryStorage* swap) { struct xsw_usage xsw; size_t size = sizeof(xsw); diff --git a/src/detection/swap/swap_bsd.c b/src/detection/swap/swap_bsd.c index 8e8089600..b4c5fa7c7 100644 --- a/src/detection/swap/swap_bsd.c +++ b/src/detection/swap/swap_bsd.c @@ -1,7 +1,7 @@ #include "swap.h" #include "common/sysctl.h" -void ffDetectSwapImpl(FFMemoryStorage* swap) +void ffDetectSwap(FFMemoryStorage* swap) { swap->bytesTotal = (uint64_t)ffSysctlGetInt64("vm.swap_total", 0); swap->bytesUsed = (uint64_t)ffSysctlGetInt64("vm.swap_reserved", 0); diff --git a/src/detection/swap/swap_linux.c b/src/detection/swap/swap_linux.c index e176bb158..487b68bcf 100644 --- a/src/detection/swap/swap_linux.c +++ b/src/detection/swap/swap_linux.c @@ -3,7 +3,7 @@ #include #include -void ffDetectSwapImpl(FFMemoryStorage* swap) +void ffDetectSwap(FFMemoryStorage* swap) { FILE* meminfo = fopen("/proc/meminfo", "r"); if(meminfo == NULL) diff --git a/src/detection/swap/swap_windows.cpp b/src/detection/swap/swap_windows.cpp index 5e7597602..224a3ce35 100644 --- a/src/detection/swap/swap_windows.cpp +++ b/src/detection/swap/swap_windows.cpp @@ -9,7 +9,7 @@ extern "C" { #include extern "C" -void ffDetectSwapImpl(FFMemoryStorage* swap) +void ffDetectSwap(FFMemoryStorage* swap) { SYSTEM_INFO sysInfo; GetNativeSystemInfo(&sysInfo); diff --git a/src/fastfetch.h b/src/fastfetch.h index 3f592156d..a33dce50a 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -25,6 +25,7 @@ static inline void ffUnused(int dummy, ...) { (void) dummy; } #define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); +#define FF_UNUSED_PARAM __attribute__ ((__unused__)) #define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) diff --git a/src/modules/memory.c b/src/modules/memory.c index 5fab1b383..149eef45b 100644 --- a/src/modules/memory.c +++ b/src/modules/memory.c @@ -76,10 +76,18 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr void ffPrintMemory(FFinstance* instance) { - printMemory(instance, FF_MEMORY_MODULE_NAME, &instance->config.memory, ffDetectMemory()); + FFMemoryStorage result; + ffStrbufInit(&result.error); + ffDetectMemory(&result); + printMemory(instance, FF_MEMORY_MODULE_NAME, &instance->config.memory, &result); + ffStrbufDestroy(&result.error); } void ffPrintSwap(FFinstance* instance) { - printMemory(instance, FF_SWAP_MODULE_NAME, &instance->config.swap, ffDetectSwap()); + FFMemoryStorage result; + ffStrbufInit(&result.error); + ffDetectSwap(&result); + printMemory(instance, FF_SWAP_MODULE_NAME, &instance->config.swap, &result); + ffStrbufDestroy(&result.error); } From 90359d227e43e76c6717f78dd0e7276ba38693f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 28 Dec 2022 17:18:08 +0800 Subject: [PATCH 309/311] Global: don't require sysinfo.h globally ... which is Linux specific --- CMakeLists.txt | 6 ------ src/common/init.c | 4 ---- src/detection/cpu/cpu_linux.c | 10 +++------- src/detection/processes/processes.h | 2 +- src/detection/processes/processes_bsd.c | 4 +--- src/detection/processes/processes_linux.c | 15 +++++++-------- src/detection/processes/processes_windows.cpp | 6 ++---- src/detection/uptime/uptime.h | 2 +- src/detection/uptime/uptime_bsd.c | 3 +-- src/detection/uptime/uptime_linux.c | 12 ++++++------ src/detection/uptime/uptime_windows.c | 3 +-- src/fastfetch.h | 8 -------- src/modules/processes.c | 2 +- src/modules/uptime.c | 2 +- 14 files changed, 25 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 866e5d0aa..7f65fca70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -497,12 +497,6 @@ add_library(libfastfetch OBJECT target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE) -CHECK_INCLUDE_FILE("sys/sysinfo.h" HAVE_SYSINFO_H) -if(HAVE_SYSINFO_H) - # needs to be public, because changes fastfech.h ABI - target_compile_definitions(libfastfetch PUBLIC FF_HAVE_SYSINFO_H) -endif() - CHECK_INCLUDE_FILE("utmpx.h" HAVE_UTMPX_H) if(HAVE_UTMPX_H) target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX_H) diff --git a/src/common/init.c b/src/common/init.c index 88ad09a66..d36c6ef5c 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -112,10 +112,6 @@ static void initState(FFstate* state) #endif uname(&state->utsname); - #if FF_HAVE_SYSINFO_H - sysinfo(&state->sysinfo); - #endif - initConfigDirs(state); } diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index ee68f1e6f..11b5ec965 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -3,6 +3,7 @@ #include "common/properties.h" #include "detection/temps/temps_linux.h" +#include #include #include @@ -99,13 +100,8 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) cpu->coresPhysical = ffStrbufToUInt16(&physicalCoresBuffer, 1); - #ifdef FF_HAVE_SYSINFO_H - cpu->coresLogical = (uint16_t) get_nprocs_conf(); - cpu->coresOnline = (uint16_t) get_nprocs(); - #else - cpu->coresLogical = 1; - cpu->coresOnline = 1; - #endif + cpu->coresLogical = (uint16_t) get_nprocs_conf(); + cpu->coresOnline = (uint16_t) get_nprocs(); #define BP "/sys/devices/system/cpu/cpufreq/policy0/" if(ffFileExists(BP, S_IFDIR)) diff --git a/src/detection/processes/processes.h b/src/detection/processes/processes.h index bfc4bce6c..74b29e1bb 100644 --- a/src/detection/processes/processes.h +++ b/src/detection/processes/processes.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error); +uint32_t ffDetectProcesses(FFstrbuf* error); #endif diff --git a/src/detection/processes/processes_bsd.c b/src/detection/processes/processes_bsd.c index a09b05a96..36bb14773 100644 --- a/src/detection/processes/processes_bsd.c +++ b/src/detection/processes/processes_bsd.c @@ -6,10 +6,8 @@ #include #endif -uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) +uint32_t ffDetectProcesses(FFstrbuf* error) { - FF_UNUSED(instance); - int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; size_t length; diff --git a/src/detection/processes/processes_linux.c b/src/detection/processes/processes_linux.c index da197b03e..91871f867 100644 --- a/src/detection/processes/processes_linux.c +++ b/src/detection/processes/processes_linux.c @@ -1,12 +1,11 @@ #include "processes.h" -uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) +#include + +uint32_t ffDetectProcesses(FFstrbuf* error) { - #if FF_HAVE_SYSINFO_H - FF_UNUSED(error); - return (uint32_t) instance->state.sysinfo.procs; - #else - ffStrbufAppendS(error, "Unimplemented"); - return 0; - #endif + struct sysinfo info; + if(sysinfo(&info) != 0) + ffStrbufAppendS(error, "sysinfo() failed"); + return (uint32_t) info.procs; } diff --git a/src/detection/processes/processes_windows.cpp b/src/detection/processes/processes_windows.cpp index 860ee8998..69a494629 100644 --- a/src/detection/processes/processes_windows.cpp +++ b/src/detection/processes/processes_windows.cpp @@ -8,10 +8,8 @@ extern "C" { #include #include -uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) +uint32_t ffDetectProcesses(FFstrbuf* error) { - FF_UNUSED(instance); - ULONG size = 0; if(NtQuerySystemInformation(SystemProcessInformation, nullptr, 0, &size) != STATUS_INFO_LENGTH_MISMATCH) { @@ -44,7 +42,7 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) #include "util/windows/wmi.hpp" -uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) +uint32_t ffDetectProcesses(FFstrbuf* error) { FFWmiQuery query(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error); if(!query) diff --git a/src/detection/uptime/uptime.h b/src/detection/uptime/uptime.h index a44d4cecc..6a032b47c 100644 --- a/src/detection/uptime/uptime.h +++ b/src/detection/uptime/uptime.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -uint64_t ffDetectUptime(const FFinstance* instance); +uint64_t ffDetectUptime(); #endif diff --git a/src/detection/uptime/uptime_bsd.c b/src/detection/uptime/uptime_bsd.c index e21eb4183..375065c35 100644 --- a/src/detection/uptime/uptime_bsd.c +++ b/src/detection/uptime/uptime_bsd.c @@ -4,9 +4,8 @@ #include #include -uint64_t ffDetectUptime(const FFinstance* instance) +uint64_t ffDetectUptime() { - FF_UNUSED(instance) struct timeval bootTime; size_t bootTimeSize = sizeof(bootTime); if(sysctl( diff --git a/src/detection/uptime/uptime_linux.c b/src/detection/uptime/uptime_linux.c index e58fa6505..cf4860771 100644 --- a/src/detection/uptime/uptime_linux.c +++ b/src/detection/uptime/uptime_linux.c @@ -1,11 +1,11 @@ #include "uptime.h" -uint64_t ffDetectUptime(const FFinstance* instance) +#include + +uint64_t ffDetectUptime() { - #if FF_HAVE_SYSINFO_H - return (uint64_t) instance->state.sysinfo.uptime; - #else - FF_UNUSED(instance) + struct sysinfo info; + if(sysinfo(&info) != 0) return 0; - #endif + return (uint32_t) info.uptime; } diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c index 8909ad596..9f2dab02a 100644 --- a/src/detection/uptime/uptime_windows.c +++ b/src/detection/uptime/uptime_windows.c @@ -3,8 +3,7 @@ #define WIN32_LEAN_AND_MEAN #include -uint64_t ffDetectUptime(const FFinstance* instance) +uint64_t ffDetectUptime() { - FF_UNUSED(instance) return GetTickCount64() / 1000; } diff --git a/src/fastfetch.h b/src/fastfetch.h index a33dce50a..757e5f083 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -16,10 +16,6 @@ #include "util/windows/utsname.h" #endif -#if FF_HAVE_SYSINFO_H - #include -#endif - #include "util/FFstrbuf.h" #include "util/FFlist.h" @@ -212,10 +208,6 @@ typedef struct FFstate struct passwd* passwd; struct utsname utsname; - #if FF_HAVE_SYSINFO_H - struct sysinfo sysinfo; - #endif - FFlist configDirs; } FFstate; diff --git a/src/modules/processes.c b/src/modules/processes.c index fa71a7611..5157f79b6 100644 --- a/src/modules/processes.c +++ b/src/modules/processes.c @@ -9,7 +9,7 @@ void ffPrintProcesses(FFinstance* instance) { FFstrbuf error; ffStrbufInit(&error); - uint32_t numProcesses = ffDetectProcesses(instance, &error); + uint32_t numProcesses = ffDetectProcesses(&error); if(error.length > 0) { diff --git a/src/modules/uptime.c b/src/modules/uptime.c index cf371778d..48d2b4f4a 100644 --- a/src/modules/uptime.c +++ b/src/modules/uptime.c @@ -7,7 +7,7 @@ void ffPrintUptime(FFinstance* instance) { - uint64_t uptime = ffDetectUptime(instance); + uint64_t uptime = ffDetectUptime(); if(uptime == 0) { From 6becc8f3340b3010f9eeeb4596be0a705ff3de9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 28 Dec 2022 17:27:35 +0800 Subject: [PATCH 310/311] Swap: improve performance on Linux We can't do the same thing with memory because there is no `cachedram` in `struct sysinfo` --- src/detection/swap/swap_linux.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/src/detection/swap/swap_linux.c b/src/detection/swap/swap_linux.c index 487b68bcf..ee623c0c4 100644 --- a/src/detection/swap/swap_linux.c +++ b/src/detection/swap/swap_linux.c @@ -1,34 +1,13 @@ #include "swap.h" -#include -#include +#include void ffDetectSwap(FFMemoryStorage* swap) { - FILE* meminfo = fopen("/proc/meminfo", "r"); - if(meminfo == NULL) - { - ffStrbufAppendS(&swap->error, "Failed to open /proc/meminfo"); - return; - } + struct sysinfo info; + if(sysinfo(&info) != 0) + ffStrbufAppendS(&swap->error, "sysinfo() failed"); - char* line = NULL; - size_t len = 0; - - uint32_t swapTotal = 0, - swapFree = 0; - - while (getline(&line, &len, meminfo) != EOF) - { - if(!sscanf(line, "SwapTotal: %u", &swapTotal)) - sscanf(line, "SwapFree: %u", &swapFree); - } - - if(line != NULL) - free(line); - - fclose(meminfo); - - swap->bytesTotal = swapTotal * (uint64_t) 1024; - swap->bytesUsed = (swapTotal - swapFree) * (uint64_t) 1024; + swap->bytesTotal = info.totalswap * (uint64_t) info.mem_unit; + swap->bytesUsed = (info.totalswap - info.freeswap) * (uint64_t) info.mem_unit; } From fd14513aef1e2cc1f6f84ef6114b0944a2f21210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 28 Dec 2022 21:27:23 +0800 Subject: [PATCH 311/311] Changelog: add changes for 1.8.0 --- CHANGELOG.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c91d6efa5..e77568852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,59 @@ +# 1.8.0 + +This release introduces Windows support! Fastfetch now fully support all major desktop OSes (Linux, macOS, Windows and FreeBSD) + +Notable Changes: +* Bios / Board / Chassis modules are splitted against Host module for performance reasons +* Caching is removed. Option `--nocache` is removed accordingly + +Features: +* Windows (7 and newer) is officially and fully supported +* FreeBSD support is improved greatly (Cpu Temp, Cpu Usage, Disk, Host, Processes, Swap, Terminal / Shell, Uptime) +* Adds a new flag `--stat`, which prints time usage for individual modules +* Adds Wifi module which supports Windows and macOS +* Adds data source option for logo printing +* Detects Homebrew Cellar and Cask seperately +* Detects WSL version +* Detects disk based on mount point +* Exposes more chafa configs +* Improves performance for Cpu Usage, Public IP, Weather modules +* Improves performance for Kitty image protocol when both image width / height specified +* Improves performance for large file loading +* Improves performance for macOS WM and Host detection +* Improves shell and terminal detection on macOS +* Supports Deepin Terminal terminal font +* Supports GPU detection on Android +* Supports Kitty Terminal terminal font +* Supports bar output for percentage values +* Supports eopkg package manager detection +* Supports iTerm image logo protocol +* Supports image logo printing on macOS +* Supports tcsh version detection +* Vulkan module on macOS no longer requires vulkan-loader to work + +Logos: +* Alpine +* CRUX +* EndeavourOS +* Enso +* Garuda small +* Nobara +* OpenMandriva +* Parabola GNU/Linux-libre +* Rocky +* Rosa +* Solus +* Univalent +* Vanilla OS + +Bugfixes: +* Fixes disk size detection on 32bit Linux (#337) +* Fixes cpu freq detection in WSL +* Fixes internal bug of FFstrbuf +* Fixes some memory leaks +* Fixes segfault if 0 is given as argument index +* Lots of code refactors + # 1.7.5 Fixes a crash on linux that could happen when getting zsh version (#285)