From 722063401caa348ba2703b13bd5074085f6a0cc9 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 4 Nov 2024 15:06:33 +0800 Subject: [PATCH 01/61] Packaging: update debian stuff [ci skip] --- debian/changelog | 6 ++++++ debian/files | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index d7fed4125..7fac832e2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fastfetch (2.29.0) jammy; urgency=medium + + * Update to 2.29.0 + + -- Carter Li Mon, 04 Nov 2024 15:05:02 +0800 + fastfetch (2.28.0) jammy; urgency=medium * Update to 2.28.0 diff --git a/debian/files b/debian/files index 386b6ac11..b90fea35f 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -fastfetch_2.28.0_source.buildinfo universe/utils optional +fastfetch_2.29.0_source.buildinfo universe/utils optional From 211fd4b19779d58f5bac984ee19b32533d6bdf6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 5 Nov 2024 09:59:25 +0800 Subject: [PATCH 02/61] Display: add `hdr-compatible` Fix #1376 --- src/modules/display/display.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/display/display.c b/src/modules/display/display.c index 98255ed46..08aa89eea 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -6,7 +6,7 @@ #include -#define FF_DISPLAY_NUM_FORMAT_ARGS 19 +#define FF_DISPLAY_NUM_FORMAT_ARGS 20 static int sortByNameAsc(FFDisplayResult* a, FFDisplayResult* b) { @@ -140,6 +140,7 @@ void ffPrintDisplay(FFDisplayOptions* options) { double ppi = sqrt(result->width * result->width + result->height * result->height) / inch; bool hdrEnabled = result->hdrStatus == FF_DISPLAY_HDR_STATUS_ENABLED; + bool hdrCompatible = result->hdrStatus == FF_DISPLAY_HDR_STATUS_SUPPORTED || result->hdrStatus == FF_DISPLAY_HDR_STATUS_ENABLED; uint32_t iInch = (uint32_t) (inch + 0.5), iPpi = (uint32_t) (ppi + 0.5); char refreshRate[16]; @@ -182,6 +183,7 @@ void ffPrintDisplay(FFDisplayOptions* options) FF_FORMAT_ARG(result->manufactureWeek, "manufacture-week"), FF_FORMAT_ARG(buf, "serial"), FF_FORMAT_ARG(result->platformApi, "platform-api"), + FF_FORMAT_ARG(hdrCompatible, "hdr-compatible"), })); } } @@ -423,6 +425,7 @@ void ffPrintDisplayHelpFormat(void) "Nth week of manufacturing in the year - manufacture-week", "Serial number - serial", "The platform API used when detecting the display - platform-api", + "True if the display is HDR compatible - hdr-compatible", })); } From 40671c78f1577b54ed3898009e7ef72be8d8d524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 5 Nov 2024 10:01:43 +0800 Subject: [PATCH 03/61] Monitor: don't display `()` if display name is not available --- src/modules/monitor/monitor.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/monitor/monitor.c b/src/modules/monitor/monitor.c index 701444c29..93ce917db 100644 --- a/src/modules/monitor/monitor.c +++ b/src/modules/monitor/monitor.c @@ -29,7 +29,9 @@ void ffPrintMonitor(FFMonitorOptions* options) ffStrbufClear(&key); if(options->moduleArgs.key.length == 0) { - ffStrbufAppendF(&key, "%s (%s)", FF_MONITOR_MODULE_NAME, display->name.chars); + ffStrbufAppendS(&key, FF_MONITOR_MODULE_NAME); + if (display->name.length > 0) + ffStrbufAppendF(&key, " (%s)", display->name.chars); } else { From ef974ef8c0a4f3a37c1b2a97239bf955f4649190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 5 Nov 2024 11:06:54 +0800 Subject: [PATCH 04/61] Bluetooth (macOS): support battery level detection --- src/detection/bluetooth/bluetooth_apple.m | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/detection/bluetooth/bluetooth_apple.m b/src/detection/bluetooth/bluetooth_apple.m index abd31a0c2..9e72637ff 100644 --- a/src/detection/bluetooth/bluetooth_apple.m +++ b/src/detection/bluetooth/bluetooth_apple.m @@ -2,6 +2,14 @@ #import +@interface IOBluetoothDevice() + @property (nonatomic) uint8_t batteryPercentCase; + @property (nonatomic) uint8_t batteryPercentCombined; + @property (nonatomic) uint8_t batteryPercentLeft; + @property (nonatomic) uint8_t batteryPercentRight; + @property (nonatomic) uint8_t batteryPercentSingle; +@end + const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */) { NSArray* ioDevices = IOBluetoothDevice.pairedDevices; @@ -14,7 +22,14 @@ ffStrbufInitS(&device->name, ioDevice.name.UTF8String); ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String); ffStrbufInit(&device->type); - device->battery = 0; + + if (ioDevice.batteryPercentSingle) + device->battery = ioDevice.batteryPercentSingle; + else if (ioDevice.batteryPercentCombined) + device->battery = ioDevice.batteryPercentCombined; + else if (ioDevice.batteryPercentCase) + device->battery = ioDevice.batteryPercentCase; + device->connected = !!ioDevice.isConnected; if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorLimitedDiscoverableMode) ffStrbufAppendS(&device->type, "Limited Discoverable Mode, "); From 9a34cb98dc80954b95ad1b9e6730232134b63248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 5 Nov 2024 16:39:04 +0800 Subject: [PATCH 05/61] Bluetooth (macOS): normalize mac address strings --- src/detection/bluetooth/bluetooth_apple.m | 2 ++ src/util/apple/Info.plist.in | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/detection/bluetooth/bluetooth_apple.m b/src/detection/bluetooth/bluetooth_apple.m index 9e72637ff..4f29deb56 100644 --- a/src/detection/bluetooth/bluetooth_apple.m +++ b/src/detection/bluetooth/bluetooth_apple.m @@ -21,6 +21,8 @@ @interface IOBluetoothDevice() FFBluetoothResult* device = ffListAdd(devices); ffStrbufInitS(&device->name, ioDevice.name.UTF8String); ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String); + ffStrbufReplaceAllC(&device->address, '-', ':'); + ffStrbufUpperCase(&device->address); ffStrbufInit(&device->type); if (ioDevice.batteryPercentSingle) diff --git a/src/util/apple/Info.plist.in b/src/util/apple/Info.plist.in index 4fd959cfd..9e24ccb7c 100644 --- a/src/util/apple/Info.plist.in +++ b/src/util/apple/Info.plist.in @@ -10,5 +10,7 @@ @PROJECT_VERSION@ CFBundleDevelopmentRegion English + NSBluetoothAlwaysUsageDescription + For detecting Bluetooth devices From f69a9dab33e262c9e861dcc580d0626f319bb039 Mon Sep 17 00:00:00 2001 From: Lucas Holt Date: Tue, 5 Nov 2024 11:17:23 -0500 Subject: [PATCH 06/61] CMake: Add initial support for MidnightBSD (#1377) * Add initial support for MidnightBSD * Cleanup some issues identified through code review. Add libzfs check as MidnightBSD does have zfs. * Add MidnightBSD check to the version.c detection * Remove `OR MidnightBSD` tests * Clean up --------- Co-authored-by: Carter Li --- CMakeLists.txt | 3 +++ src/detection/version/version.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc33bf5be..8f60c39b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,9 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") set(FreeBSD TRUE CACHE BOOL "..." FORCE) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD") set(OpenBSD TRUE CACHE BOOL "..." FORCE) +elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "MidnightBSD") + set(FreeBSD TRUE CACHE BOOL "..." FORCE) + set(MidnightBSD TRUE CACHE BOOL "..." FORCE) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "NetBSD") set(NetBSD TRUE CACHE BOOL "..." FORCE) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly") diff --git a/src/detection/version/version.c b/src/detection/version/version.c index 8b230eecb..1f1deb348 100644 --- a/src/detection/version/version.c +++ b/src/detection/version/version.c @@ -28,6 +28,8 @@ #define FF_SYSNAME "Linux" #elif defined(__DragonFly__) // We define `__FreeBSD__` on DragonFly BSD for simplification #define FF_SYSNAME "DragonFly" +#elif defined(__MidnightBSD__) + #define FF_SYSNAME "MidnightBSD" #elif defined(__FreeBSD__) #define FF_SYSNAME "FreeBSD" #elif defined(__APPLE__) From 8f750da55956e4f5ba50dca25c247a4c1a1a0584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 5 Nov 2024 22:11:16 +0800 Subject: [PATCH 07/61] Bluetooth (Windows): fix mac address detection --- src/detection/bluetooth/bluetooth_windows.c | 12 ++++++------ .../bluetoothradio/bluetoothradio_windows.c | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/detection/bluetooth/bluetooth_windows.c b/src/detection/bluetooth/bluetooth_windows.c index acb2f4bb4..e163214d3 100644 --- a/src/detection/bluetooth/bluetooth_windows.c +++ b/src/detection/bluetooth/bluetooth_windows.c @@ -33,13 +33,13 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */) do { FFBluetoothResult* device = ffListAdd(devices); ffStrbufInitWS(&device->name, btdi.szName); - ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x", - btdi.Address.rgBytes[0], - btdi.Address.rgBytes[1], - btdi.Address.rgBytes[2], - btdi.Address.rgBytes[3], + ffStrbufInitF(&device->address, "%02X:%02X:%02X:%02X:%02X:%02X", + btdi.Address.rgBytes[5], btdi.Address.rgBytes[4], - btdi.Address.rgBytes[5]); + btdi.Address.rgBytes[3], + btdi.Address.rgBytes[2], + btdi.Address.rgBytes[1], + btdi.Address.rgBytes[0]); ffStrbufInit(&device->type); device->battery = 0; device->connected = !!btdi.fConnected; diff --git a/src/detection/bluetoothradio/bluetoothradio_windows.c b/src/detection/bluetoothradio/bluetoothradio_windows.c index c8471d442..c4482f14d 100644 --- a/src/detection/bluetoothradio/bluetoothradio_windows.c +++ b/src/detection/bluetoothradio/bluetoothradio_windows.c @@ -84,12 +84,12 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */) BLUETOOTH_ADDRESS_STRUCT addr = { .ullLong = blri.localInfo.address }; ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x", - addr.rgBytes[0], - addr.rgBytes[1], - addr.rgBytes[2], - addr.rgBytes[3], + addr.rgBytes[5], addr.rgBytes[4], - addr.rgBytes[5]); + addr.rgBytes[3], + addr.rgBytes[2], + addr.rgBytes[1], + addr.rgBytes[0]); device->lmpVersion = blri.radioInfo.lmpVersion; device->lmpSubversion = blri.radioInfo.lmpSubversion; From 2389d7b580ec40c3343f34caf025cef23b9d70b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 6 Nov 2024 08:08:10 +0800 Subject: [PATCH 08/61] FFstrbuf: correct definition of `StrStrIA` --- src/util/FFstrbuf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index c40f411e5..2ac123352 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -12,7 +12,7 @@ #ifdef _WIN32 // #include - __stdcall const char* StrStrIA(const char* lpFirst, const char* lpSrch); + __stdcall char* StrStrIA(const char* lpFirst, const char* lpSrch); #define strcasestr StrStrIA #endif From 73962088091189895fbab045995314a658c6d38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 6 Nov 2024 08:09:28 +0800 Subject: [PATCH 09/61] Logo (Builtin): fix Lilidog Fix #1373 --- src/logo/builtin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index c20cbc927..51d6119a9 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2392,7 +2392,7 @@ static const FFlogo L[] = { // Lilidog { .names = {"Lilidog"}, - .lines = FASTFETCH_DATATEXT_LOGO_LIBREELEC, + .lines = FASTFETCH_DATATEXT_LOGO_LILIDOG, .colors = { FF_COLOR_FG_BLUE, }, From acb38fa3ee87ea4a0a53e4b5346587ef0b345af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 6 Nov 2024 00:16:05 +0800 Subject: [PATCH 10/61] Bluetooth (Windows): detect battery (WIP) --- CMakeLists.txt | 2 + src/detection/bluetooth/bluetooth_windows.cpp | 31 ++++++++++++++ src/util/windows/wmi.cpp | 40 ++----------------- src/util/windows/wmi.hpp | 20 +++++++++- 4 files changed, 55 insertions(+), 38 deletions(-) create mode 100644 src/detection/bluetooth/bluetooth_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f60c39b8..82db4936e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -915,6 +915,7 @@ elseif(WIN32) src/detection/battery/battery_windows.c src/detection/bios/bios_windows.c src/detection/bluetooth/bluetooth_windows.c + src/detection/bluetooth/bluetooth_windows.cpp src/detection/bluetoothradio/bluetoothradio_windows.c src/detection/board/board_windows.c src/detection/bootmgr/bootmgr_windows.c @@ -1428,6 +1429,7 @@ elseif(WIN32) PRIVATE "imagehlp" PRIVATE "cfgmgr32" PRIVATE "winbrand" + PRIVATE "propsys" ) elseif(FreeBSD) target_link_libraries(libfastfetch diff --git a/src/detection/bluetooth/bluetooth_windows.cpp b/src/detection/bluetooth/bluetooth_windows.cpp new file mode 100644 index 000000000..a0d38f8b2 --- /dev/null +++ b/src/detection/bluetooth/bluetooth_windows.cpp @@ -0,0 +1,31 @@ +extern "C" +{ +#include "bluetooth.h" +} +#include "util/windows/wmi.hpp" +#include "util/windows/unicode.hpp" + +#include + +STDAPI InitVariantFromStringArray(_In_reads_(cElems) PCWSTR *prgsz, _In_ ULONG cElems, _Out_ VARIANT *pvar); + +static const char* detectWithWmi(FFlist* result) +{ + FFWmiQuery query(L"SELECT __PATH FROM Win32_PnPEntity WHERE Service = 'BthHFEnum'", nullptr, FFWmiNamespace::CIMV2); + if(!query) + return "Query WMI service failed"; + + while(FFWmiRecord record = query.next()) + { + IWbemClassObject* pInParams = nullptr; + PCWSTR props[] = { L"{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2" }; + VARIANT devicePropertyKeys; + InitVariantFromStringArray(props, ARRAY_SIZE(props), &devicePropertyKeys); + record.obj->GetMethod(bstr_t(L"GetDeviceProperties"), 0, &pInParams, NULL); + pInParams->Put(L"devicePropertyKeys", 0, &devicePropertyKeys, CIM_FLAG_ARRAY | CIM_STRING); + IWbemCallResult* pResult = nullptr; + query.pService->ExecMethod(bstr_t(record.get(L"__PATH").bstrVal), bstr_t(L"GetDeviceProperties"), 0, nullptr, pInParams, nullptr, &pResult); + // TODO: parse result + } + return NULL; +} diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 6e8db9615..34cfb06d6 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -6,21 +6,6 @@ #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(void) noexcept { SysFreeString(_bstr); } - explicit operator const wchar_t*(void) const noexcept { return _bstr; } - operator BSTR(void) const noexcept { return _bstr; } - - private: - BSTR _bstr; - }; -} - static const char* doInitService(const wchar_t* networkResource, IWbemServices** result) { HRESULT hres; @@ -59,30 +44,11 @@ static const char* doInitService(const wchar_t* networkResource, IWbemServices** if (FAILED(hres)) return "Could not connect WMI server"; - // 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(); - return "Could not set proxy blanket"; - } - *result = pSvc; return NULL; } FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace wmiNs) - : pEnumerator(nullptr) { const char* errStr; if ((errStr = ffInitCom())) @@ -95,7 +61,7 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace static IWbemServices* contexts[(int) FFWmiNamespace::LAST]; IWbemServices* context = contexts[(int)wmiNs]; - if (!contexts[(int)wmiNs]) + if (!context) { if ((errStr = doInitService(wmiNs == FFWmiNamespace::CIMV2 ? L"ROOT\\CIMV2" : L"ROOT\\WMI", &context))) { @@ -106,13 +72,15 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace contexts[(int)wmiNs] = context; } + this->pService = context; + // Use the IWbemServices pointer to make requests of WMI HRESULT hres = context->ExecQuery( bstr_t(L"WQL"), bstr_t(queryStr), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, - &pEnumerator); + &this->pEnumerator); if (FAILED(hres)) { diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index f9e3e9ae3..0c7096231 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -20,9 +20,9 @@ enum class FFWmiNamespace { struct FFWmiRecord { - IWbemClassObject* obj; + IWbemClassObject* obj = nullptr; - explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator): obj(nullptr) { + explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator) { if(!pEnumerator) return; ULONG ret; @@ -53,6 +53,7 @@ struct FFWmiRecord struct FFWmiQuery { + IWbemServices* pService = nullptr; IEnumWbemClassObject* pEnumerator = nullptr; FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error = nullptr, FFWmiNamespace wmiNs = FFWmiNamespace::CIMV2); @@ -75,6 +76,21 @@ struct FFWmiQuery } }; +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(void) noexcept { SysFreeString(_bstr); } + explicit operator const wchar_t*(void) const noexcept { return _bstr; } + operator BSTR(void) const noexcept { return _bstr; } + + private: + BSTR _bstr; + }; +} + #else // Win32 COM headers requires C++ compiler #error Must be included in C++ source file From 07f2a71b3c50a673f64caa3572400d0f4070b09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 9 Nov 2024 20:21:46 +0800 Subject: [PATCH 11/61] Bluetooth (Windows): detect battery level --- CMakeLists.txt | 2 +- src/detection/bluetooth/bluetooth_windows.c | 3 + src/detection/bluetooth/bluetooth_windows.cpp | 115 ++++++++++++++++-- src/util/windows/wmi.hpp | 14 +-- 4 files changed, 113 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82db4936e..be01e71c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1147,7 +1147,7 @@ if(LINUX) elseif(ANDROID) target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE _FILE_OFFSET_BITS=64 "$<$:__BIONIC_FORTIFY>" "$<$:__BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED>") elseif(WIN32) - target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN=1 _WIN32_WINNT=0x0A00 NOMINMAX) # "$<$:_FORTIFY_SOURCE=3>" + target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00 NOMINMAX UNICODE) # "$<$:_FORTIFY_SOURCE=3>" elseif(APPLE) target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 _DARWIN_C_SOURCE) elseif(OpenBSD) diff --git a/src/detection/bluetooth/bluetooth_windows.c b/src/detection/bluetooth/bluetooth_windows.c index e163214d3..80b83837a 100644 --- a/src/detection/bluetooth/bluetooth_windows.c +++ b/src/detection/bluetooth/bluetooth_windows.c @@ -121,5 +121,8 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */) ffBluetoothFindDeviceClose(hFind); + const char* ffBluetoothDetectBattery(FFlist* result); + ffBluetoothDetectBattery(devices); + return NULL; } diff --git a/src/detection/bluetooth/bluetooth_windows.cpp b/src/detection/bluetooth/bluetooth_windows.cpp index a0d38f8b2..70fc1de18 100644 --- a/src/detection/bluetooth/bluetooth_windows.cpp +++ b/src/detection/bluetooth/bluetooth_windows.cpp @@ -5,27 +5,118 @@ extern "C" #include "util/windows/wmi.hpp" #include "util/windows/unicode.hpp" -#include - STDAPI InitVariantFromStringArray(_In_reads_(cElems) PCWSTR *prgsz, _In_ ULONG cElems, _Out_ VARIANT *pvar); -static const char* detectWithWmi(FFlist* result) +template +struct on_scope_exit { + on_scope_exit(Fn &&fn): _fn(std::move(fn)) {} + ~on_scope_exit() { this->_fn(); } + +private: + Fn _fn; +}; + +extern "C" +const char* ffBluetoothDetectBattery(FFlist* devices) { FFWmiQuery query(L"SELECT __PATH FROM Win32_PnPEntity WHERE Service = 'BthHFEnum'", nullptr, FFWmiNamespace::CIMV2); if(!query) return "Query WMI service failed"; - while(FFWmiRecord record = query.next()) + IWbemClassObject* pInParams = nullptr; + on_scope_exit releaseInParams([&] { pInParams && pInParams->Release(); }); { - IWbemClassObject* pInParams = nullptr; - PCWSTR props[] = { L"{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2" }; + IWbemClassObject* pnpEntityClass = nullptr; + + if (FAILED(query.pService->GetObjectW(bstr_t(L"Win32_PnPEntity"), 0, nullptr, &pnpEntityClass, nullptr))) + return "Failed to get PnP entity class"; + on_scope_exit releasePnpEntityClass([&] { pnpEntityClass && pnpEntityClass->Release(); }); + + if (FAILED(pnpEntityClass->GetMethod(bstr_t(L"GetDeviceProperties"), 0, &pInParams, NULL))) + return "Failed to get GetDeviceProperties method"; + VARIANT devicePropertyKeys; - InitVariantFromStringArray(props, ARRAY_SIZE(props), &devicePropertyKeys); - record.obj->GetMethod(bstr_t(L"GetDeviceProperties"), 0, &pInParams, NULL); - pInParams->Put(L"devicePropertyKeys", 0, &devicePropertyKeys, CIM_FLAG_ARRAY | CIM_STRING); - IWbemCallResult* pResult = nullptr; - query.pService->ExecMethod(bstr_t(record.get(L"__PATH").bstrVal), bstr_t(L"GetDeviceProperties"), 0, nullptr, pInParams, nullptr, &pResult); - // TODO: parse result + PCWSTR props[] = { L"{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2", L"DEVPKEY_Bluetooth_DeviceAddress" }; + + if (FAILED(InitVariantFromStringArray(props, ARRAY_SIZE(props), &devicePropertyKeys))) + return "Failed to init variant from string array"; + on_scope_exit releaseDevicePropertyKeys([&] { VariantClear(&devicePropertyKeys); }); + + if (FAILED(pInParams->Put(L"devicePropertyKeys", 0, &devicePropertyKeys, CIM_FLAG_ARRAY | CIM_STRING))) + return "Failed to put devicePropertyKeys"; + } + + while (FFWmiRecord record = query.next()) + { + IWbemCallResult* pCallResult = nullptr; + + if (FAILED(query.pService->ExecMethod(record.get(L"__PATH").bstrVal, bstr_t(L"GetDeviceProperties"), 0, nullptr, pInParams, nullptr, &pCallResult))) + continue; + on_scope_exit releaseCallResult([&] { pCallResult && pCallResult->Release(); }); + + IWbemClassObject* pResultObject = nullptr; + if (FAILED(pCallResult->GetResultObject(WBEM_INFINITE, &pResultObject))) + continue; + on_scope_exit releaseResultObject([&] { pResultObject && pResultObject->Release(); }); + + VARIANT propArray; + if (FAILED(pResultObject->Get(L"deviceProperties", 0, &propArray, nullptr, nullptr))) + continue; + on_scope_exit releasePropArray([&] { VariantClear(&propArray); }); + + if (propArray.vt != (VT_ARRAY | VT_UNKNOWN) || + (propArray.parray->fFeatures & FADF_UNKNOWN) == 0 || + propArray.parray->cDims != 1 || + propArray.parray->rgsabound[0].cElements != 2 + ) + continue; + + uint8_t batt = 0; + for (LONG i = 0; i < 2; i++) + { + IWbemClassObject* object = nullptr; + if (FAILED(SafeArrayGetElement(propArray.parray, &i, &object))) + continue; + + FFWmiRecord rec(object); + auto data = rec.get(L"Data"); + if (data.vt == VT_EMPTY) + break; + + if (i == 0) + batt = data.get(); + else + { + FF_STRBUF_AUTO_DESTROY addr; // MAC address without colon + ffStrbufInitWSV(&addr, data.get()); + if (__builtin_expect(addr.length != 12, 0)) + continue; + + FF_LIST_FOR_EACH(FFBluetoothResult, bt, *devices) + { + if (bt->address.length != 12 + 5) + continue; + + if (addr.chars[0] == bt->address.chars[0] && + addr.chars[1] == bt->address.chars[1] && + addr.chars[2] == bt->address.chars[3] && + addr.chars[3] == bt->address.chars[4] && + addr.chars[4] == bt->address.chars[6] && + addr.chars[5] == bt->address.chars[7] && + addr.chars[6] == bt->address.chars[9] && + addr.chars[7] == bt->address.chars[10] && + addr.chars[8] == bt->address.chars[12] && + addr.chars[9] == bt->address.chars[13] && + addr.chars[10] == bt->address.chars[15] && + addr.chars[11] == bt->address.chars[16]) + { + bt->battery = batt; + break; + } + } + } + } } + return NULL; } diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 0c7096231..f4340ae7b 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -22,13 +22,7 @@ struct FFWmiRecord { IWbemClassObject* obj = nullptr; - explicit FFWmiRecord(IEnumWbemClassObject* pEnumerator) { - if(!pEnumerator) return; - - ULONG ret; - bool ok = SUCCEEDED(pEnumerator->Next(instance.config.general.wmiTimeout, 1, &obj, &ret)) && ret; - if(!ok) obj = nullptr; - } + explicit FFWmiRecord(IWbemClassObject* obj): obj(obj) {}; FFWmiRecord(const FFWmiRecord&) = delete; FFWmiRecord(FFWmiRecord&& other) { *this = (FFWmiRecord&&)other; } ~FFWmiRecord() { if(obj) obj->Release(); } @@ -71,7 +65,11 @@ struct FFWmiQuery } FFWmiRecord next() { - FFWmiRecord result(pEnumerator); + IWbemClassObject* obj = nullptr; + ULONG ret; + pEnumerator->Next(instance.config.general.wmiTimeout, 1, &obj, &ret); + + FFWmiRecord result(obj); return result; } }; From 3fa0d1ab19c69770fd7936b03970af55d32781c3 Mon Sep 17 00:00:00 2001 From: xiaoran007 <52413051+xiaoran007@users.noreply.github.com> Date: Sat, 9 Nov 2024 20:32:35 +0800 Subject: [PATCH 12/61] Host (macOS): add HwModel support for new Mac (2024) (#1381) * host(macOS): add HwModel support for new Mac (iMac, Mac mini and Macbook Pro 2024) * Update host_apple.c --------- Co-authored-by: Carter Li --- src/detection/host/host_apple.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/detection/host/host_apple.c b/src/detection/host/host_apple.c index 61a14e642..552ab8978 100644 --- a/src/detection/host/host_apple.c +++ b/src/detection/host/host_apple.c @@ -111,6 +111,15 @@ static const char* getProductNameWithHwModel(const FFstrbuf* hwModel) else if(ffStrbufStartsWithS(hwModel, "Mac")) { const char* version = hwModel->chars + strlen("Mac"); + if(ffStrEquals(version, "16,3")) return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)"; + if(ffStrEquals(version, "16,2")) return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)"; + if(ffStrEquals(version, "16,1") || + ffStrEquals(version, "16,6") || + ffStrEquals(version, "16,8")) return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)"; + if(ffStrEquals(version, "16,7") || + ffStrEquals(version, "16,5")) return "MacBook Pro (16-inch, 2024, Three Thunderbolt 4 ports)"; + if(ffStrEquals(version, "16,15") || + ffStrEquals(version, "16,10")) return "Mac mini (2024)"; if(ffStrEquals(version, "15,13")) return "MacBook Air (15-inch, M3, 2024)"; if(ffStrEquals(version, "15,2")) return "MacBook Air (13-inch, M3, 2024)"; if(ffStrEquals(version, "15,3")) return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)"; From 837903e8458619646961a29c34df07ed1d43c645 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 9 Nov 2024 21:27:16 +0800 Subject: [PATCH 13/61] DisplayServer: fix deprecation warnings --- src/detection/displayserver/displayserver_apple.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index d51584923..520750110 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -36,6 +36,8 @@ static void detectDisplays(FFDisplayServerResult* ds) if (refreshRate == 0) { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" CVDisplayLinkRef link; if(CVDisplayLinkCreateWithCGDisplay(screen, &link) == kCVReturnSuccess) { @@ -44,6 +46,7 @@ static void detectDisplays(FFDisplayServerResult* ds) refreshRate = time.timeScale / (double) time.timeValue; //59.97... CVDisplayLinkRelease(link); } + #pragma clang diagnostic pop } ffStrbufClear(&buffer); @@ -99,6 +102,10 @@ static void detectDisplays(FFDisplayServerResult* ds) ); if (display) { + #ifndef MAC_OS_X_VERSION_10_11 + FF_CFTYPE_AUTO_RELEASE CFStringRef pe = CGDisplayModeCopyPixelEncoding(mode); + if (pe) display->bitDepth = (uint8_t) (CFStringGetLength(pe) - CFStringFind(pe, CFSTR("B"), 0).location); + #else // https://stackoverflow.com/a/33519316/9976392 // Also shitty, but better than parsing `CFCopyDescription(mode)` CFDictionaryRef dict = (CFDictionaryRef) *((int64_t *)mode + 2); @@ -108,6 +115,7 @@ static void detectDisplays(FFDisplayServerResult* ds) ffCfDictGetInt(dict, kCGDisplayBitsPerSample, &bitDepth); display->bitDepth = (uint8_t) bitDepth; } + #endif if (display->type == FF_DISPLAY_TYPE_BUILTIN) display->hdrStatus = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) From 0284e4ccc4a9b133b045a4c20cb7eb13e77f2441 Mon Sep 17 00:00:00 2001 From: apocelipes Date: Sun, 10 Nov 2024 08:27:34 +0800 Subject: [PATCH 14/61] IO: optimize createSubfolders (#1382) --- src/common/io/io_unix.c | 9 +++++---- src/common/io/io_windows.c | 8 +++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index 4cb946d0e..d66354481 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -23,13 +23,14 @@ static void createSubfolders(const char* fileName) { - FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); - + char path[PATH_MAX]; char *token = NULL; + char *pathTail = path; while((token = strchr(fileName, '/')) != NULL) { - ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName); - mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH); + uint32_t length = (uint32_t)(token - fileName + 1); + pathTail = ffStrCopyN(pathTail, fileName, length); + mkdir(path, S_IRWXU | S_IRGRP | S_IROTH); fileName = token + 1; } } diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index 9f1a96ce5..90f12b76a 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -8,12 +8,14 @@ static void createSubfolders(const char* fileName) { - FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + char path[MAX_PATH]; char *token = NULL; + char *pathTail = path; while((token = strchr(fileName, '/')) != NULL) { - ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName); - CreateDirectoryA(path.chars, NULL); + uint32_t length = (uint32_t)(token - fileName + 1); + pathTail = ffStrCopyN(pathTail, fileName, length); + CreateDirectoryA(path, NULL); fileName = token + 1; } } From 7b81ffc8e4a116422ce2a175601a9ba825e27ad3 Mon Sep 17 00:00:00 2001 From: apocelipes Date: Sun, 10 Nov 2024 08:27:57 +0800 Subject: [PATCH 15/61] FFstrbuf: fix small FFstrbuf allocations in ffStrbufEnsureFree (#1383) --- src/util/FFstrbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 4387a5d7b..68240f00e 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -33,7 +33,7 @@ void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) return; uint32_t allocate = strbuf->allocated; - if(allocate < 2) + if(allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC; while((strbuf->length + free + 1) > allocate) // + 1 for the null byte From 7d406bbae1e17eed35eb806f5259e9fa385df444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 10 Nov 2024 10:47:52 +0800 Subject: [PATCH 16/61] Logo (Builtin): add MidnightBSD --- src/logo/ascii/midnightbsd.txt | 16 ++++++++++++++++ src/logo/builtin.c | 10 ++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/logo/ascii/midnightbsd.txt diff --git a/src/logo/ascii/midnightbsd.txt b/src/logo/ascii/midnightbsd.txt new file mode 100644 index 000000000..39b338461 --- /dev/null +++ b/src/logo/ascii/midnightbsd.txt @@ -0,0 +1,16 @@ + ..:::'''':::.. + .:'''` `''':. + .:'` .::` `':: + :' .::' ':. + .:` .:::' `:. + :` :::: `: +:: ::::: :: +: ::::: :: : +: :::::: .:::' : +:: ::::::. : .:::::: :: + :. :::::::. : :::::::' .: + `:. `':::::::.'.:::::': .:' + `:. '':::::::::::::.: .:` + ':. `''::::::::''' .:' + '':.. ``'`` ..:'' + ''''::::::'''' \ No newline at end of file diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 51d6119a9..daeeabe7d 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2809,6 +2809,16 @@ static const FFlogo M[] = { .colorKeys = FF_COLOR_FG_BLUE, .colorTitle = FF_COLOR_FG_WHITE, }, + // MidnightBSD + { + .names = {"MidnightBSD"}, + .lines = FASTFETCH_DATATEXT_LOGO_MIDNIGHTBSD, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_LIGHT_BLACK, + .colorTitle = FF_COLOR_FG_WHITE, + }, // MidOS { .names = {"MidOS"}, From 7fab6f27ee2f9b832599122f9549f3c5caf984a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 10 Nov 2024 11:35:27 +0800 Subject: [PATCH 17/61] Packages (BSD): support mport --- src/detection/packages/packages.h | 3 ++- src/detection/packages/packages_bsd.c | 4 ++-- src/modules/packages/option.h | 1 + src/modules/packages/packages.c | 11 +++++++++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index aef482d84..2e3213e7e 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -25,17 +25,18 @@ typedef struct FFPackagesResult uint32_t nixUser; uint32_t opkg; uint32_t pacman; + uint32_t pacstall; uint32_t paludis; uint32_t pkg; uint32_t pkgtool; uint32_t macports; + uint32_t mport; uint32_t rpm; uint32_t scoop; uint32_t snap; uint32_t sorcery; uint32_t winget; uint32_t xbps; - uint32_t pacstall; uint32_t all; //Make sure this goes last diff --git a/src/detection/packages/packages_bsd.c b/src/detection/packages/packages_bsd.c index 511af569b..4ad2d8b49 100644 --- a/src/detection/packages/packages_bsd.c +++ b/src/detection/packages/packages_bsd.c @@ -21,7 +21,7 @@ static uint32_t getSQLite3Int(const char* dbPath, const char* query, const char* void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options) { if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT)) - { result->pkg = getSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg/local.sqlite", "SELECT count(*) FROM packages", "pkg"); - } + if (!(options->disabled & FF_PACKAGES_FLAG_MPORT_BIT)) + result->mport = getSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/mport/master.db", "SELECT count(*) FROM packages", "mport"); } diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h index e3f3d54c7..976640d09 100644 --- a/src/modules/packages/option.h +++ b/src/modules/packages/option.h @@ -33,6 +33,7 @@ typedef enum FFPackagesFlags FF_PACKAGES_FLAG_GUIX_BIT = 1 << 23, FF_PACKAGES_FLAG_LINGLONG_BIT = 1 << 24, FF_PACKAGES_FLAG_PACSTALL_BIT = 1 << 25, + FF_PACKAGES_FLAG_MPORT_BIT = 1 << 26, } FFPackagesFlags; typedef struct FFPackagesOptions diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index e33b18d49..c33b7ca8e 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -4,7 +4,7 @@ #include "modules/packages/packages.h" #include "util/stringUtils.h" -#define FF_PACKAGES_NUM_FORMAT_ARGS 38 +#define FF_PACKAGES_NUM_FORMAT_ARGS 39 void ffPrintPackages(FFPackagesOptions* options) { @@ -73,6 +73,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_PRINT_PACKAGE_NAME(guixHome, "guix-home") FF_PRINT_PACKAGE(linglong) FF_PRINT_PACKAGE(pacstall) + FF_PRINT_PACKAGE(mport) putchar('\n'); } @@ -117,6 +118,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_FORMAT_ARG(counts.guixHome, "guix-home"), FF_FORMAT_ARG(counts.linglong, "linglong"), FF_FORMAT_ARG(counts.pacstall, "pacstall"), + FF_FORMAT_ARG(counts.mport, "mport"), FF_FORMAT_ARG(nixAll, "nix-all"), FF_FORMAT_ARG(flatpakAll, "flatpak-all"), FF_FORMAT_ARG(brewAll, "brew-all"), @@ -179,6 +181,7 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, break; case 'M': if (false); FF_TEST_PACKAGE_NAME(MACPORTS) + FF_TEST_PACKAGE_NAME(MPORT) break; case 'N': if (false); FF_TEST_PACKAGE_NAME(NIX) @@ -279,7 +282,7 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module) case 'F': if (false); FF_TEST_PACKAGE_NAME(FLATPAK) break; - case 'G': if (false); + case 'G': if (false); FF_TEST_PACKAGE_NAME(GUIX) break; case 'L': if (false); @@ -289,6 +292,7 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module) break; case 'M': if (false); FF_TEST_PACKAGE_NAME(MACPORTS) + FF_TEST_PACKAGE_NAME(MPORT) break; case 'N': if (false); FF_TEST_PACKAGE_NAME(NIX) @@ -353,6 +357,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do FF_TEST_PACKAGE_NAME(LPKG) FF_TEST_PACKAGE_NAME(LPKGBUILD) FF_TEST_PACKAGE_NAME(MACPORTS) + FF_TEST_PACKAGE_NAME(MPORT) FF_TEST_PACKAGE_NAME(NIX) FF_TEST_PACKAGE_NAME(OPKG) FF_TEST_PACKAGE_NAME(PACMAN) @@ -418,6 +423,7 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy FF_APPEND_PACKAGE_COUNT(guixHome) FF_APPEND_PACKAGE_COUNT(linglong) FF_APPEND_PACKAGE_COUNT(pacstall) + FF_APPEND_PACKAGE_COUNT(mport) yyjson_mut_obj_add_strbuf(doc, obj, "pacmanBranch", &counts.pacmanBranch); } @@ -458,6 +464,7 @@ void ffPrintPackagesHelpFormat(void) "Number of guix-home packages - guix-home", "Number of linglong packages - linglong", "Number of pacstall packages - pacstall", + "Number of mport packages - mport", "Total number of all nix packages - nix-all", "Total number of all flatpak app packages - flatpak-all", "Total number of all brew packages - brew-all", From 59c666515aeda5a5b95ee20a707a7b29a7a0187b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 10 Nov 2024 20:11:02 +0800 Subject: [PATCH 18/61] Version (MidnightBSD): support libc version detection --- CMakeLists.txt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be01e71c0..da782da36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1127,17 +1127,25 @@ if(APPLE AND EXISTS "/usr/bin/otool") target_compile_definitions(libfastfetch PUBLIC FF_LIBSYSTEM_VERSION="${CMAKE_MATCH_1}") endif() endif() -if(FreeBSD AND EXISTS "/usr/local/bin/objdump") +if(MidnightBSD AND EXISTS "/usr/bin/objdump") + execute_process(COMMAND /bin/sh -c "/usr/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1" + OUTPUT_VARIABLE OBJDUMP_T_RESULT) + if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)") + message(STATUS "Found FBSD ${CMAKE_MATCH_1}") + target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}") + endif() +elseif(FreeBSD AND EXISTS "/usr/local/bin/objdump") execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1" OUTPUT_VARIABLE OBJDUMP_T_RESULT) if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)") + message(STATUS "Found FBSD ${CMAKE_MATCH_1}") target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}") endif() -endif() -if(DragonFly AND EXISTS "/usr/local/bin/objdump") +elseif(DragonFly AND EXISTS "/usr/local/bin/objdump") execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'DF[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1" OUTPUT_VARIABLE OBJDUMP_T_RESULT) if("${OBJDUMP_T_RESULT}" MATCHES "DF([0-9]+\\.[0-9]+)") + message(STATUS "Found DF ${CMAKE_MATCH_1}") target_compile_definitions(libfastfetch PUBLIC FF_DF_VERSION="${CMAKE_MATCH_1}") endif() endif() From f98e6c9d4e5835279ced048c21f54567433094dd Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 10 Nov 2024 20:15:42 +0800 Subject: [PATCH 19/61] Sound (BSD): trim device names --- src/detection/sound/sound_bsd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/sound/sound_bsd.c b/src/detection/sound/sound_bsd.c index af601b5a5..4487b42a4 100644 --- a/src/detection/sound/sound_bsd.c +++ b/src/detection/sound/sound_bsd.c @@ -39,6 +39,7 @@ const char* ffDetectSound(FFlist* devices) FFSoundDevice* device = ffListAdd(devices); ffStrbufInitS(&device->identifier, path); ffStrbufInitF(&device->name, "%s %s", ci.longname, ci.hw_info); + ffStrbufTrimRightSpace(&device->name); device->volume = mutemask & SOUND_MASK_VOLUME ? 0 : ((uint8_t) volume /*left*/ + (uint8_t) (volume >> 8) /*right*/) / 2; From 4534f185255141f3eb4c26da9b1edcbcf9a96c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 10 Nov 2024 13:07:12 +0800 Subject: [PATCH 20/61] Battery: don't print index in multi-battery device --- src/modules/battery/battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/battery/battery.c b/src/modules/battery/battery.c index f27ff29e7..cc30b4262 100644 --- a/src/modules/battery/battery.c +++ b/src/modules/battery/battery.c @@ -41,7 +41,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin if(options->moduleArgs.outputFormat.length == 0) { - ffPrintLogoAndKey(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); + ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); bool showStatus = @@ -100,7 +100,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin ffPercentAppendBar(&capacityBar, result->capacity, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate(); ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig, &options->moduleArgs); - FF_PRINT_FORMAT_CHECKED(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) { + FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) { FF_FORMAT_ARG(result->manufacturer, "manufacturer"), FF_FORMAT_ARG(result->modelName, "model-name"), FF_FORMAT_ARG(result->technology, "technology"), From d10c14721a460da4ee26764c363a0bab23026da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 10 Nov 2024 13:07:30 +0800 Subject: [PATCH 21/61] Disk: be able to print disk indices --- src/modules/disk/disk.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c index 69ed5f8b6..5dddf1e90 100644 --- a/src/modules/disk/disk.c +++ b/src/modules/disk/disk.c @@ -10,7 +10,7 @@ #define FF_DISK_NUM_FORMAT_ARGS 14 #pragma GCC diagnostic ignored "-Wsign-conversion" -static void printDisk(FFDiskOptions* options, const FFDisk* disk) +static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index) { FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); @@ -35,11 +35,12 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk) } else { - FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 4, ((FFformatarg[]){ + FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 5, ((FFformatarg[]){ FF_FORMAT_ARG(disk->mountpoint, "mountpoint"), FF_FORMAT_ARG(disk->name, "name"), FF_FORMAT_ARG(disk->mountFrom, "mount-from"), FF_FORMAT_ARG(options->moduleArgs.keyIcon, "icon"), + FF_FORMAT_ARG(index, "index"), })); } @@ -150,12 +151,13 @@ void ffPrintDisk(FFDiskOptions* options) } else { + uint32_t index = 0; FF_LIST_FOR_EACH(FFDisk, disk, disks) { if(__builtin_expect(options->folders.length == 0, 1) && (disk->type & ~options->showTypes)) continue; - printDisk(options, disk); + printDisk(options, disk, ++index); } } From 08a92a4324ff8ffe9efa4bfd1cc88764448f3786 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 10 Nov 2024 13:28:48 +0800 Subject: [PATCH 22/61] CPU (OpenBSD): support CPU temp detection --- src/detection/cpu/cpu_obsd.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/detection/cpu/cpu_obsd.c b/src/detection/cpu/cpu_obsd.c index 04d550198..298f064d6 100644 --- a/src/detection/cpu/cpu_obsd.c +++ b/src/detection/cpu/cpu_obsd.c @@ -1,6 +1,9 @@ #include "cpu.h" #include "common/sysctl.h" +#include +#include + const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { if (ffSysctlGetString(CTL_HW, HW_MODEL, &cpu->name)) @@ -13,7 +16,14 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) ffCPUDetectSpeedByCpuid(cpu); cpu->frequencyBase = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0); - cpu->temperature = FF_CPU_TEMP_UNSET; // HW_SENSORS? + cpu->temperature = FF_CPU_TEMP_UNSET; + if (options->temp) + { + struct sensor sensors; + size_t size = sizeof(sensors); + if (sysctl((int[]) {CTL_HW, HW_SENSORS, 0, SENSOR_TEMP, 0}, 5, &sensors, &size, NULL, 0) == 0) + cpu->temperature = (double) (sensors.value - 273150000) / 1E6; + } return NULL; } From 4f9645e7ff1385353c29a0aa689cfc3938574d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 10 Nov 2024 13:14:56 +0800 Subject: [PATCH 23/61] Logo (Builtin): add Unifi --- src/logo/ascii/unifi.txt | 6 ++++++ src/logo/builtin.c | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/logo/ascii/unifi.txt diff --git a/src/logo/ascii/unifi.txt b/src/logo/ascii/unifi.txt new file mode 100644 index 000000000..dff463228 --- /dev/null +++ b/src/logo/ascii/unifi.txt @@ -0,0 +1,6 @@ + ___ ___ .__________.__ + | | |____ |__\_ ____/__| + | | / \| || __) | | + | | | | \ || \ | | + |______|___| /__||__/ |__| + |_/ \ No newline at end of file diff --git a/src/logo/builtin.c b/src/logo/builtin.c index daeeabe7d..dbd8dfdd4 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -4602,6 +4602,15 @@ static const FFlogo U[] = { FF_COLOR_FG_WHITE, }, }, + // Unifi + { + .names = {"Unifi"}, + .lines = FASTFETCH_DATATEXT_LOGO_UNIFI, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_WHITE, + }, + }, // Univalent { .names = {"Univalent"}, From f9713d5ee2a26aeab33daed33e9ca4af1696acf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 10 Nov 2024 13:57:57 +0800 Subject: [PATCH 24/61] OS (Android): display android icon --- src/modules/os/os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/os/os.c b/src/modules/os/os.c index 8224b65c5..cc488382f 100644 --- a/src/modules/os/os.c +++ b/src/modules/os/os.c @@ -224,10 +224,10 @@ void ffInitOSOptions(FFOSOptions* options) "" #elif __FreeBSD__ "󰣠" - #elif __linux__ - "" #elif __ANDROID__ "" + #elif __linux__ + "" #elif __sun "" #elif __OpenBSD__ From f989a1a982bce172e42226d9a2d3a36daeb45d78 Mon Sep 17 00:00:00 2001 From: Emily Astranova Date: Sun, 10 Nov 2024 09:37:29 -0600 Subject: [PATCH 25/61] Doc: fix typo in README (#1385) [ci skip] Changed "deserved" to "derived" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6487d0e70..2246074f8 100644 --- a/README.md +++ b/README.md @@ -194,7 +194,7 @@ See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096). Neofetch incorrectly counts `rc` packages ( the package has been removed, but that the configuration files remain ). Bug https://github.com/dylanaraps/neofetch/issues/2278 -### Q: I use Debian / Ubuntu / Debian deserved distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is it a bug? +### Q: I use Debian / Ubuntu / Debian derived distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is it a bug? Try upgrading `pci.ids`: Download and overwrite file `/usr/share/hwdata/pci.ids`. For AMD GPUs, you should also upgrade `amdgpu.ids`: Download and overwrite file `/usr/share/libdrm/amdgpu.ids` From 07d0743a18935eae4839e6604ba95e49a10ef30d Mon Sep 17 00:00:00 2001 From: Tibo G <35193961+Tiuxi@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:43:43 -0500 Subject: [PATCH 26/61] Logo (Builtin): add cosmicDE logo (#1386) * add cosmicDE logo * Update cosmic.txt * Update builtin.c --------- Co-authored-by: tgallone Co-authored-by: Carter Li --- src/logo/ascii/cosmic.txt | 11 +++++++++++ src/logo/builtin.c | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/logo/ascii/cosmic.txt diff --git a/src/logo/ascii/cosmic.txt b/src/logo/ascii/cosmic.txt new file mode 100644 index 000000000..10fd4e18f --- /dev/null +++ b/src/logo/ascii/cosmic.txt @@ -0,0 +1,11 @@ + .xMMMMMMMMMMMMMMMMMMMMMMx. +JDMMMMMMMMMMMMMMMMMMMMMMMMOL +IMMMY' 'YMMMI +MMMM MMMM +MMMM MMMM +IMMMb dMMMI +'YMMMMMMMMb. .dMMMMMMMMK' + 'OMMMMMMMP' 'YMMMMMMMP' + + $2.x76767$36767676$476767$5676x. + $2'*76767$36767676$476767$5676*' diff --git a/src/logo/builtin.c b/src/logo/builtin.c index dbd8dfdd4..77d2e05c0 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1070,6 +1070,20 @@ static const FFlogo C[] = { .colorKeys = FF_COLOR_FG_BLUE, .colorTitle = FF_COLOR_FG_WHITE, }, + // Cosmic DE + { + .names = {"Cosmic"}, + .lines = FASTFETCH_DATATEXT_LOGO_COSMIC, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_LIGHT_YELLOW, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_LIGHT_RED, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_LIGHT_RED, + .colorTitle = FF_COLOR_FG_YELLOW, + }, // CRUX { .names = {"CRUX"}, From 0a61031463e22bef72ce9fb5acc5a7a49700ee7d Mon Sep 17 00:00:00 2001 From: apocelipes Date: Mon, 11 Nov 2024 07:58:24 +0800 Subject: [PATCH 27/61] tests: add FFstrbuf smallest allocation test & minor fix (#1387) --- tests/list.c | 2 +- tests/strbuf.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/list.c b/tests/list.c index 5119b046f..c7c1752eb 100644 --- a/tests/list.c +++ b/tests/list.c @@ -116,7 +116,7 @@ int main(void) { FF_LIST_AUTO_DESTROY test = ffListCreate(1); - VERIFY(test.elementSize = 1); + VERIFY(test.elementSize == 1); VERIFY(test.capacity == 0); VERIFY(test.length == 0); } diff --git a/tests/strbuf.c b/tests/strbuf.c index d901faab1..7d016467e 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -442,6 +442,19 @@ int main(void) VERIFY(ffStrbufEqualS(&strbuf, "AA12BB3456CCDD")); ffStrbufDestroy(&strbuf); + // smallest allocation test + { + FF_STRBUF_AUTO_DESTROY strbuf1 = ffStrbufCreateA(10); + VERIFY(strbuf1.allocated == 10); + ffStrbufEnsureFree(&strbuf1, 16); + VERIFY(strbuf1.allocated == 32); + + FF_STRBUF_AUTO_DESTROY strbuf2 = ffStrbufCreate(); + VERIFY(strbuf2.allocated == 0); + ffStrbufEnsureFree(&strbuf2, 16); + VERIFY(strbuf2.allocated == 32); + } + //Success puts("\e[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET); } From 4799f9277e57ec55925d56576841a51092d862a9 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 11 Nov 2024 17:33:22 +0800 Subject: [PATCH 28/61] Revert "IO: optimize createSubfolders (#1382)" (#1390) This reverts commit 0284e4ccc4a9b133b045a4c20cb7eb13e77f2441. --- src/common/io/io_unix.c | 9 ++++----- src/common/io/io_windows.c | 8 +++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index d66354481..4cb946d0e 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -23,14 +23,13 @@ static void createSubfolders(const char* fileName) { - char path[PATH_MAX]; + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + char *token = NULL; - char *pathTail = path; while((token = strchr(fileName, '/')) != NULL) { - uint32_t length = (uint32_t)(token - fileName + 1); - pathTail = ffStrCopyN(pathTail, fileName, length); - mkdir(path, S_IRWXU | S_IRGRP | S_IROTH); + ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName); + mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH); fileName = token + 1; } } diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index 90f12b76a..9f1a96ce5 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -8,14 +8,12 @@ static void createSubfolders(const char* fileName) { - char path[MAX_PATH]; + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); char *token = NULL; - char *pathTail = path; while((token = strchr(fileName, '/')) != NULL) { - uint32_t length = (uint32_t)(token - fileName + 1); - pathTail = ffStrCopyN(pathTail, fileName, length); - CreateDirectoryA(path, NULL); + ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName); + CreateDirectoryA(path.chars, NULL); fileName = token + 1; } } From 5e7d9ed45e1909de1a4132f10b47479ea0be2064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 10 Nov 2024 23:32:22 +0800 Subject: [PATCH 29/61] Packages (Linux): add qi support --- doc/json_schema.json | 4 +++ src/detection/packages/packages.h | 5 ++-- src/detection/packages/packages_linux.c | 1 + src/modules/packages/option.h | 1 + src/modules/packages/packages.c | 33 ++++++++++++++++--------- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/doc/json_schema.json b/doc/json_schema.json index 6c30442c4..7450e0884 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -1942,15 +1942,19 @@ "eopkg", "flatpak", "guix", + "linglong", "lpkg", "lpkgbuild", "macports", + "mport", "nix", "opkg", "pacman", + "pacstall", "paludis", "pkg", "pkgtool", + "qi", "rpm", "scoop", "snap", diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index 2e3213e7e..261c8acb0 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -20,6 +20,8 @@ typedef struct FFPackagesResult uint32_t linglong; uint32_t lpkg; uint32_t lpkgbuild; + uint32_t macports; + uint32_t mport; uint32_t nixDefault; uint32_t nixSystem; uint32_t nixUser; @@ -29,8 +31,7 @@ typedef struct FFPackagesResult uint32_t paludis; uint32_t pkg; uint32_t pkgtool; - uint32_t macports; - uint32_t mport; + uint32_t qi; uint32_t rpm; uint32_t scoop; uint32_t snap; diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index a978929c4..6d5eff079 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -573,6 +573,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, } if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", DT_DIR); if (!(options->disabled & FF_PACKAGES_FLAG_PACSTALL_BIT)) packageCounts->pacstall += getNumElements(baseDir, "/var/lib/pacstall/metadata", DT_REG); + if (!(options->disabled & FF_PACKAGES_FLAG_QI_BIT)) packageCounts->qi += getNumStrings(baseDir, "/var/qi/installed_packages.list", "\n", "qi"); } static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options) diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h index 976640d09..ddb7d0f13 100644 --- a/src/modules/packages/option.h +++ b/src/modules/packages/option.h @@ -34,6 +34,7 @@ typedef enum FFPackagesFlags FF_PACKAGES_FLAG_LINGLONG_BIT = 1 << 24, FF_PACKAGES_FLAG_PACSTALL_BIT = 1 << 25, FF_PACKAGES_FLAG_MPORT_BIT = 1 << 26, + FF_PACKAGES_FLAG_QI_BIT = 1 << 27, } FFPackagesFlags; typedef struct FFPackagesOptions diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index c33b7ca8e..3241b714d 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -4,7 +4,7 @@ #include "modules/packages/packages.h" #include "util/stringUtils.h" -#define FF_PACKAGES_NUM_FORMAT_ARGS 39 +#define FF_PACKAGES_NUM_FORMAT_ARGS 40 void ffPrintPackages(FFPackagesOptions* options) { @@ -74,6 +74,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_PRINT_PACKAGE(linglong) FF_PRINT_PACKAGE(pacstall) FF_PRINT_PACKAGE(mport) + FF_PRINT_PACKAGE(qi) putchar('\n'); } @@ -119,6 +120,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_FORMAT_ARG(counts.linglong, "linglong"), FF_FORMAT_ARG(counts.pacstall, "pacstall"), FF_FORMAT_ARG(counts.mport, "mport"), + FF_FORMAT_ARG(counts.qi, "qi"), FF_FORMAT_ARG(nixAll, "nix-all"), FF_FORMAT_ARG(flatpakAll, "flatpak-all"), FF_FORMAT_ARG(brewAll, "brew-all"), @@ -196,6 +198,9 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, FF_TEST_PACKAGE_NAME(PKG) FF_TEST_PACKAGE_NAME(PKGTOOL) break; + case 'Q': if (false); + FF_TEST_PACKAGE_NAME(QI) + break; case 'R': if (false); FF_TEST_PACKAGE_NAME(RPM) break; @@ -307,6 +312,9 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module) FF_TEST_PACKAGE_NAME(PKG) FF_TEST_PACKAGE_NAME(PKGTOOL) break; + case 'Q': if (false); + FF_TEST_PACKAGE_NAME(QI) + break; case 'R': if (false); FF_TEST_PACKAGE_NAME(RPM) break; @@ -365,6 +373,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do FF_TEST_PACKAGE_NAME(PALUDIS) FF_TEST_PACKAGE_NAME(PKG) FF_TEST_PACKAGE_NAME(PKGTOOL) + FF_TEST_PACKAGE_NAME(QI) FF_TEST_PACKAGE_NAME(RPM) FF_TEST_PACKAGE_NAME(SCOOP) FF_TEST_PACKAGE_NAME(SNAP) @@ -393,6 +402,7 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy #define FF_APPEND_PACKAGE_COUNT(name) yyjson_mut_obj_add_uint(doc, obj, #name, counts.name); FF_APPEND_PACKAGE_COUNT(all) + FF_APPEND_PACKAGE_COUNT(am) FF_APPEND_PACKAGE_COUNT(apk) FF_APPEND_PACKAGE_COUNT(brew) FF_APPEND_PACKAGE_COUNT(brewCask) @@ -402,34 +412,34 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy FF_APPEND_PACKAGE_COUNT(eopkg) FF_APPEND_PACKAGE_COUNT(flatpakSystem) FF_APPEND_PACKAGE_COUNT(flatpakUser) + FF_APPEND_PACKAGE_COUNT(guixSystem) + FF_APPEND_PACKAGE_COUNT(guixUser) + FF_APPEND_PACKAGE_COUNT(guixHome) + FF_APPEND_PACKAGE_COUNT(linglong) + FF_APPEND_PACKAGE_COUNT(mport) FF_APPEND_PACKAGE_COUNT(nixDefault) FF_APPEND_PACKAGE_COUNT(nixSystem) FF_APPEND_PACKAGE_COUNT(nixUser) + FF_APPEND_PACKAGE_COUNT(opkg) FF_APPEND_PACKAGE_COUNT(pacman) + FF_APPEND_PACKAGE_COUNT(pacstall) FF_APPEND_PACKAGE_COUNT(paludis) FF_APPEND_PACKAGE_COUNT(pkg) FF_APPEND_PACKAGE_COUNT(pkgtool) + FF_APPEND_PACKAGE_COUNT(qi) FF_APPEND_PACKAGE_COUNT(macports) FF_APPEND_PACKAGE_COUNT(rpm) FF_APPEND_PACKAGE_COUNT(scoop) FF_APPEND_PACKAGE_COUNT(snap) + FF_APPEND_PACKAGE_COUNT(sorcery) FF_APPEND_PACKAGE_COUNT(winget) FF_APPEND_PACKAGE_COUNT(xbps) - FF_APPEND_PACKAGE_COUNT(opkg) - FF_APPEND_PACKAGE_COUNT(am) - FF_APPEND_PACKAGE_COUNT(sorcery) - FF_APPEND_PACKAGE_COUNT(guixSystem) - FF_APPEND_PACKAGE_COUNT(guixUser) - FF_APPEND_PACKAGE_COUNT(guixHome) - FF_APPEND_PACKAGE_COUNT(linglong) - FF_APPEND_PACKAGE_COUNT(pacstall) - FF_APPEND_PACKAGE_COUNT(mport) yyjson_mut_obj_add_strbuf(doc, obj, "pacmanBranch", &counts.pacmanBranch); } void ffPrintPackagesHelpFormat(void) { - FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_PACKAGES_MODULE_NAME, "{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-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (MacPorts), {20} (scoop), {21} (choco), {22} (pkgtool), {23} (paludis), {24} (winget), {25} (opkg), {26} (am), {27} (sorcery), {28} (lpkg), {29} (lpkgbuild), {30} (guix-system), {31} (guix-user), {32} (guix-home), {33} (linglong)", FF_PACKAGES_NUM_FORMAT_ARGS, ((const char* []) { + FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_PACKAGES_MODULE_NAME, "{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-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (MacPorts), {20} (scoop), {21} (choco), {22} (pkgtool), {23} (paludis), {24} (winget), {25} (opkg), {26} (am), {27} (sorcery), {28} (lpkg), {29} (lpkgbuild), {30} (guix-system), {31} (guix-user), {32} (guix-home), {33} (linglong), {34} (pacstall), {35} (mport), {36} qi", FF_PACKAGES_NUM_FORMAT_ARGS, ((const char* []) { "Number of all packages - all", "Number of pacman packages - pacman", "Pacman branch on manjaro - pacman-branch", @@ -465,6 +475,7 @@ void ffPrintPackagesHelpFormat(void) "Number of linglong packages - linglong", "Number of pacstall packages - pacstall", "Number of mport packages - mport", + "Number of qi packages - qi", "Total number of all nix packages - nix-all", "Total number of all flatpak app packages - flatpak-all", "Total number of all brew packages - brew-all", From 830c71ddc40d4174148a3ae5da059b2fc693c51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 11 Nov 2024 00:28:39 +0800 Subject: [PATCH 30/61] DisplayServer (NetBSD): detect WM / DE by process name --- src/detection/displayserver/linux/wmde.c | 32 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index aa1f0eafd..7a8554caa 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -8,16 +8,19 @@ #include #include -#ifdef __FreeBSD__ +#if __FreeBSD__ #include #include #include -#elif defined(__OpenBSD__) +#elif __OpenBSD__ #include #include #include -#elif defined(__sun) +#elif __sun #include +#elif __NetBSD__ + #include + #include #endif static const char* parseEnv(void) @@ -388,6 +391,29 @@ static const char* getFromProcesses(FFDisplayServerResult* result) if(result->wmPrettyName.length == 0) applyNameIfWM(result, processName.chars); + if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0) + break; + } +#elif __NetBSD__ + int request[] = {CTL_KERN, KERN_PROC2, KERN_PROC_UID, (int) userId, sizeof(struct kinfo_proc2), INT_MAX}; + + size_t size = 0; + if(sysctl(request, ARRAY_SIZE(request), NULL, &size, NULL, 0) != 0) + return "sysctl(KERN_PROC_UID, NULL) failed"; + + FF_AUTO_FREE struct kinfo_proc2* procs = malloc(size); + + if(sysctl(request, ARRAY_SIZE(request), procs, &size, NULL, 0) != 0) + return "sysctl(KERN_PROC_UID, procs) failed"; + + for(struct kinfo_proc2* proc = procs; proc < procs + (size / sizeof(struct kinfo_proc2)); proc++) + { + if(result->dePrettyName.length == 0) + applyPrettyNameIfDE(result, proc->p_comm); + + if(result->wmPrettyName.length == 0) + applyNameIfWM(result, proc->p_comm); + if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0) break; } From c368908b7d027bbad8c825d3569cb7232387b1b3 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 11 Nov 2024 17:49:49 +0800 Subject: [PATCH 31/61] Shell (macOS): try fixing segfault in old macOS Ref: #1388 --- src/common/processing_linux.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index fb5db6260..c170cd56c 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -158,10 +158,8 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid }; if (sysctl(mibs, ARRAY_SIZE(mibs), NULL, &len, NULL, 0) == 0) {// try get arg0 - #ifndef MAC_OS_X_VERSION_10_15 //don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version. len++; - #endif FF_AUTO_FREE char* const procArgs2 = malloc(len); if (sysctl(mibs, ARRAY_SIZE(mibs), procArgs2, &len, NULL, 0) == 0) { From 7c8250c68c04f6ad8f67aa8fb21106fa5d2562c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 11 Nov 2024 18:02:23 +0800 Subject: [PATCH 32/61] StringUtil: rename `ffStrCopy` and correctly reflect its usage --- src/detection/cpucache/cpucache_apple.c | 14 +++++++------- src/detection/gpu/gpu_linux.c | 2 +- src/detection/localip/localip_linux.c | 4 ++-- src/detection/packages/packages_windows.c | 8 ++++---- src/detection/terminalfont/terminalfont_windows.c | 6 +++--- src/detection/wifi/wifi_linux.c | 2 +- src/util/stringUtils.h | 6 +++--- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/detection/cpucache/cpucache_apple.c b/src/detection/cpucache/cpucache_apple.c index 363733f8b..b0e315a14 100644 --- a/src/detection/cpucache/cpucache_apple.c +++ b/src/detection/cpucache/cpucache_apple.c @@ -20,35 +20,35 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result) { *pNum = (char) ('0' + i); - ffStrCopyN(pSubkey, "physicalcpu", lenLeft); + ffStrCopy(pSubkey, "physicalcpu", lenLeft); uint32_t ncpu = (uint32_t) ffSysctlGetInt(sysctlKey, 0); if (ncpu <= 0) continue; - ffStrCopyN(pSubkey, "l1icachesize", lenLeft); + ffStrCopy(pSubkey, "l1icachesize", lenLeft); uint32_t size = (uint32_t) ffSysctlGetInt(sysctlKey, 0); if (size) ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_INSTRUCTION)->num = ncpu; - ffStrCopyN(pSubkey, "l1dcachesize", lenLeft); + ffStrCopy(pSubkey, "l1dcachesize", lenLeft); size = (uint32_t) ffSysctlGetInt(sysctlKey, 0); if (size) ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_DATA)->num = ncpu; - ffStrCopyN(pSubkey, "l2cachesize", lenLeft); + ffStrCopy(pSubkey, "l2cachesize", lenLeft); size = (uint32_t) ffSysctlGetInt(sysctlKey, 0); if (size) { - ffStrCopyN(pSubkey, "cpusperl2", lenLeft); + ffStrCopy(pSubkey, "cpusperl2", lenLeft); uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0); if (cpuSper) ffCPUCacheAddItem(result, 2, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper; } - ffStrCopyN(pSubkey, "l3cachesize", lenLeft); + ffStrCopy(pSubkey, "l3cachesize", lenLeft); size = (uint32_t) ffSysctlGetInt(sysctlKey, 0); if (size) { - ffStrCopyN(pSubkey, "cpusperl3", lenLeft); + ffStrCopy(pSubkey, "cpusperl3", lenLeft); uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0); if (cpuSper) ffCPUCacheAddItem(result, 3, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper; diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index a915a25e9..bf9cc1add 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -460,7 +460,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf { if (ffStrStartsWith(entry->d_name, "card")) { - ffStrCopyN(drmKeyBuffer, entry->d_name, ARRAY_SIZE(drmKeyBuffer)); + ffStrCopy(drmKeyBuffer, entry->d_name, ARRAY_SIZE(drmKeyBuffer)); drmKey = drmKeyBuffer; break; } diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index 00e64b990..7a8552811 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -231,7 +231,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) FF_LIST_FOR_EACH(FFLocalIpResult, iface, *results) { struct ifreq ifr; - ffStrCopyN(ifr.ifr_name, iface->name.chars, IFNAMSIZ); + ffStrCopy(ifr.ifr_name, iface->name.chars, IFNAMSIZ); if (options->showType & FF_LOCALIP_TYPE_MTU_BIT) { @@ -248,7 +248,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android #elif __FreeBSD__ || __APPLE__ || __OpenBSD__ || __NetBSD__ struct ifmediareq ifmr = {}; - ffStrCopyN(ifmr.ifm_name, iface->name.chars, IFNAMSIZ); + ffStrCopy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ); if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0 && (IFM_TYPE(ifmr.ifm_active) & IFM_ETHER)) { switch (IFM_SUBTYPE(ifmr.ifm_active)) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index afa2b12e9..a9fa9df6d 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -58,8 +58,8 @@ static void detectChoco(FF_MAYBE_UNUSED FFPackagesResult* result) return; char chocoPath[MAX_PATH + 3]; - char* pend = ffStrCopyN(chocoPath, chocoInstall, ARRAY_SIZE(chocoPath)); - ffStrCopyN(pend, "/lib/*", ARRAY_SIZE(chocoPath) - (size_t) (pend - chocoPath)); + char* pend = ffStrCopy(chocoPath, chocoInstall, ARRAY_SIZE(chocoPath)); + ffStrCopy(pend, "/lib/*", ARRAY_SIZE(chocoPath) - (size_t) (pend - chocoPath)); result->choco = getNumElements(chocoPath, FILE_ATTRIBUTE_DIRECTORY, "choco"); } @@ -71,8 +71,8 @@ static void detectPacman(FFPackagesResult* result) // MSYS2 char pacmanPath[MAX_PATH + 3]; - char* pend = ffStrCopyN(pacmanPath, msystemPrefix, ARRAY_SIZE(pacmanPath)); - ffStrCopyN(pend, "/../var/lib/pacman/local/*", ARRAY_SIZE(pacmanPath) - (size_t) (pend - pacmanPath)); + char* pend = ffStrCopy(pacmanPath, msystemPrefix, ARRAY_SIZE(pacmanPath)); + ffStrCopy(pend, "/../var/lib/pacman/local/*", ARRAY_SIZE(pacmanPath) - (size_t) (pend - pacmanPath)); result->pacman = getNumElements(pacmanPath, FILE_ATTRIBUTE_DIRECTORY, NULL); } diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index 6e59cbdfb..3adcd8eaa 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -98,12 +98,12 @@ static void detectFromWindowsTerminal(const FFstrbuf* terminalExe, FFTerminalFon if(terminalExe && terminalExe->length > 0 && !ffStrbufEqualS(terminalExe, "Windows Terminal")) { char jsonPath[MAX_PATH + 1]; - char* pathEnd = ffStrCopyN(jsonPath, terminalExe->chars, ffStrbufLastIndexC(terminalExe, '\\') + 1); - ffStrCopyN(pathEnd, ".portable", ARRAY_SIZE(jsonPath) - (size_t) (pathEnd - jsonPath) - 1); + char* pathEnd = ffStrCopy(jsonPath, terminalExe->chars, ffStrbufLastIndexC(terminalExe, '\\') + 1); + ffStrCopy(pathEnd, ".portable", ARRAY_SIZE(jsonPath) - (size_t) (pathEnd - jsonPath) - 1); if(ffPathExists(jsonPath, FF_PATHTYPE_ANY)) { - ffStrCopyN(pathEnd, "settings\\settings.json", ARRAY_SIZE(jsonPath) - (size_t) (pathEnd - jsonPath) - 1); + ffStrCopy(pathEnd, "settings\\settings.json", ARRAY_SIZE(jsonPath) - (size_t) (pathEnd - jsonPath) - 1); if(!ffAppendFileBuffer(jsonPath, &json)) error = "Error reading Windows Terminal portable settings JSON file"; } diff --git a/src/detection/wifi/wifi_linux.c b/src/detection/wifi/wifi_linux.c index 732c5afc8..cd99a271a 100644 --- a/src/detection/wifi/wifi_linux.c +++ b/src/detection/wifi/wifi_linux.c @@ -190,7 +190,7 @@ static const char* detectWifiWithIoctls(FFWifiResult* item) return "socket() failed"; struct iwreq iwr; - ffStrCopyN(iwr.ifr_name, item->inf.description.chars, IFNAMSIZ); + ffStrCopy(iwr.ifr_name, item->inf.description.chars, IFNAMSIZ); ffStrbufEnsureFree(&item->conn.ssid, IW_ESSID_MAX_SIZE); iwr.u.essid.pointer = (caddr_t) item->conn.ssid.chars; iwr.u.essid.length = IW_ESSID_MAX_SIZE + 1; diff --git a/src/util/stringUtils.h b/src/util/stringUtils.h index 6c641517b..c22d1976e 100644 --- a/src/util/stringUtils.h +++ b/src/util/stringUtils.h @@ -80,12 +80,12 @@ static inline bool ffCharIsDigit(char c) return '0' <= c && c <= '9'; } -static inline char* ffStrCopyN(char* __restrict__ dst, const char* __restrict__ src, size_t nDst) +// Copies at most (dstBufSiz - 1) bytes from src to dst; dst is always null-terminated +static inline char* ffStrCopy(char* __restrict__ dst, const char* __restrict__ src, size_t dstBufSiz) { - assert(dst != NULL); if (__builtin_expect(dst == NULL, false)) return dst; - size_t len = strnlen(src, nDst - 1); + size_t len = strnlen(src, dstBufSiz - 1); memcpy(dst, src, len); dst[len] = '\0'; return dst + len; From 748b7df0d7c5a81a00f105571cc48b1aca4f98aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 12 Nov 2024 10:45:09 +0800 Subject: [PATCH 33/61] Smbios: clean up more garbage values Ref: #1391 --- src/util/smbiosHelper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/smbiosHelper.c b/src/util/smbiosHelper.c index 8ce226fa0..9366f8a9f 100644 --- a/src/util/smbiosHelper.c +++ b/src/util/smbiosHelper.c @@ -13,6 +13,7 @@ bool ffIsSmbiosValueSet(FFstrbuf* value) !ffStrbufStartsWithIgnCaseS(value, "OEM") && !ffStrbufStartsWithIgnCaseS(value, "O.E.M.") && !ffStrbufStartsWithIgnCaseS(value, "System Product") && + !ffStrbufStartsWithIgnCaseS(value, "Unknown Product") && !ffStrbufIgnCaseEqualS(value, "None") && !ffStrbufIgnCaseEqualS(value, "System Name") && !ffStrbufIgnCaseEqualS(value, "System Version") && @@ -29,6 +30,7 @@ bool ffIsSmbiosValueSet(FFstrbuf* value) !ffStrbufIgnCaseEqualS(value, "Chassis Version") && !ffStrbufIgnCaseEqualS(value, "All Series") && !ffStrbufIgnCaseEqualS(value, "N/A") && + !ffStrbufIgnCaseEqualS(value, "Unknown") && !ffStrbufIgnCaseEqualS(value, "0x0000") ; } From e618303343ce84499665d45d2460f3fec42dd21f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 12 Nov 2024 21:52:12 +0800 Subject: [PATCH 34/61] Media (macOS): try fixing error `CFStringGetCString() failed` --- src/util/apple/cf_helpers.c | 17 ++++++++++++----- tests/strbuf.c | 3 +++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/util/apple/cf_helpers.c b/src/util/apple/cf_helpers.c index a0bc534c7..a7705ec65 100644 --- a/src/util/apple/cf_helpers.c +++ b/src/util/apple/cf_helpers.c @@ -49,15 +49,22 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) if (CFGetTypeID(cf) == CFStringGetTypeID()) { CFStringRef cfStr = (CFStringRef)cf; - uint32_t length = (uint32_t)CFStringGetLength(cfStr); - //CFString stores UTF16 characters, therefore may require larger buffer to convert to UTF8 string - ffStrbufEnsureFree(result, length * 2); - if (!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8)) + + const char* cstr = CFStringGetCStringPtr(cfStr, kCFStringEncodingUTF8); + if (cstr) + { + ffStrbufSetS(result, cstr); + return NULL; + } + else { - ffStrbufEnsureFree(result, length * 4); + uint32_t length = CFStringGetLength(cfStr); + uint32_t maxLength = (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); + ffStrbufEnsureFixedLengthFree(result, maxLength); if(!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8)) return "CFStringGetCString() failed"; } + // CFStringGetCString ensures the buffer is NUL terminated // https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring result->length = (uint32_t) strnlen(result->chars, (uint32_t)result->allocated); diff --git a/tests/strbuf.c b/tests/strbuf.c index 7d016467e..92141d4b9 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -381,6 +381,9 @@ int main(void) ffStrbufEnsureFixedLengthFree(&strbuf, 10); VERIFY(strbuf.length == 0); VERIFY(strbuf.allocated == 11); + ffStrbufEnsureFixedLengthFree(&strbuf, 12); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.allocated == 13); ffStrbufDestroy(&strbuf); //ffStrbufEnsureFixedLengthFree / empty buffer with zero free length From 644458bc74681735714f37a9302098b839ad833e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 12 Nov 2024 22:34:28 +0800 Subject: [PATCH 35/61] CPU (macOS): try fixing CPU freq detection on Apple M4 Fix #1394 --- src/detection/cpu/cpu_apple.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 3c5f45940..388f93ccc 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -59,7 +59,12 @@ static const char* detectFrequency(FFCPUResult* cpu) pMax = pMax > pStart[i] ? pMax : pStart[i]; if (pMax > 0) - cpu->frequencyMax = pMax / 1000 / 1000; + { + if (pMax > 100000000) // Assume that pMax is in MHz, M1~M3 + cpu->frequencyMax = pMax / 1000 / 1000; + else // Assume that pMax is in kHz, M4 and later (#1394) + cpu->frequencyMax = pMax / 1000; + } return NULL; } From c70c37c50c5ed704a06d7edf9ba75eb8d278b00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 12 Nov 2024 22:47:24 +0800 Subject: [PATCH 36/61] GPU (macOS): apply the same logic as CPU just in case --- src/detection/cpu/cpu_apple.c | 2 +- src/detection/gpu/gpu_apple.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 388f93ccc..1d94b005e 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -60,7 +60,7 @@ static const char* detectFrequency(FFCPUResult* cpu) if (pMax > 0) { - if (pMax > 100000000) // Assume that pMax is in MHz, M1~M3 + if (pMax > 100000000) // Assume that pMax is in Hz, M1~M3 cpu->frequencyMax = pMax / 1000 / 1000; else // Assume that pMax is in kHz, M4 and later (#1394) cpu->frequencyMax = pMax / 1000; diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index 16f9f9c0c..cc35ef0ee 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -68,7 +68,13 @@ static const char* detectFrequency(FFGPUResult* gpu) pMax = pMax > pStart[i] ? pMax : pStart[i]; if (pMax > 0) - gpu->frequency = pMax / 1000 / 1000; + { + // While this is not necessary for now (seems), we add this logic just in case. See cpu_apple.c + if (pMax > 100000000) // Assume that pMax is in Hz + gpu->frequency = pMax / 1000 / 1000; + else // Assume that pMax is in kHz + gpu->frequency = pMax / 1000; + } return NULL; } From bccf241816a9a4eefc0627fc9b797b6d28573f0f Mon Sep 17 00:00:00 2001 From: Tibo <35193961+Tiuxi@users.noreply.github.com> Date: Tue, 12 Nov 2024 20:13:13 -0500 Subject: [PATCH 37/61] Scripts: Add python script to generate man page (#1392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ Add man generating script * ✨ Add arguments and description * 🐛 Add shebang * 📝 Add documentation & text for sections * 🐛 Fix italic text (italic is not supported for man pages) * 🗑️ Remove .1 generated file * ✏️ Fix type "abbreviation" gen-man.py:24 * 🐛 Fix invalid escape sequence * ✨ Add version finder * ✨ Example & config sections * 🗑️ Delete generated .1 file --------- Co-authored-by: tgallone --- scripts/gen-man.py | 273 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100755 scripts/gen-man.py diff --git a/scripts/gen-man.py b/scripts/gen-man.py new file mode 100755 index 000000000..f9a15aefa --- /dev/null +++ b/scripts/gen-man.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python3 +""" +Python script to generate a man page for the command `fastfetch`. +The man content will be printed to stdout so you will need to +pipe it to a file if you want to save it. +The command options will be generated using a JSON file. +For the format of the JSON file, see https://github.com/fastfetch-cli/fastfetch/blob/dev/src/data/help.json +""" + +from json import load +from datetime import date +from re import search + + +###### Text Decorations Tags ###### + +startUnderline = "\\fI" # start underline text tag +endUnderline = "\\fR" # end underline text tag + +startBold = "\\fB" # start bold text tag +endBold = "\\fR" # end bold text tag + + +###### Parameters ###### + +# path to the JSON option file +pathToHelpFile = "../src/data/help.json" +# man page section +manSection = 1 +# title (center header) +titlePage = "Fastfetch man page" +# date (center footer) +todayDate = date.today().strftime("%b %d %Y") # format : "Month (abbreviation) Day Year" +# file to fastfetch version (left footer) +pathToVersionFile = "../CMakeLists.txt" + + +###### Sections Text ###### + +# text displayed in the "NAME" section +nameSection = "\ +fastfetch - a neofetch-like tool for fetching system \ +information and displaying them in a pretty way" + +# text displayed in the "DESCRIPTION" section +descriptionSection = "\ +A maintained, feature-rich and performance \ +oriented, neofetch like system information tool." + +# text displayed at the beginning of the "OPTIONS" section +optionSection = "\ +Parsing is not case sensitive. E.g. \\fB--lib-PCI\\fR \ +is equal to \\fB--Lib-Pci\\fR. \ + \n\n\ +If a value is between square brakets, it is optional. \ +An optional boolean value defaults to true if not \ +specified. \ + \n\n\ +More detailed help messages for each options can be \ +printed with \\fB-h \\fR. \ + \n\n\ +All options can be made permanent with command \ +\\fBfastfetch --gen-config\\fR. \ +" + +# text displayed in the "CONFIGURATION" +configurationSection = f"\ +.SS Fetch Structure \n\ +The structure of a fetch describes the modules that should \ +be included in the output. It consists of a string of modules, \ +separated by a colon (:). To list all available modules, \ +use --list-modules \ +\n\n\ +.SS Config Files \n\ +Fastfetch uses JSONC based format for configuration. \ +Fastfetch doesn't generate config file automatically; \ +it should be generated manually by {startBold}--gen-config.{endBold} \ +The config file will be saved in \ +{startBold}~/.config/fastfetch/config.jsonc{endBold} by default. \ +\n\n\ +A JSONC config file is a JSON file that also supports comments \ +with (// and /* */). Those files must have the extension '.jsonc'. \ +\n\n\ +The specified configuration/preset files are searched in the following order: \ +\n\n\ +{startBold}1.{endBold} relative to the current working directory \ +\n\n\ +{startBold}2.{endBold} relative to ~/.local/share/fastfetch/presets/ \ +\n\n\ +{startBold}3.{endBold} relative to /usr/share/fastfetch/presets/ \ +\n\n\ +Fastfetch provides some default presets. List them with --list-presets. \ +" + +# text displayed in the "EXAMPLE" section +exampleSection = "\ +.SS Config files:\n\ +.nf \ +// ~/.config/fastfetch/config.jsonc \n\ +{\n\ + \"$schema\": \"https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json\",\n\ + \"modules\": [ \n\ + \"title\", \n\ + \"separator\", \n\ + \"module1\", \n\ + { \n\ + \"type\": \"module2\", \n\ + \"module2-option\": \"value\" \n\ + } \n\ + ]\n\ +} \n\ +.fi" + +# text displayed in the "BUGS" section +bugSection = "Please report bugs to : \ +https://github.com/fastfetch-cli/fastfetch/issues" + +# text displayed in the "WIKI" section +wikiSection = "Fastfetch github wiki : https://github.com/fastfetch-cli/fastfetch/wiki/Configuration" + + +###### Argument decoration ###### + +### optional arguments tags ### + +# if an optional argument is displayed as [?optArg] (with "optArg" underlined) +# this value should be f"[?{startUnderline}" +startOptionalArgument = f"[{startUnderline}?" +# if an optional argument is displayed as [?optArg] (with "optArg underlined") +# this value should be f"{endUnderline}]" +endOptionalArgument = f"{endUnderline}]" + +### mandatory arguments tags ### +startMandatoryArgument = f"{startUnderline}" +endMandatoryArgument = f"{endUnderline}" + +def generateManPage(): + + # importing the JSON file + try: + with open(pathToHelpFile, 'r') as jsonFile: + helpFileData = load(jsonFile) # json.load + jsonFile.close() + except IOError as error: + print("Error with file", pathToHelpFile, ":", error) + return + + + ######## Start printing the generated .1 file ######## + + + ###### header, footer & config ##### + + print(f".TH man {manSection}", end=" ") + print(f"\"{todayDate}\"", end=" ") + + # version number + try: + with open(pathToVersionFile, 'r') as versionFile: + + # research version number in file with regex + for line in versionFile: + researchVersion = search("^\s*VERSION (\d+\.\d+\.\d+)$", line) # re.search() + if (researchVersion != None): + versionNumber = "".join(line[researchVersion.start():researchVersion.end()].split(" ")) + versionNumber = versionNumber[:7] + " " + versionNumber[7:] + break + + versionFile.close() + except IOError as error: + print("Error with file", pathToHelpFile, ":", error) + return + + print(f"\"{versionNumber}\"", end=" ") + print(f"\"{titlePage}\"") + + + ###### Name ###### + + print(".SH NAME") + print(nameSection) + + + ##### Synopsis ###### + + print(".SH SYNOPSIS") + print(".B fastfetch") + print(f"[{startUnderline}OPTIONS{endUnderline}]") + + + ##### Description ##### + + print(".SH DESCRIPTION") + print(descriptionSection) + + + ###### Wiki ###### + + print(".SH WIKI") + print(wikiSection) + + + ###### Configuration ###### + + print(".SH CONFIGURATION") + print(configurationSection) + + + ###### Options ###### + + print(".SH OPTIONS") + print(optionSection) + print() + + # loop through every options sections + for key, value in helpFileData.items(): + + # print new subsection + print(f".SS {key}:") + + # loop through every option in a section + for option in value: + # list of existing keys for this option + keyList = option.keys() + + # start a new "option" entry + print(".TP") + print(startBold, end="") + + # short option (-opt) + if "short" in keyList: + print(f"\\-{ option['short'] }", end="") + # if also have a long option, print a comma + if "long" in keyList: + print(", ", end="") + + # long option (--option) + if "long" in keyList: + print(f"\\-\\-{ option['long'] }", end="") + + print(endBold, end=" ") + + # arguments + if "arg" in keyList: + # if argument is optional, print "[arg]" + if "optional" in option["arg"].keys() and option["arg"]["optional"]: + print(startOptionalArgument + option['arg']['type'] + endOptionalArgument, end="") + + # if argument is mandatory, print "arg" + else: + print(startMandatoryArgument + option['arg']['type'] + endMandatoryArgument, end="") + + # description + print(f"\n {option['desc']} \n") + + + ###### Examples ###### + + print(".SH EXAMPLES") + print(exampleSection) + + + ###### Bugs ###### + + print(".SH BUGS") + print(bugSection) + + + + + +if __name__ == "__main__": + generateManPage() \ No newline at end of file From 5a1be2535bab81a8bc6c8b73c2af63489d2b61ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Nov 2024 10:10:06 +0800 Subject: [PATCH 38/61] Scripts: make `gen-pciids.py` executable --- scripts/gen-pciids.py | 2 ++ 1 file changed, 2 insertions(+) mode change 100644 => 100755 scripts/gen-pciids.py diff --git a/scripts/gen-pciids.py b/scripts/gen-pciids.py old mode 100644 new mode 100755 index 80e7304fb..875b8511a --- a/scripts/gen-pciids.py +++ b/scripts/gen-pciids.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + from requests import get as http_get class PciDeviceModel: From fe57b285810f6298ff8126524c47123f72d1fe8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Nov 2024 10:09:36 +0800 Subject: [PATCH 39/61] Scripts: clean up `gen-man.py` --- scripts/gen-man.py | 214 ++++++++++++++++++++------------------------- 1 file changed, 97 insertions(+), 117 deletions(-) diff --git a/scripts/gen-man.py b/scripts/gen-man.py index f9a15aefa..77c32f461 100755 --- a/scripts/gen-man.py +++ b/scripts/gen-man.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 + """ Python script to generate a man page for the command `fastfetch`. -The man content will be printed to stdout so you will need to +The man content will be printed to stdout so you will need to pipe it to a file if you want to save it. The command options will be generated using a JSON file. For the format of the JSON file, see https://github.com/fastfetch-cli/fastfetch/blob/dev/src/data/help.json @@ -10,106 +11,105 @@ from json import load from datetime import date from re import search +from os import path ###### Text Decorations Tags ###### -startUnderline = "\\fI" # start underline text tag -endUnderline = "\\fR" # end underline text tag +startUnderline = r"\fI" # start underline text tag +endUnderline = r"\fR" # end underline text tag -startBold = "\\fB" # start bold text tag -endBold = "\\fR" # end bold text tag +startBold = r"\fB" # start bold text tag +endBold = r"\fR" # end bold text tag ###### Parameters ###### +# path to the current directory +pathToCurrentDir = path.dirname(__file__) # path to the JSON option file -pathToHelpFile = "../src/data/help.json" +pathToHelpFile = path.join(pathToCurrentDir, "../src/data/help.json") # man page section manSection = 1 # title (center header) -titlePage = "Fastfetch man page" +titlePage = "Fastfetch man page" # date (center footer) todayDate = date.today().strftime("%b %d %Y") # format : "Month (abbreviation) Day Year" # file to fastfetch version (left footer) -pathToVersionFile = "../CMakeLists.txt" +pathToVersionFile = path.join(pathToCurrentDir, "../CMakeLists.txt") ###### Sections Text ###### # text displayed in the "NAME" section -nameSection = "\ -fastfetch - a neofetch-like tool for fetching system \ -information and displaying them in a pretty way" - -# text displayed in the "DESCRIPTION" section -descriptionSection = "\ -A maintained, feature-rich and performance \ -oriented, neofetch like system information tool." +nameSection = r"fastfetch \- A maintained, feature\-rich and performance oriented, neofetch like system information tool" # text displayed at the beginning of the "OPTIONS" section -optionSection = "\ -Parsing is not case sensitive. E.g. \\fB--lib-PCI\\fR \ -is equal to \\fB--Lib-Pci\\fR. \ - \n\n\ -If a value is between square brakets, it is optional. \ -An optional boolean value defaults to true if not \ -specified. \ - \n\n\ -More detailed help messages for each options can be \ -printed with \\fB-h \\fR. \ - \n\n\ -All options can be made permanent with command \ -\\fBfastfetch --gen-config\\fR. \ -" +optionSection = r""" +Parsing is not case sensitive. E.g. \fB--logo-type\fR is +equal to \fB--LOGO-TYPE\fR. + +If a value is between square brakets, it is optional. +An optional boolean value defaults to true if not specified. + +More detailed help messages for each options can be printed +with \fB-h \fR. + +All options can be made permanent with command +\fBfastfetch --gen-config\fR. +""" # text displayed in the "CONFIGURATION" -configurationSection = f"\ -.SS Fetch Structure \n\ -The structure of a fetch describes the modules that should \ -be included in the output. It consists of a string of modules, \ -separated by a colon (:). To list all available modules, \ -use --list-modules \ -\n\n\ -.SS Config Files \n\ -Fastfetch uses JSONC based format for configuration. \ -Fastfetch doesn't generate config file automatically; \ -it should be generated manually by {startBold}--gen-config.{endBold} \ -The config file will be saved in \ -{startBold}~/.config/fastfetch/config.jsonc{endBold} by default. \ -\n\n\ -A JSONC config file is a JSON file that also supports comments \ -with (// and /* */). Those files must have the extension '.jsonc'. \ -\n\n\ -The specified configuration/preset files are searched in the following order: \ -\n\n\ -{startBold}1.{endBold} relative to the current working directory \ -\n\n\ -{startBold}2.{endBold} relative to ~/.local/share/fastfetch/presets/ \ -\n\n\ -{startBold}3.{endBold} relative to /usr/share/fastfetch/presets/ \ -\n\n\ -Fastfetch provides some default presets. List them with --list-presets. \ -" +configurationSection = f""" +.SS Fetch Structure + +The structure of a fetch describes the modules that should +be included in the output. It consists of a string of modules, +separated by a colon (:). To list all available modules, +use --list-modules. + + +.SS Config Files + +Fastfetch uses JSONC based format for configuration. +Fastfetch doesn't generate config file automatically; +it should be generated manually by {startBold}--gen-config{endBold}. +The config file will be saved in +{startBold}~/.config/fastfetch/config.jsonc{endBold} by default. + +A JSONC config file is a JSON file that also supports comments +with (// and /* */). Those files must have the extension '.jsonc'. + +The specified configuration/preset files are searched in the following order: + +{startBold}1.{endBold} relative to the current working directory + +{startBold}2.{endBold} relative to ~/.local/share/fastfetch/presets/ + +{startBold}3.{endBold} relative to /usr/share/fastfetch/presets/ + +Fastfetch provides some default presets. List them with --list-presets. +""" # text displayed in the "EXAMPLE" section -exampleSection = "\ -.SS Config files:\n\ -.nf \ -// ~/.config/fastfetch/config.jsonc \n\ -{\n\ - \"$schema\": \"https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json\",\n\ - \"modules\": [ \n\ - \"title\", \n\ - \"separator\", \n\ - \"module1\", \n\ - { \n\ - \"type\": \"module2\", \n\ - \"module2-option\": \"value\" \n\ - } \n\ - ]\n\ -} \n\ -.fi" +exampleSection = """ +.SS Config files: +.nf +// ~/.config/fastfetch/config.jsonc +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "modules": [ + "title", + "separator", + "module1", + { + "type": "module2", + "module2-option": "value" + } + ] +} +.fi +""" # text displayed in the "BUGS" section bugSection = "Please report bugs to : \ @@ -128,50 +128,37 @@ startOptionalArgument = f"[{startUnderline}?" # if an optional argument is displayed as [?optArg] (with "optArg underlined") # this value should be f"{endUnderline}]" -endOptionalArgument = f"{endUnderline}]" +endOptionalArgument = f"{endUnderline}]" ### mandatory arguments tags ### -startMandatoryArgument = f"{startUnderline}" +startMandatoryArgument = f"{startUnderline}" endMandatoryArgument = f"{endUnderline}" -def generateManPage(): +def main(): # importing the JSON file - try: - with open(pathToHelpFile, 'r') as jsonFile: - helpFileData = load(jsonFile) # json.load - jsonFile.close() - except IOError as error: - print("Error with file", pathToHelpFile, ":", error) - return - + with open(pathToHelpFile, 'r') as jsonFile: + helpFileData = load(jsonFile) # json.load + ######## Start printing the generated .1 file ######## ###### header, footer & config ##### - print(f".TH man {manSection}", end=" ") + print(f".TH FASTFETCH {manSection} ", end=" ") print(f"\"{todayDate}\"", end=" ") # version number - try: - with open(pathToVersionFile, 'r') as versionFile: - - # research version number in file with regex - for line in versionFile: - researchVersion = search("^\s*VERSION (\d+\.\d+\.\d+)$", line) # re.search() - if (researchVersion != None): - versionNumber = "".join(line[researchVersion.start():researchVersion.end()].split(" ")) - versionNumber = versionNumber[:7] + " " + versionNumber[7:] - break - - versionFile.close() - except IOError as error: - print("Error with file", pathToHelpFile, ":", error) - return - - print(f"\"{versionNumber}\"", end=" ") + with open(pathToVersionFile, 'r') as versionFile: + + # research version number in file with regex + for line in versionFile: + researchVersion = search(r"^\s*VERSION (\d+\.\d+\.\d+)$", line) + if (researchVersion): + print(f"\"{researchVersion.group(1)}\"", end=" ") + break + print(f"\"{titlePage}\"") @@ -185,13 +172,7 @@ def generateManPage(): print(".SH SYNOPSIS") print(".B fastfetch") - print(f"[{startUnderline}OPTIONS{endUnderline}]") - - - ##### Description ##### - - print(".SH DESCRIPTION") - print(descriptionSection) + print(f"[{startUnderline}OPTIONS{endUnderline}]")\ ###### Wiki ###### @@ -229,17 +210,17 @@ def generateManPage(): # short option (-opt) if "short" in keyList: - print(f"\\-{ option['short'] }", end="") + print(fr"\-{ option['short'] }", end="") # if also have a long option, print a comma if "long" in keyList: print(", ", end="") # long option (--option) if "long" in keyList: - print(f"\\-\\-{ option['long'] }", end="") + print(fr"\-\-{ option['long'] }", end="") print(endBold, end=" ") - + # arguments if "arg" in keyList: # if argument is optional, print "[arg]" @@ -249,10 +230,10 @@ def generateManPage(): # if argument is mandatory, print "arg" else: print(startMandatoryArgument + option['arg']['type'] + endMandatoryArgument, end="") - + # description print(f"\n {option['desc']} \n") - + ###### Examples ###### @@ -268,6 +249,5 @@ def generateManPage(): - if __name__ == "__main__": - generateManPage() \ No newline at end of file + main() From d7fa0417eddb291eddb79076613e7ac500729bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Nov 2024 10:24:57 +0800 Subject: [PATCH 40/61] CMake: use `gen-man.py` to generate man file --- CMakeLists.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da782da36..440929008 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,6 +256,7 @@ endfunction(fastfetch_load_text) find_package(Python) if(Python_FOUND) + message(STATUS "Minifying 'help.json'") execute_process(COMMAND ${Python_EXECUTABLE} -c "import json,sys;json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))" INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json" OUTPUT_VARIABLE DATATEXT_JSON_HELP) @@ -263,20 +264,31 @@ if(Python_FOUND) message(ERROR "DATATEXT_JSON_HELP is empty, which should not happen!") endif() else() - message(STATUS "Python3 is not found, 'help.json' will not be minified") + message(WARNING "Python3 is not found, 'help.json' will not be minified") file(READ "src/data/help.json" DATATEXT_JSON_HELP) endif() if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "fastfetch_pciids.c.inc") if(Python_FOUND) + message(STATUS "Generating 'fastfetch_pciids.c.inc'") execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-pciids.py" OUTPUT_FILE "fastfetch_pciids.c.inc") else() - message(STATUS "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated") + message(WARNING "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated") set(ENABLE_EMBEDDED_PCIIDS OFF) endif() endif() +if(Python_FOUND) + message(STATUS "Generating 'fastfetch.1'") + execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-man.py" + OUTPUT_FILE "fastfetch.1") +else() + message(WARNING "Python3 is not found, use basic 'fastfetch.1.in' instead") + string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC) + configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY) +endif() + fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP) fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE) fastfetch_load_text(src/data/help_footer.txt DATATEXT_HELP_FOOTER) @@ -289,9 +301,6 @@ if(APPLE) configure_file(src/util/apple/Info.plist.in Info.plist @ONLY) endif() -string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC) -configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY) - #################### # Ascii image data # #################### From 5efb87997bee250c0a4d5766b1c97b75d3213ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Nov 2024 10:32:08 +0800 Subject: [PATCH 41/61] Util (macOS): cleanup `cf_helpers.c` --- src/util/apple/cf_helpers.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/util/apple/cf_helpers.c b/src/util/apple/cf_helpers.c index a7705ec65..e63df9727 100644 --- a/src/util/apple/cf_helpers.c +++ b/src/util/apple/cf_helpers.c @@ -52,22 +52,17 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) const char* cstr = CFStringGetCStringPtr(cfStr, kCFStringEncodingUTF8); if (cstr) - { ffStrbufSetS(result, cstr); - return NULL; - } else { - uint32_t length = CFStringGetLength(cfStr); - uint32_t maxLength = (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); - ffStrbufEnsureFixedLengthFree(result, maxLength); + uint32_t length = (uint32_t) CFStringGetLength(cfStr); + ffStrbufEnsureFixedLengthFree(result, (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8)); if(!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8)) return "CFStringGetCString() failed"; + // CFStringGetCString ensures the buffer is NUL terminated + // https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring + result->length = (uint32_t) strnlen(result->chars, (uint32_t)result->allocated); } - - // CFStringGetCString ensures the buffer is NUL terminated - // https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring - result->length = (uint32_t) strnlen(result->chars, (uint32_t)result->allocated); } else if (CFGetTypeID(cf) == CFDataGetTypeID()) { From 2cfc8ec0db68420ae039ff1625698b6fb02ab21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Nov 2024 10:46:30 +0800 Subject: [PATCH 42/61] Processing (macOS): fix exe path detection --- src/common/processing_linux.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index c170cd56c..3b290bc3d 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -147,7 +147,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons if (length > 0) // doesn't contain trailing NUL { buf[length] = '\0'; - ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length + 1); // +1 for the NUL + ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length); ffStrbufAppendNS(exePath, (uint32_t)length, buf); } } @@ -193,11 +193,12 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons } else { - ffStrbufEnsureFixedLengthFree(exe, PATH_MAX); - int length = proc_pidpath(pid, exe->chars, exe->allocated); + char buf[PROC_PIDPATHINFO_MAXSIZE]; + int length = proc_pidpath(pid, buf, ARRAY_SIZE(buf)); if (length > 0) { - exe->length = (uint32_t) length; + ffStrbufEnsureFixedLengthFree(exe, (uint32_t) length); + ffStrbufAppendNS(exe, (uint32_t) length, buf); if (exePath) ffStrbufSet(exePath, exe); } @@ -273,7 +274,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons if (length > 0) // doesn't contain trailing NUL { buf[length] = '\0'; - ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length + 1); // +1 for the NUL + ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length); ffStrbufAppendNS(exePath, (uint32_t)length, buf); } } From 1d92bf864a90180191c619f39e238fb78d179700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Nov 2024 15:15:50 +0800 Subject: [PATCH 43/61] IO (macOS): fix logo fails to load from symlinked files Fix #1395 --- src/common/io/io.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/common/io/io.h b/src/common/io/io.h index 84b3ec988..910c64825 100644 --- a/src/common/io/io.h +++ b/src/common/io/io.h @@ -118,6 +118,19 @@ static inline bool ffPathExists(const char* path, FFPathType pathType) } else { + #if __APPLE__ // #1395 + struct stat fileStat; + if(stat(path, &fileStat) != 0) + return false; + + unsigned int mode = fileStat.st_mode & S_IFMT; + + if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR) + return true; + + if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR) + return true; + #else size_t len = strlen(path); assert(len < PATH_MAX); if (len == 0) return false; @@ -134,6 +147,7 @@ static inline bool ffPathExists(const char* path, FFPathType pathType) else ret = access(path, F_OK); return pathType == FF_PATHTYPE_DIRECTORY ? ret == 0 : ret == -1 && errno == ENOTDIR; + #endif } #endif From bad85a557a252a7eb83dbcf6ef6bb94f13ff604f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Nov 2024 15:53:14 +0800 Subject: [PATCH 44/61] Host (Android): detect marketing name of vivo smartphone --- src/detection/host/host_android.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/detection/host/host_android.c b/src/detection/host/host_android.c index b496029a8..7e6d9638b 100644 --- a/src/detection/host/host_android.c +++ b/src/detection/host/host_android.c @@ -9,11 +9,12 @@ const char* ffDetectHost(FFHostResult* host) ffSettingsGetAndroidProperty("ro.product.marketname", &host->name) || ffSettingsGetAndroidProperty("ro.vendor.product.display", &host->name) + || ffSettingsGetAndroidProperty("ro.vivo.market.name", &host->name) + || ffSettingsGetAndroidProperty("ro.product.oppo_model", &host->name) + || ffSettingsGetAndroidProperty("ro.oppo.market.name", &host->name) || ffSettingsGetAndroidProperty("ro.config.devicename", &host->name) || ffSettingsGetAndroidProperty("ro.config.marketing_name", &host->name) || ffSettingsGetAndroidProperty("ro.product.vendor.model", &host->name) - || ffSettingsGetAndroidProperty("ro.product.oppo_model", &host->name) - || ffSettingsGetAndroidProperty("ro.oppo.market.name", &host->name) || ffSettingsGetAndroidProperty("ro.product.brand", &host->name); if (ffSettingsGetAndroidProperty("ro.product.model", &host->version)) From e821a998736112db80e2d79b8aee435eea9ec8d8 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 13 Nov 2024 16:44:24 +0800 Subject: [PATCH 45/61] CPU (Linux): add more Apple SOC code names --- src/detection/cpu/cpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/detection/cpu/cpu.c b/src/detection/cpu/cpu.c index 774e747ae..a3b47416c 100644 --- a/src/detection/cpu/cpu.c +++ b/src/detection/cpu/cpu.c @@ -37,6 +37,8 @@ const char* ffCPUAppleCodeToName(uint32_t code) case 6031: case 6034: return "Apple M3 Max"; case 8132: return "Apple M4"; + case 6040: return "Apple M4 Pro"; + case 6041: return "Apple M4 Max"; default: return NULL; } } From 97e1b987dd91f9fb802d32fb5c711b46a10ff7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Nov 2024 10:04:57 +0800 Subject: [PATCH 46/61] Global: pack all enums and make flag enums unsigned --- src/common/format.h | 2 +- src/common/io/io.h | 3 ++- src/common/option.h | 3 ++- src/common/percent.c | 10 ++++---- src/common/percent.h | 23 +++++++++++++------ src/common/printing.h | 3 ++- src/common/settings.h | 2 +- src/detection/cpucache/cpucache.h | 2 +- src/detection/displayserver/displayserver.h | 4 ++-- .../displayserver/linux/wayland/wayland.h | 2 +- src/detection/gpu/gpu_driver_specific.h | 3 ++- src/detection/gtk_qt/qt.c | 2 +- src/detection/physicaldisk/physicaldisk.h | 5 +++- src/logo/image/image.h | 2 +- src/logo/logo.c | 2 +- src/logo/logo.h | 3 ++- src/modules/battery/battery.c | 2 +- src/modules/battery/option.h | 2 +- src/modules/bluetooth/bluetooth.c | 2 +- src/modules/bluetooth/option.h | 2 +- src/modules/brightness/brightness.c | 2 +- src/modules/brightness/option.h | 2 +- src/modules/btrfs/btrfs.c | 2 +- src/modules/btrfs/option.h | 2 +- src/modules/colors/option.h | 2 +- src/modules/cpuusage/cpuusage.c | 2 +- src/modules/cpuusage/option.h | 2 +- src/modules/disk/disk.c | 2 +- src/modules/disk/option.h | 7 +++--- src/modules/display/option.h | 5 ++-- src/modules/dns/dns.c | 3 +++ src/modules/dns/option.h | 3 ++- src/modules/gamepad/gamepad.c | 2 +- src/modules/gamepad/option.h | 2 +- src/modules/gpu/gpu.c | 2 +- src/modules/gpu/option.h | 6 ++--- src/modules/loadavg/loadavg.c | 2 +- src/modules/loadavg/option.h | 2 +- src/modules/localip/option.h | 4 +++- src/modules/memory/memory.c | 2 +- src/modules/memory/option.h | 2 +- src/modules/opengl/option.h | 2 +- src/modules/packages/option.h | 4 +++- src/modules/sound/option.h | 4 ++-- src/modules/sound/sound.c | 2 +- src/modules/swap/option.h | 2 +- src/modules/swap/swap.c | 2 +- src/modules/wifi/option.h | 2 +- src/modules/wifi/wifi.c | 2 +- src/modules/zpool/option.h | 2 +- src/modules/zpool/zpool.c | 2 +- src/options/display.h | 6 ++--- src/options/general.h | 2 +- src/options/logo.h | 4 ++-- 54 files changed, 100 insertions(+), 73 deletions(-) diff --git a/src/common/format.h b/src/common/format.h index 79e1c90f4..fa092b40a 100644 --- a/src/common/format.h +++ b/src/common/format.h @@ -2,7 +2,7 @@ #include "util/FFstrbuf.h" -typedef enum FFformatArgType +typedef enum __attribute__((__packed__)) FFformatArgType { FF_FORMAT_ARG_TYPE_NULL = 0, FF_FORMAT_ARG_TYPE_UINT, diff --git a/src/common/io/io.h b/src/common/io/io.h index 910c64825..4cee2e471 100644 --- a/src/common/io/io.h +++ b/src/common/io/io.h @@ -87,11 +87,12 @@ static inline bool ffReadFileBufferRelative(FFNativeFD dfd, const char* fileName } //Bit flags, combine with | -typedef enum FFPathType +typedef enum __attribute__((__packed__)) FFPathType { FF_PATHTYPE_FILE = 1 << 0, FF_PATHTYPE_DIRECTORY = 1 << 1, FF_PATHTYPE_ANY = FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY, + FF_PATHTYPE_FORCE_UNSIGNED = UINT8_MAX, } FFPathType; static inline bool ffPathExists(const char* path, FFPathType pathType) diff --git a/src/common/option.h b/src/common/option.h index 10576c0ff..b9f3fb311 100644 --- a/src/common/option.h +++ b/src/common/option.h @@ -45,12 +45,13 @@ static inline void ffOptionInitModuleBaseInfo( baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig; } -typedef enum FFModuleKeyType +typedef enum __attribute__((__packed__)) FFModuleKeyType { FF_MODULE_KEY_TYPE_NONE = 0, FF_MODULE_KEY_TYPE_STRING = 1 << 0, FF_MODULE_KEY_TYPE_ICON = 1 << 1, FF_MODULE_KEY_TYPE_BOTH = FF_MODULE_KEY_TYPE_STRING | FF_MODULE_KEY_TYPE_ICON, + FF_MODULE_KEY_TYPE_FORCE_UNSIGNED = UINT8_MAX, } FFModuleKeyType; typedef struct FFModuleArgs diff --git a/src/common/percent.c b/src/common/percent.c index 9cc6e9d45..0993346e8 100644 --- a/src/common/percent.c +++ b/src/common/percent.c @@ -14,7 +14,7 @@ static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module) ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars); } -void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module) +void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module) { uint8_t green = config.green, yellow = config.yellow; assert(green <= 100 && yellow <= 100); @@ -104,7 +104,7 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con } } -void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module) +void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module) { uint8_t green = config.green, yellow = config.yellow; assert(green <= 100 && yellow <= 100); @@ -156,7 +156,7 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig con ffStrbufAppendC(buffer, ')'); } -bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFColorRangeConfig* config) +bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config) { if (!ffStrStartsWithIgnCase(subkey, "percent-")) return false; @@ -190,7 +190,7 @@ bool ffPercentParseCommandOptions(const char* key, const char* subkey, const cha return false; } -bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeConfig* config) +bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageModuleConfig* config) { if (!ffStrEqualsIgnCase(key, "percent")) return false; @@ -228,7 +228,7 @@ bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeCo return true; } -void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFColorRangeConfig defaultConfig, FFColorRangeConfig config) +void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig defaultConfig, FFPercentageModuleConfig config) { if (config.green == defaultConfig.green && config.yellow == defaultConfig.yellow) return; diff --git a/src/common/percent.h b/src/common/percent.h index 33921f689..c7350ff1c 100644 --- a/src/common/percent.h +++ b/src/common/percent.h @@ -4,14 +4,23 @@ #include "common/parsing.h" #include "common/option.h" -enum FFPercentageTypeFlags +typedef enum __attribute__((__packed__)) FFPercentageTypeFlags { + FF_PERCENTAGE_TYPE_NONE = 0, FF_PERCENTAGE_TYPE_NUM_BIT = 1 << 0, FF_PERCENTAGE_TYPE_BAR_BIT = 1 << 1, FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT = 1 << 2, FF_PERCENTAGE_TYPE_NUM_COLOR_BIT = 1 << 3, FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT = FF_PERCENTAGE_TYPE_NUM_COLOR_BIT, -}; + FF_PERCENTAGE_TYPE_FORCE_UNSIGNED_ = UINT8_MAX, +} FFPercentageTypeFlags; +static_assert(sizeof(FFPercentageTypeFlags) == 1, ""); + +typedef struct FFPercentageModuleConfig +{ + uint8_t green; + uint8_t yellow; +} FFPercentageModuleConfig; // if (green <= yellow) // [0, green]: print green @@ -23,12 +32,12 @@ enum FFPercentageTypeFlags // [yellow, green): print yellow // [0, yellow): print red -void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module); -void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module); +void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module); +void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module); typedef struct yyjson_val yyjson_val; typedef struct yyjson_mut_doc yyjson_mut_doc; typedef struct yyjson_mut_val yyjson_mut_val; -bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFColorRangeConfig* config); -bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeConfig* config); -void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFColorRangeConfig defaultConfig, FFColorRangeConfig config); +bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config); +bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageModuleConfig* config); +void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig defaultConfig, FFPercentageModuleConfig config); diff --git a/src/common/printing.h b/src/common/printing.h index 2060337c5..94479dc03 100644 --- a/src/common/printing.h +++ b/src/common/printing.h @@ -3,12 +3,13 @@ #include "fastfetch.h" #include "common/format.h" -typedef enum FFPrintType { +typedef enum __attribute__((__packed__)) FFPrintType { FF_PRINT_TYPE_DEFAULT = 0, FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0, // key has been formatted outside FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1, FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH = 1 << 2, FF_PRINT_TYPE_NO_CUSTOM_OUTPUT_FORMAT = 1 << 3, // reserved + FF_PRINT_TYPE_FORCE_UNSIGNED = UINT8_MAX, } FFPrintType; void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType); diff --git a/src/common/settings.h b/src/common/settings.h index 0b87bb33e..cfe6d093e 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -2,7 +2,7 @@ #include "fastfetch.h" -typedef enum FFvarianttype +typedef enum __attribute__((__packed__)) FFvarianttype { FF_VARIANT_TYPE_STRING, FF_VARIANT_TYPE_BOOL, diff --git a/src/detection/cpucache/cpucache.h b/src/detection/cpucache/cpucache.h index fb8170c4a..f63964240 100644 --- a/src/detection/cpucache/cpucache.h +++ b/src/detection/cpucache/cpucache.h @@ -2,7 +2,7 @@ #include "fastfetch.h" -typedef enum FFCPUCacheType +typedef enum __attribute__((__packed__)) FFCPUCacheType { FF_CPU_CACHE_TYPE_UNIFIED = 0, FF_CPU_CACHE_TYPE_INSTRUCTION = 1, diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index d1d21839e..4de3bdd4d 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -42,13 +42,13 @@ #define FF_WM_PROTOCOL_X11 "X11" #define FF_WM_PROTOCOL_WAYLAND "Wayland" -typedef enum FFDisplayType { +typedef enum __attribute__((__packed__)) FFDisplayType { FF_DISPLAY_TYPE_UNKNOWN, FF_DISPLAY_TYPE_BUILTIN, FF_DISPLAY_TYPE_EXTERNAL, } FFDisplayType; -typedef enum FFDisplayHdrStatus +typedef enum __attribute__((__packed__)) FFDisplayHdrStatus { FF_DISPLAY_HDR_STATUS_UNKNOWN, FF_DISPLAY_HDR_STATUS_UNSUPPORTED, diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index 3c3b64a94..c19d88199 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -9,7 +9,7 @@ #include "../displayserver_linux.h" -typedef enum WaylandProtocolType +typedef enum __attribute__((__packed__)) WaylandProtocolType { FF_WAYLAND_PROTOCOL_TYPE_NONE, FF_WAYLAND_PROTOCOL_TYPE_GLOBAL, diff --git a/src/detection/gpu/gpu_driver_specific.h b/src/detection/gpu/gpu_driver_specific.h index 989ef6093..258dc68f1 100644 --- a/src/detection/gpu/gpu_driver_specific.h +++ b/src/detection/gpu/gpu_driver_specific.h @@ -2,11 +2,12 @@ #include "gpu.h" -typedef enum FFGpuDriverConditionType +typedef enum __attribute__((__packed__)) FFGpuDriverConditionType { FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID = 1 << 0, FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID = 1 << 1, FF_GPU_DRIVER_CONDITION_TYPE_LUID = 1 << 2, + FF_GPU_DRIVER_CONDITION_TYPE_FORCE_UNSIGNED = UINT8_MAX, } FFGpuDriverConditionType; typedef struct FFGpuDriverPciBusId diff --git a/src/detection/gtk_qt/qt.c b/src/detection/gtk_qt/qt.c index 02c578a16..cefdf86dc 100644 --- a/src/detection/gtk_qt/qt.c +++ b/src/detection/gtk_qt/qt.c @@ -18,7 +18,7 @@ static inline bool allValuesSet(const FFQtResult* result) result->wallpaper.length > 0; } -typedef enum PlasmaCategory +typedef enum __attribute__((__packed__)) PlasmaCategory { PLASMA_CATEGORY_GENERAL, PLASMA_CATEGORY_KDE, diff --git a/src/detection/physicaldisk/physicaldisk.h b/src/detection/physicaldisk/physicaldisk.h index 76863f783..fbed2f52c 100644 --- a/src/detection/physicaldisk/physicaldisk.h +++ b/src/detection/physicaldisk/physicaldisk.h @@ -2,7 +2,7 @@ #define FF_PHYSICALDISK_TEMP_UNSET (0/0.0) -typedef enum FFPhysicalDiskType +typedef enum __attribute__((__packed__)) FFPhysicalDiskType { FF_PHYSICALDISK_TYPE_NONE = 0, @@ -15,7 +15,10 @@ typedef enum FFPhysicalDiskType FF_PHYSICALDISK_TYPE_READWRITE = 1 << 4, FF_PHYSICALDISK_TYPE_READONLY = 1 << 5, + + FF_PHYSICALDISK_TYPE_FORCE_UNSIGNED = UINT8_MAX, } FFPhysicalDiskType; +static_assert(sizeof(FFPhysicalDiskType) == sizeof(uint8_t), ""); typedef struct FFPhysicalDiskResult { diff --git a/src/logo/image/image.h b/src/logo/image/image.h index 608286392..58a2f6289 100644 --- a/src/logo/image/image.h +++ b/src/logo/image/image.h @@ -4,7 +4,7 @@ #if defined(FF_HAVE_IMAGEMAGICK7) || defined(FF_HAVE_IMAGEMAGICK6) -typedef enum FFLogoImageResult +typedef enum __attribute__((__packed__)) FFLogoImageResult { FF_LOGO_IMAGE_RESULT_SUCCESS, //Logo printed FF_LOGO_IMAGE_RESULT_INIT_ERROR, //Failed to load library, try again with next IM version diff --git a/src/logo/logo.c b/src/logo/logo.c index 26da1eed7..09dfd8696 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -9,7 +9,7 @@ #include #include -typedef enum FFLogoSize +typedef enum __attribute__((__packed__)) FFLogoSize { FF_LOGO_SIZE_UNKNOWN, FF_LOGO_SIZE_NORMAL, diff --git a/src/logo/logo.h b/src/logo/logo.h index e9bea9788..92a1683a6 100644 --- a/src/logo/logo.h +++ b/src/logo/logo.h @@ -2,11 +2,12 @@ #include "fastfetch.h" -typedef enum FFLogoLineType +typedef enum __attribute__((__packed__)) FFLogoLineType { FF_LOGO_LINE_TYPE_NORMAL = 0, FF_LOGO_LINE_TYPE_SMALL_BIT = 1 << 0, // The names of small logo must end with `_small` or `-small` FF_LOGO_LINE_TYPE_ALTER_BIT = 1 << 1, + FF_LOGO_LINE_TYPE_FORCE_UNSIGNED = UINT8_MAX, } FFLogoLineType; typedef struct FFlogo diff --git a/src/modules/battery/battery.c b/src/modules/battery/battery.c index cc30b4262..fad309bb7 100644 --- a/src/modules/battery/battery.c +++ b/src/modules/battery/battery.c @@ -301,7 +301,7 @@ void ffInitBatteryOptions(FFBatteryOptions* options) ffOptionInitModuleArg(&options->moduleArgs, ""); options->temp = false; options->tempConfig = (FFColorRangeConfig) { 60, 80 }; - options->percent = (FFColorRangeConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20 }; #ifdef _WIN32 options->useSetupApi = false; diff --git a/src/modules/battery/option.h b/src/modules/battery/option.h index ecaa45ccc..8b04ef1b4 100644 --- a/src/modules/battery/option.h +++ b/src/modules/battery/option.h @@ -12,7 +12,7 @@ typedef struct FFBatteryOptions bool temp; FFColorRangeConfig tempConfig; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; #ifdef _WIN32 bool useSetupApi; diff --git a/src/modules/bluetooth/bluetooth.c b/src/modules/bluetooth/bluetooth.c index b00ff013c..0139289e1 100644 --- a/src/modules/bluetooth/bluetooth.c +++ b/src/modules/bluetooth/bluetooth.c @@ -202,7 +202,7 @@ void ffInitBluetoothOptions(FFBluetoothOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, ""); options->showDisconnected = false; - options->percent = (FFColorRangeConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20 }; } void ffDestroyBluetoothOptions(FFBluetoothOptions* options) diff --git a/src/modules/bluetooth/option.h b/src/modules/bluetooth/option.h index 7938e77f0..4de6fff72 100644 --- a/src/modules/bluetooth/option.h +++ b/src/modules/bluetooth/option.h @@ -11,5 +11,5 @@ typedef struct FFBluetoothOptions FFModuleArgs moduleArgs; bool showDisconnected; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFBluetoothOptions; diff --git a/src/modules/brightness/brightness.c b/src/modules/brightness/brightness.c index c5740bc57..7b06613c5 100644 --- a/src/modules/brightness/brightness.c +++ b/src/modules/brightness/brightness.c @@ -237,7 +237,7 @@ void ffInitBrightnessOptions(FFBrightnessOptions* options) ffOptionInitModuleArg(&options->moduleArgs, "󰯪"); options->ddcciSleep = 10; - options->percent = (FFColorRangeConfig) { 100, 100 }; + options->percent = (FFPercentageModuleConfig) { 100, 100 }; options->compact = false; } diff --git a/src/modules/brightness/option.h b/src/modules/brightness/option.h index e359cdc3e..70337f59e 100644 --- a/src/modules/brightness/option.h +++ b/src/modules/brightness/option.h @@ -11,6 +11,6 @@ typedef struct FFBrightnessOptions FFModuleArgs moduleArgs; uint32_t ddcciSleep; // ms - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; bool compact; } FFBrightnessOptions; diff --git a/src/modules/btrfs/btrfs.c b/src/modules/btrfs/btrfs.c index 77e7ba1ad..c874b69d4 100644 --- a/src/modules/btrfs/btrfs.c +++ b/src/modules/btrfs/btrfs.c @@ -245,7 +245,7 @@ void ffInitBtrfsOptions(FFBtrfsOptions* options) ffGenerateBtrfsJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󱑛"); - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; } void ffDestroyBtrfsOptions(FFBtrfsOptions* options) diff --git a/src/modules/btrfs/option.h b/src/modules/btrfs/option.h index 504b15768..2e4b069b4 100644 --- a/src/modules/btrfs/option.h +++ b/src/modules/btrfs/option.h @@ -10,5 +10,5 @@ typedef struct FFBtrfsOptions FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFBtrfsOptions; diff --git a/src/modules/colors/option.h b/src/modules/colors/option.h index 54a8e496d..1a948a9b1 100644 --- a/src/modules/colors/option.h +++ b/src/modules/colors/option.h @@ -4,7 +4,7 @@ #include "common/option.h" -typedef enum FFColorsSymbol +typedef enum __attribute__((__packed__)) FFColorsSymbol { FF_COLORS_SYMBOL_BLOCK, FF_COLORS_SYMBOL_BACKGROUND, diff --git a/src/modules/cpuusage/cpuusage.c b/src/modules/cpuusage/cpuusage.c index ab5e4b9d2..cf4a5a65c 100644 --- a/src/modules/cpuusage/cpuusage.c +++ b/src/modules/cpuusage/cpuusage.c @@ -214,7 +214,7 @@ void ffInitCPUUsageOptions(FFCPUUsageOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, "󰓅"); options->separate = false; - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; options->waitTime = 200; } diff --git a/src/modules/cpuusage/option.h b/src/modules/cpuusage/option.h index 844828b94..9f65f701d 100644 --- a/src/modules/cpuusage/option.h +++ b/src/modules/cpuusage/option.h @@ -11,6 +11,6 @@ typedef struct FFCPUUsageOptions FFModuleArgs moduleArgs; bool separate; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; uint32_t waitTime; // in ms } FFCPUUsageOptions; diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c index 5dddf1e90..2eb39f48f 100644 --- a/src/modules/disk/disk.c +++ b/src/modules/disk/disk.c @@ -473,7 +473,7 @@ void ffInitDiskOptions(FFDiskOptions* options) ffStrbufInit(&options->folders); options->showTypes = FF_DISK_VOLUME_TYPE_REGULAR_BIT | FF_DISK_VOLUME_TYPE_EXTERNAL_BIT | FF_DISK_VOLUME_TYPE_READONLY_BIT; options->calcType = FF_DISK_CALC_TYPE_FREE; - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; } void ffDestroyDiskOptions(FFDiskOptions* options) diff --git a/src/modules/disk/option.h b/src/modules/disk/option.h index 7c2abdcaa..eb2323f4c 100644 --- a/src/modules/disk/option.h +++ b/src/modules/disk/option.h @@ -5,7 +5,7 @@ #include "common/option.h" #include "common/percent.h" -typedef enum FFDiskVolumeType +typedef enum __attribute__((__packed__)) FFDiskVolumeType { FF_DISK_VOLUME_TYPE_NONE = 0, FF_DISK_VOLUME_TYPE_REGULAR_BIT = 1 << 0, @@ -14,9 +14,10 @@ typedef enum FFDiskVolumeType FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT = 1 << 3, FF_DISK_VOLUME_TYPE_UNKNOWN_BIT = 1 << 4, FF_DISK_VOLUME_TYPE_READONLY_BIT = 1 << 5, + FF_DISK_VOLUME_TYPE_FORCE_UNSIGNED = UINT8_MAX, } FFDiskVolumeType; -typedef enum FFDiskCalcType +typedef enum __attribute__((__packed__)) FFDiskCalcType { FF_DISK_CALC_TYPE_FREE, FF_DISK_CALC_TYPE_AVAILABLE, @@ -30,5 +31,5 @@ typedef struct FFDiskOptions FFstrbuf folders; FFDiskVolumeType showTypes; FFDiskCalcType calcType; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFDiskOptions; diff --git a/src/modules/display/option.h b/src/modules/display/option.h index d6238e1b1..7233b2dd3 100644 --- a/src/modules/display/option.h +++ b/src/modules/display/option.h @@ -4,15 +4,16 @@ #include "common/option.h" -typedef enum FFDisplayCompactType +typedef enum __attribute__((__packed__)) FFDisplayCompactType { FF_DISPLAY_COMPACT_TYPE_NONE = 0, FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT = 1 << 0, FF_DISPLAY_COMPACT_TYPE_SCALED_BIT = 1 << 1, FF_DISPLAY_COMPACT_TYPE_REFRESH_RATE_BIT = 1 << 2, + FF_DISPLAY_COMPACT_TYPE_UNSIGNED = UINT8_MAX, } FFDisplayCompactType; -typedef enum FFDisplayOrder +typedef enum __attribute__((__packed__)) FFDisplayOrder { FF_DISPLAY_ORDER_NONE, FF_DISPLAY_ORDER_ASC, diff --git a/src/modules/dns/dns.c b/src/modules/dns/dns.c index 63a744885..fe4654f23 100644 --- a/src/modules/dns/dns.c +++ b/src/modules/dns/dns.c @@ -122,6 +122,8 @@ void ffGenerateDNSJsonConfig(FFDNSOptions* options, yyjson_mut_doc* doc, yyjson_ if (defaultOptions.showType != options->showType) { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wswitch" // FF_DNS_TYPE_FORCE_UNSIGNED switch (options->showType) { case FF_DNS_TYPE_IPV4_BIT: @@ -134,6 +136,7 @@ void ffGenerateDNSJsonConfig(FFDNSOptions* options, yyjson_mut_doc* doc, yyjson_ yyjson_mut_obj_add_str(doc, module, "showType", "both"); break; } + #pragma GCC diagnostic pop } } diff --git a/src/modules/dns/option.h b/src/modules/dns/option.h index d261d7e06..18dbb147b 100644 --- a/src/modules/dns/option.h +++ b/src/modules/dns/option.h @@ -4,10 +4,11 @@ #include "common/option.h" -typedef enum FFDNSShowType { +typedef enum __attribute__((__packed__)) FFDNSShowType { FF_DNS_TYPE_IPV4_BIT = 1, FF_DNS_TYPE_IPV6_BIT = 2, FF_DNS_TYPE_BOTH = FF_DNS_TYPE_IPV4_BIT | FF_DNS_TYPE_IPV6_BIT, + FF_DNS_TYPE_FORCE_UNSIGNED = UINT8_MAX, } FFDNSShowType; typedef struct FFDNSOptions diff --git a/src/modules/gamepad/gamepad.c b/src/modules/gamepad/gamepad.c index b1b3457f0..f30aa1772 100644 --- a/src/modules/gamepad/gamepad.c +++ b/src/modules/gamepad/gamepad.c @@ -160,7 +160,7 @@ void ffInitGamepadOptions(FFGamepadOptions* options) ffGenerateGamepadJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󰺵"); - options->percent = (FFColorRangeConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20 }; } void ffDestroyGamepadOptions(FFGamepadOptions* options) diff --git a/src/modules/gamepad/option.h b/src/modules/gamepad/option.h index b4ecaf94d..d1b570bf8 100644 --- a/src/modules/gamepad/option.h +++ b/src/modules/gamepad/option.h @@ -9,5 +9,5 @@ typedef struct FFGamepadOptions FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFGamepadOptions; diff --git a/src/modules/gpu/gpu.c b/src/modules/gpu/gpu.c index 57a7b9a8a..890e06716 100644 --- a/src/modules/gpu/gpu.c +++ b/src/modules/gpu/gpu.c @@ -439,7 +439,7 @@ void ffInitGPUOptions(FFGPUOptions* options) options->temp = false; options->hideType = FF_GPU_TYPE_UNKNOWN; options->tempConfig = (FFColorRangeConfig) { 60, 80 }; - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; } void ffDestroyGPUOptions(FFGPUOptions* options) diff --git a/src/modules/gpu/option.h b/src/modules/gpu/option.h index 5f53d2f6f..98362940b 100644 --- a/src/modules/gpu/option.h +++ b/src/modules/gpu/option.h @@ -5,14 +5,14 @@ #include "common/option.h" #include "common/percent.h" -typedef enum FFGPUType +typedef enum __attribute__((__packed__)) FFGPUType { FF_GPU_TYPE_UNKNOWN, FF_GPU_TYPE_INTEGRATED, FF_GPU_TYPE_DISCRETE, } FFGPUType; -typedef enum FFGPUDetectionMethod +typedef enum __attribute__((__packed__)) FFGPUDetectionMethod { FF_GPU_DETECTION_METHOD_AUTO, FF_GPU_DETECTION_METHOD_PCI, @@ -32,5 +32,5 @@ typedef struct FFGPUOptions bool driverSpecific; bool forceMethod; FFColorRangeConfig tempConfig; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFGPUOptions; diff --git a/src/modules/loadavg/loadavg.c b/src/modules/loadavg/loadavg.c index d53b12ff4..4e712e93b 100644 --- a/src/modules/loadavg/loadavg.c +++ b/src/modules/loadavg/loadavg.c @@ -204,7 +204,7 @@ void ffInitLoadavgOptions(FFLoadavgOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, ""); - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; options->ndigits = 2; options->compact = true; } diff --git a/src/modules/loadavg/option.h b/src/modules/loadavg/option.h index 0bcce0037..aee5f435c 100644 --- a/src/modules/loadavg/option.h +++ b/src/modules/loadavg/option.h @@ -9,7 +9,7 @@ typedef struct FFLoadavgOptions FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; uint8_t ndigits; bool compact; } FFLoadavgOptions; diff --git a/src/modules/localip/option.h b/src/modules/localip/option.h index 511ec729d..c95b77d8b 100644 --- a/src/modules/localip/option.h +++ b/src/modules/localip/option.h @@ -4,7 +4,7 @@ #include "common/option.h" -typedef enum FFLocalIpType +typedef enum __attribute__((__packed__)) FFLocalIpType { FF_LOCALIP_TYPE_NONE, FF_LOCALIP_TYPE_LOOP_BIT = 1 << 0, @@ -19,7 +19,9 @@ typedef enum FFLocalIpType FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10, FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT = 1 << 11, FF_LOCALIP_TYPE_ALL_IPS_BIT = 1 << 12, + FF_LOCALIP_TYPE_FORCE_UNSIGNED = UINT16_MAX, } FFLocalIpType; +static_assert(sizeof(FFLocalIpType) == sizeof(uint16_t), ""); typedef struct FFLocalIpOptions { diff --git a/src/modules/memory/memory.c b/src/modules/memory/memory.c index 05f58a0e7..58b0aff7f 100644 --- a/src/modules/memory/memory.c +++ b/src/modules/memory/memory.c @@ -152,7 +152,7 @@ void ffInitMemoryOptions(FFMemoryOptions* options) ffGenerateMemoryJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, ""); - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; } void ffDestroyMemoryOptions(FFMemoryOptions* options) diff --git a/src/modules/memory/option.h b/src/modules/memory/option.h index 4936b252b..76fc9fd06 100644 --- a/src/modules/memory/option.h +++ b/src/modules/memory/option.h @@ -10,5 +10,5 @@ typedef struct FFMemoryOptions FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFMemoryOptions; diff --git a/src/modules/opengl/option.h b/src/modules/opengl/option.h index 8c9db6309..54fd466c9 100644 --- a/src/modules/opengl/option.h +++ b/src/modules/opengl/option.h @@ -4,7 +4,7 @@ #include "common/option.h" -typedef enum FFOpenGLLibrary +typedef enum __attribute__((__packed__)) FFOpenGLLibrary { FF_OPENGL_LIBRARY_AUTO, FF_OPENGL_LIBRARY_EGL, diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h index ddb7d0f13..cab933592 100644 --- a/src/modules/packages/option.h +++ b/src/modules/packages/option.h @@ -4,7 +4,7 @@ #include "common/option.h" -typedef enum FFPackagesFlags +typedef enum __attribute__((__packed__)) FFPackagesFlags { FF_PACKAGES_FLAG_NONE = 0, FF_PACKAGES_FLAG_APK_BIT = 1 << 0, @@ -35,7 +35,9 @@ typedef enum FFPackagesFlags FF_PACKAGES_FLAG_PACSTALL_BIT = 1 << 25, FF_PACKAGES_FLAG_MPORT_BIT = 1 << 26, FF_PACKAGES_FLAG_QI_BIT = 1 << 27, + FF_PACKAGES_FLAG_FORCE_UNSIGNED = UINT32_MAX, } FFPackagesFlags; +static_assert(sizeof(FFPackagesFlags) == sizeof(uint32_t), ""); typedef struct FFPackagesOptions { diff --git a/src/modules/sound/option.h b/src/modules/sound/option.h index ad659a557..7ec2c1614 100644 --- a/src/modules/sound/option.h +++ b/src/modules/sound/option.h @@ -5,7 +5,7 @@ #include "common/option.h" #include "common/percent.h" -typedef enum FFSoundType +typedef enum __attribute__((__packed__)) FFSoundType { FF_SOUND_TYPE_MAIN, FF_SOUND_TYPE_ACTIVE, @@ -18,5 +18,5 @@ typedef struct FFSoundOptions FFModuleArgs moduleArgs; FFSoundType soundType; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFSoundOptions; diff --git a/src/modules/sound/sound.c b/src/modules/sound/sound.c index 3d24b2be6..ad78fa320 100644 --- a/src/modules/sound/sound.c +++ b/src/modules/sound/sound.c @@ -253,7 +253,7 @@ void ffInitSoundOptions(FFSoundOptions* options) ffOptionInitModuleArg(&options->moduleArgs, ""); options->soundType = FF_SOUND_TYPE_MAIN; - options->percent = (FFColorRangeConfig) { 80, 90 }; + options->percent = (FFPercentageModuleConfig) { 80, 90 }; } void ffDestroySoundOptions(FFSoundOptions* options) diff --git a/src/modules/swap/option.h b/src/modules/swap/option.h index 1c96ce41f..d6e7965ad 100644 --- a/src/modules/swap/option.h +++ b/src/modules/swap/option.h @@ -10,5 +10,5 @@ typedef struct FFSwapOptions FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFSwapOptions; diff --git a/src/modules/swap/swap.c b/src/modules/swap/swap.c index 210351631..235e7b9f7 100644 --- a/src/modules/swap/swap.c +++ b/src/modules/swap/swap.c @@ -161,7 +161,7 @@ void ffInitSwapOptions(FFSwapOptions* options) ffGenerateSwapJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󰓡"); - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; } void ffDestroySwapOptions(FFSwapOptions* options) diff --git a/src/modules/wifi/option.h b/src/modules/wifi/option.h index 305a95a47..3628df69d 100644 --- a/src/modules/wifi/option.h +++ b/src/modules/wifi/option.h @@ -9,5 +9,5 @@ typedef struct FFWifiOptions FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFWifiOptions; diff --git a/src/modules/wifi/wifi.c b/src/modules/wifi/wifi.c index d000c7e6b..a65de1168 100644 --- a/src/modules/wifi/wifi.c +++ b/src/modules/wifi/wifi.c @@ -222,7 +222,7 @@ void ffInitWifiOptions(FFWifiOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, ""); - options->percent = (FFColorRangeConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20 }; } void ffDestroyWifiOptions(FFWifiOptions* options) diff --git a/src/modules/zpool/option.h b/src/modules/zpool/option.h index 3143cf91b..ac4f8ff3f 100644 --- a/src/modules/zpool/option.h +++ b/src/modules/zpool/option.h @@ -10,5 +10,5 @@ typedef struct FFZpoolOptions FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - FFColorRangeConfig percent; + FFPercentageModuleConfig percent; } FFZpoolOptions; diff --git a/src/modules/zpool/zpool.c b/src/modules/zpool/zpool.c index 719d411bf..41cec9a23 100644 --- a/src/modules/zpool/zpool.c +++ b/src/modules/zpool/zpool.c @@ -205,7 +205,7 @@ void ffInitZpoolOptions(FFZpoolOptions* options) ffGenerateZpoolJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󱑛"); - options->percent = (FFColorRangeConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80 }; } void ffDestroyZpoolOptions(FFZpoolOptions* options) diff --git a/src/options/display.h b/src/options/display.h index fe1f0ba5d..47aaed0d6 100644 --- a/src/options/display.h +++ b/src/options/display.h @@ -2,14 +2,14 @@ #include "util/FFstrbuf.h" -typedef enum FFSizeBinaryPrefixType +typedef enum __attribute__((__packed__)) FFSizeBinaryPrefixType { FF_SIZE_BINARY_PREFIX_TYPE_IEC, // 1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard) FF_SIZE_BINARY_PREFIX_TYPE_SI, // 1000 Bytes = 1 KB, 1000 KB = 1 MB, ... FF_SIZE_BINARY_PREFIX_TYPE_JEDEC, // 1024 Bytes = 1 kB, 1024 kB = 1 MB, ... } FFSizeBinaryPrefixType; -typedef enum FFTemperatureUnit +typedef enum __attribute__((__packed__)) FFTemperatureUnit { FF_TEMPERATURE_UNIT_CELSIUS, FF_TEMPERATURE_UNIT_FAHRENHEIT, @@ -46,7 +46,7 @@ typedef struct FFOptionsDisplay FFstrbuf barBorderLeft; FFstrbuf barBorderRight; uint8_t barWidth; - uint8_t percentType; + FFPercentageTypeFlags percentType; uint8_t percentNdigits; FFstrbuf percentColorGreen; FFstrbuf percentColorYellow; diff --git a/src/options/general.h b/src/options/general.h index f1f0f3ff8..8cb0d4884 100644 --- a/src/options/general.h +++ b/src/options/general.h @@ -2,7 +2,7 @@ #include "util/FFstrbuf.h" -typedef enum FFDsForceDrmType +typedef enum __attribute__((__packed__)) FFDsForceDrmType { FF_DS_FORCE_DRM_TYPE_FALSE = 0, // Disable FF_DS_FORCE_DRM_TYPE_TRUE = 1, // Try `libdrm`, then `sysfs` if libdrm failed diff --git a/src/options/logo.h b/src/options/logo.h index ab22843b9..a4a031d5f 100644 --- a/src/options/logo.h +++ b/src/options/logo.h @@ -5,7 +5,7 @@ #define FASTFETCH_LOGO_MAX_NAMES 9 #define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) -typedef enum FFLogoType +typedef enum __attribute__((__packed__)) FFLogoType { FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo FF_LOGO_TYPE_BUILTIN, //builtin ascii art @@ -23,7 +23,7 @@ typedef enum FFLogoType FF_LOGO_TYPE_NONE, //--logo none } FFLogoType; -typedef enum FFLogoPosition +typedef enum __attribute__((__packed__)) FFLogoPosition { FF_LOGO_POSITION_LEFT, FF_LOGO_POSITION_TOP, From c9e3f8d95cb13b4533119ccdf9998b08b7a51a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Nov 2024 13:52:02 +0800 Subject: [PATCH 47/61] Global: support percent type config in module level --- src/common/percent.c | 28 +++++++++++++++++++++++----- src/common/percent.h | 1 + src/modules/battery/battery.c | 10 ++++++---- src/modules/bluetooth/bluetooth.c | 17 ++++++++++++++--- src/modules/brightness/brightness.c | 12 +++++++----- src/modules/btrfs/btrfs.c | 2 +- src/modules/cpuusage/cpuusage.c | 8 +++++--- src/modules/disk/disk.c | 11 ++++++----- src/modules/gamepad/gamepad.c | 17 ++++++++++++++--- src/modules/gpu/gpu.c | 2 +- src/modules/loadavg/loadavg.c | 9 +++++---- src/modules/memory/memory.c | 9 +++++---- src/modules/sound/sound.c | 11 ++++++----- src/modules/swap/swap.c | 14 ++++++++------ src/modules/wifi/wifi.c | 10 ++++++---- src/modules/zpool/zpool.c | 2 +- 16 files changed, 109 insertions(+), 54 deletions(-) diff --git a/src/common/percent.c b/src/common/percent.c index 0993346e8..98401121b 100644 --- a/src/common/percent.c +++ b/src/common/percent.c @@ -41,15 +41,18 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConf } else { - const char* colorGreen = instance.config.display.percentColorGreen.chars; - const char* colorYellow = instance.config.display.percentColorYellow.chars; - const char* colorRed = instance.config.display.percentColorRed.chars; + const char* colorGreen = options->percentColorGreen.chars; + const char* colorYellow = options->percentColorYellow.chars; + const char* colorRed = options->percentColorRed.chars; + + FFPercentageTypeFlags percentType = config.type == 0 ? options->percentType : config.type; + bool monochrome = !!(percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT); for (uint32_t i = 0; i < blocksPercent; ++i) { if(!options->pipe) { - if (options->percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT) + if (monochrome) { const char* color = NULL; if (green <= yellow) @@ -110,8 +113,9 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConf assert(green <= 100 && yellow <= 100); const FFOptionsDisplay* options = &instance.config.display; + FFPercentageTypeFlags percentType = config.type == 0 ? options->percentType : config.type; - bool colored = !!(options->percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT); + bool colored = !!(percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT); if (parentheses) ffStrbufAppendC(buffer, '('); @@ -187,6 +191,12 @@ bool ffPercentParseCommandOptions(const char* key, const char* subkey, const cha return true; } + if (ffStrEqualsIgnCase(subkey, "type")) + { + config->type = (FFPercentageTypeFlags) ffOptionParseUInt32(key, value); + return true; + } + return false; } @@ -225,6 +235,12 @@ bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageMo config->yellow = (uint8_t) num; } + yyjson_val* typeVal = yyjson_obj_get(value, "type"); + if (typeVal) + { + config->type = (FFPercentageTypeFlags) yyjson_get_int(typeVal); + } + return true; } @@ -238,4 +254,6 @@ void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FF yyjson_mut_obj_add_uint(doc, percent, "green", config.green); if (config.yellow != defaultConfig.yellow) yyjson_mut_obj_add_uint(doc, percent, "yellow", config.yellow); + if (config.type != defaultConfig.type) + yyjson_mut_obj_add_uint(doc, percent, "type", config.type); } diff --git a/src/common/percent.h b/src/common/percent.h index c7350ff1c..f06ad1a3e 100644 --- a/src/common/percent.h +++ b/src/common/percent.h @@ -20,6 +20,7 @@ typedef struct FFPercentageModuleConfig { uint8_t green; uint8_t yellow; + FFPercentageTypeFlags type; } FFPercentageModuleConfig; // if (green <= yellow) diff --git a/src/modules/battery/battery.c b/src/modules/battery/battery.c index fad309bb7..013b9a695 100644 --- a/src/modules/battery/battery.c +++ b/src/modules/battery/battery.c @@ -39,24 +39,26 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin timeRemaining /= 24; uint32_t days = timeRemaining; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; + if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); bool showStatus = - !(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT) && + !(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT) && result->status.length > 0 && ffStrbufIgnCaseCompS(&result->status, "Unknown") != 0; if(result->capacity >= 0) { - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { ffPercentAppendBar(&str, result->capacity, options->percent, &options->moduleArgs); } - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) { if(str.length > 0) ffStrbufAppendC(&str, ' '); @@ -301,7 +303,7 @@ void ffInitBatteryOptions(FFBatteryOptions* options) ffOptionInitModuleArg(&options->moduleArgs, ""); options->temp = false; options->tempConfig = (FFColorRangeConfig) { 60, 80 }; - options->percent = (FFPercentageModuleConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20, 0 }; #ifdef _WIN32 options->useSetupApi = false; diff --git a/src/modules/bluetooth/bluetooth.c b/src/modules/bluetooth/bluetooth.c index 0139289e1..bd07ab0d3 100644 --- a/src/modules/bluetooth/bluetooth.c +++ b/src/modules/bluetooth/bluetooth.c @@ -13,9 +13,20 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* de { ffPrintLogoAndKey(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); - FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateCopy(&device->name); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + bool showBatteryLevel = device->battery > 0 && device->battery <= 100; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; - if (device->battery > 0 && device->battery <= 100) + if (showBatteryLevel && (percentType & FF_PERCENTAGE_TYPE_BAR_BIT)) + { + ffPercentAppendBar(&buffer, device->battery, options->percent, &options->moduleArgs); + ffStrbufAppendC(&buffer, ' '); + } + + if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppend(&buffer, &device->name); + + if (showBatteryLevel && (percentType & FF_PERCENTAGE_TYPE_NUM_BIT)) { if (buffer.length) ffStrbufAppendC(&buffer, ' '); @@ -202,7 +213,7 @@ void ffInitBluetoothOptions(FFBluetoothOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, ""); options->showDisconnected = false; - options->percent = (FFPercentageModuleConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20, 0 }; } void ffDestroyBluetoothOptions(FFBluetoothOptions* options) diff --git a/src/modules/brightness/brightness.c b/src/modules/brightness/brightness.c index 7b06613c5..bc06b68ba 100644 --- a/src/modules/brightness/brightness.c +++ b/src/modules/brightness/brightness.c @@ -25,6 +25,8 @@ void ffPrintBrightness(FFBrightnessOptions* options) return; } + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; + if (options->compact) { FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); @@ -48,7 +50,7 @@ void ffPrintBrightness(FFBrightnessOptions* options) uint32_t index = 0; FF_LIST_FOR_EACH(FFBrightnessResult, item, result) { - if(options->moduleArgs.key.length == 0) + if (options->moduleArgs.key.length == 0) { ffStrbufAppendF(&key, "%s (%s)", FF_BRIGHTNESS_MODULE_NAME, item->name.chars); } @@ -64,17 +66,17 @@ void ffPrintBrightness(FFBrightnessOptions* options) const double percent = (item->current - item->min) / (item->max - item->min) * 100; - if(options->moduleArgs.outputFormat.length == 0) + if (options->moduleArgs.outputFormat.length == 0) { FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); - if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { ffPercentAppendBar(&str, percent, options->percent, &options->moduleArgs); } - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) { if(str.length > 0) ffStrbufAppendC(&str, ' '); @@ -237,7 +239,7 @@ void ffInitBrightnessOptions(FFBrightnessOptions* options) ffOptionInitModuleArg(&options->moduleArgs, "󰯪"); options->ddcciSleep = 10; - options->percent = (FFPercentageModuleConfig) { 100, 100 }; + options->percent = (FFPercentageModuleConfig) { 100, 100, 0 }; options->compact = false; } diff --git a/src/modules/btrfs/btrfs.c b/src/modules/btrfs/btrfs.c index c874b69d4..7054e8139 100644 --- a/src/modules/btrfs/btrfs.c +++ b/src/modules/btrfs/btrfs.c @@ -245,7 +245,7 @@ void ffInitBtrfsOptions(FFBtrfsOptions* options) ffGenerateBtrfsJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󱑛"); - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; } void ffDestroyBtrfsOptions(FFBtrfsOptions* options) diff --git a/src/modules/cpuusage/cpuusage.c b/src/modules/cpuusage/cpuusage.c index cf4a5a65c..1fc7490c6 100644 --- a/src/modules/cpuusage/cpuusage.c +++ b/src/modules/cpuusage/cpuusage.c @@ -44,6 +44,8 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options) } double avgValue = sumValue / (double) valueCount; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; + if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); @@ -51,9 +53,9 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options) FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); if (!options->separate) { - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) ffPercentAppendBar(&str, avgValue, options->percent, &options->moduleArgs); - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) { if(str.length > 0) ffStrbufAppendC(&str, ' '); @@ -214,7 +216,7 @@ void ffInitCPUUsageOptions(FFCPUUsageOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, "󰓅"); options->separate = false; - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; options->waitTime = 200; } diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c index 2eb39f48f..b47c2bb0a 100644 --- a/src/modules/disk/disk.c +++ b/src/modules/disk/disk.c @@ -51,6 +51,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index ffParseSize(disk->bytesTotal, &totalPretty); double bytesPercentage = disk->bytesTotal > 0 ? (double) disk->bytesUsed / (double) disk->bytesTotal * 100.0 : 0; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { @@ -60,16 +61,16 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index if(disk->bytesTotal > 0) { - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { ffPercentAppendBar(&str, bytesPercentage, options->percent, &options->moduleArgs); ffStrbufAppendC(&str, ' '); } - if(!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if(!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) { ffPercentAppendNum(&str, bytesPercentage, options->percent, str.length > 0, &options->moduleArgs); ffStrbufAppendC(&str, ' '); @@ -78,7 +79,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index else ffStrbufAppendS(&str, "Unknown "); - if(!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if(!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) { if(disk->filesystem.length) ffStrbufAppendF(&str, "- %s ", disk->filesystem.chars); @@ -473,7 +474,7 @@ void ffInitDiskOptions(FFDiskOptions* options) ffStrbufInit(&options->folders); options->showTypes = FF_DISK_VOLUME_TYPE_REGULAR_BIT | FF_DISK_VOLUME_TYPE_EXTERNAL_BIT | FF_DISK_VOLUME_TYPE_READONLY_BIT; options->calcType = FF_DISK_CALC_TYPE_FREE; - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; } void ffDestroyDiskOptions(FFDiskOptions* options) diff --git a/src/modules/gamepad/gamepad.c b/src/modules/gamepad/gamepad.c index f30aa1772..154b71a6e 100644 --- a/src/modules/gamepad/gamepad.c +++ b/src/modules/gamepad/gamepad.c @@ -13,9 +13,20 @@ static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device { ffPrintLogoAndKey(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); - FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateCopy(&device->name); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + bool showBatteryLevel = device->battery > 0 && device->battery <= 100; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; - if (device->battery > 0 && device->battery <= 100) + if (showBatteryLevel && (percentType & FF_PERCENTAGE_TYPE_BAR_BIT)) + { + ffPercentAppendBar(&buffer, device->battery, options->percent, &options->moduleArgs); + ffStrbufAppendC(&buffer, ' '); + } + + if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppend(&buffer, &device->name); + + if (showBatteryLevel && (percentType & FF_PERCENTAGE_TYPE_NUM_BIT)) { if (buffer.length) ffStrbufAppendC(&buffer, ' '); @@ -160,7 +171,7 @@ void ffInitGamepadOptions(FFGamepadOptions* options) ffGenerateGamepadJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󰺵"); - options->percent = (FFPercentageModuleConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20, 0 }; } void ffDestroyGamepadOptions(FFGamepadOptions* options) diff --git a/src/modules/gpu/gpu.c b/src/modules/gpu/gpu.c index 890e06716..3489fc57e 100644 --- a/src/modules/gpu/gpu.c +++ b/src/modules/gpu/gpu.c @@ -439,7 +439,7 @@ void ffInitGPUOptions(FFGPUOptions* options) options->temp = false; options->hideType = FF_GPU_TYPE_UNKNOWN; options->tempConfig = (FFColorRangeConfig) { 60, 80 }; - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; } void ffDestroyGPUOptions(FFGPUOptions* options) diff --git a/src/modules/loadavg/loadavg.c b/src/modules/loadavg/loadavg.c index 4e712e93b..27e74a98e 100644 --- a/src/modules/loadavg/loadavg.c +++ b/src/modules/loadavg/loadavg.c @@ -59,18 +59,19 @@ void ffPrintLoadavg(FFLoadavgOptions* options) ffStrbufClear(&buffer); double percent = result[index] * 100 / cpu.coresOnline; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; - if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) ffPercentAppendBar(&buffer, percent, options->percent, &options->moduleArgs); - if (!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) { if (buffer.length > 0) ffStrbufAppendC(&buffer, ' '); ffStrbufAppendF(&buffer, "%.*f", options->ndigits, result[index]); } - if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) { if (buffer.length > 0) ffStrbufAppendC(&buffer, ' '); @@ -204,7 +205,7 @@ void ffInitLoadavgOptions(FFLoadavgOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, ""); - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; options->ndigits = 2; options->compact = true; } diff --git a/src/modules/memory/memory.c b/src/modules/memory/memory.c index 58b0aff7f..d364225c1 100644 --- a/src/modules/memory/memory.c +++ b/src/modules/memory/memory.c @@ -37,17 +37,18 @@ void ffPrintMemory(FFMemoryOptions* options) else { FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { ffPercentAppendBar(&str, percentage, options->percent, &options->moduleArgs); ffStrbufAppendC(&str, ' '); } - if(!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if(!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) ffPercentAppendNum(&str, percentage, options->percent, str.length > 0, &options->moduleArgs); ffStrbufTrimRight(&str, ' '); @@ -152,7 +153,7 @@ void ffInitMemoryOptions(FFMemoryOptions* options) ffGenerateMemoryJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, ""); - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; } void ffDestroyMemoryOptions(FFMemoryOptions* options) diff --git a/src/modules/sound/sound.c b/src/modules/sound/sound.c index ad78fa320..dafc37619 100644 --- a/src/modules/sound/sound.c +++ b/src/modules/sound/sound.c @@ -12,14 +12,15 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_SOUND_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); - if (!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) ffStrbufAppend(&str, &device->name); if(device->volume != FF_SOUND_VOLUME_UNKNOWN) { - if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { if (str.length) ffStrbufAppendC(&str, ' '); @@ -27,7 +28,7 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui ffPercentAppendBar(&str, device->volume, options->percent, &options->moduleArgs); } - if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) { if (str.length) ffStrbufAppendC(&str, ' '); @@ -36,7 +37,7 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui } } - if (!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) { if (device->main && index > 0) ffStrbufAppendS(&str, " (*)"); @@ -253,7 +254,7 @@ void ffInitSoundOptions(FFSoundOptions* options) ffOptionInitModuleArg(&options->moduleArgs, ""); options->soundType = FF_SOUND_TYPE_MAIN; - options->percent = (FFPercentageModuleConfig) { 80, 90 }; + options->percent = (FFPercentageModuleConfig) { 80, 90, 0 }; } void ffDestroySoundOptions(FFSoundOptions* options) diff --git a/src/modules/swap/swap.c b/src/modules/swap/swap.c index 235e7b9f7..c71831571 100644 --- a/src/modules/swap/swap.c +++ b/src/modules/swap/swap.c @@ -33,30 +33,32 @@ void ffPrintSwap(FFSwapOptions* options) { ffPrintLogoAndKey(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; + if (storage.bytesTotal == 0) { - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { ffPercentAppendBar(&str, 0, options->percent, &options->moduleArgs); ffStrbufAppendC(&str, ' '); } - if(!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if(!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) ffStrbufAppendS(&str, "Disabled"); else ffPercentAppendNum(&str, 0, options->percent, str.length > 0, &options->moduleArgs); } else { - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { ffPercentAppendBar(&str, percentage, options->percent, &options->moduleArgs); ffStrbufAppendC(&str, ' '); } - if(!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if(!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) ffPercentAppendNum(&str, percentage, options->percent, str.length > 0, &options->moduleArgs); } @@ -161,7 +163,7 @@ void ffInitSwapOptions(FFSwapOptions* options) ffGenerateSwapJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󰓡"); - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; } void ffDestroySwapOptions(FFSwapOptions* options) diff --git a/src/modules/wifi/wifi.c b/src/modules/wifi/wifi.c index a65de1168..be6b63649 100644 --- a/src/modules/wifi/wifi.c +++ b/src/modules/wifi/wifi.c @@ -22,6 +22,8 @@ void ffPrintWifi(FFWifiOptions* options) return; } + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; + for(uint32_t index = 0; index < result.length; ++index) { FFWifiResult* item = FF_LIST_GET(FFWifiResult, result, index); @@ -36,14 +38,14 @@ void ffPrintWifi(FFWifiOptions* options) { if(item->conn.signalQuality == item->conn.signalQuality) { - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { ffPercentAppendBar(&buffer, item->conn.signalQuality, options->percent, &options->moduleArgs); ffStrbufAppendC(&buffer, ' '); } } - if (!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) { ffStrbufAppend(&buffer, &item->conn.ssid); @@ -62,7 +64,7 @@ void ffPrintWifi(FFWifiOptions* options) if(item->conn.signalQuality == item->conn.signalQuality) { - if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) ffPercentAppendNum(&buffer, item->conn.signalQuality, options->percent, buffer.length > 0, &options->moduleArgs); } @@ -222,7 +224,7 @@ void ffInitWifiOptions(FFWifiOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, ""); - options->percent = (FFPercentageModuleConfig) { 50, 20 }; + options->percent = (FFPercentageModuleConfig) { 50, 20, 0 }; } void ffDestroyWifiOptions(FFWifiOptions* options) diff --git a/src/modules/zpool/zpool.c b/src/modules/zpool/zpool.c index 41cec9a23..a8e56146f 100644 --- a/src/modules/zpool/zpool.c +++ b/src/modules/zpool/zpool.c @@ -205,7 +205,7 @@ void ffInitZpoolOptions(FFZpoolOptions* options) ffGenerateZpoolJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs, "󱑛"); - options->percent = (FFPercentageModuleConfig) { 50, 80 }; + options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; } void ffDestroyZpoolOptions(FFZpoolOptions* options) From 1c41c6ccb1fa049c236ccca19ba3e394ca7e3b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Nov 2024 14:21:55 +0800 Subject: [PATCH 48/61] Percent: allow use enum to set type value in JSON config --- src/common/percent.c | 46 ++++++++++++++++++++++++++++++++++++++++++- src/common/percent.h | 1 + src/options/display.c | 7 ++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/common/percent.c b/src/common/percent.c index 98401121b..8a1dffc14 100644 --- a/src/common/percent.c +++ b/src/common/percent.c @@ -14,6 +14,45 @@ static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module) ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars); } +const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFlags* result) +{ + if (yyjson_is_uint(jsonVal)) + { + *result = (FFPercentageTypeFlags) yyjson_get_uint(jsonVal); + return NULL; + } + if (yyjson_is_arr(jsonVal)) + { + FFPercentageTypeFlags flags = 0; + + yyjson_val* item; + size_t idx, max; + yyjson_arr_foreach(jsonVal, idx, max, item) + { + const char* flag = yyjson_get_str(item); + if (!flag) + return "Error: percent.type: invalid flag string"; + if (ffStrEqualsIgnCase(flag, "num")) + flags |= FF_PERCENTAGE_TYPE_NUM_BIT; + else if (ffStrEqualsIgnCase(flag, "bar")) + flags |= FF_PERCENTAGE_TYPE_BAR_BIT; + else if (ffStrEqualsIgnCase(flag, "hide-others")) + flags |= FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT; + else if (ffStrEqualsIgnCase(flag, "num-color")) + flags |= FF_PERCENTAGE_TYPE_NUM_COLOR_BIT; + else if (ffStrEqualsIgnCase(flag, "bar-monochrome")) + flags |= FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT; + else + return "Error: percent.type: unknown flag string"; + } + + *result = flags; + return NULL; + } + + return "Error: usage: percent.type must be a number or an array of strings"; +} + void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module) { uint8_t green = config.green, yellow = config.yellow; @@ -238,7 +277,12 @@ bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageMo yyjson_val* typeVal = yyjson_obj_get(value, "type"); if (typeVal) { - config->type = (FFPercentageTypeFlags) yyjson_get_int(typeVal); + const char* error = ffPercentParseTypeJsonConfig(typeVal, &config->type); + if (error) + { + fputs(error, stderr); + exit(480); + } } return true; diff --git a/src/common/percent.h b/src/common/percent.h index f06ad1a3e..7341b7ba0 100644 --- a/src/common/percent.h +++ b/src/common/percent.h @@ -42,3 +42,4 @@ typedef struct yyjson_mut_val yyjson_mut_val; bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config); bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageModuleConfig* config); void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig defaultConfig, FFPercentageModuleConfig config); +const char* ffPercentParseTypeJsonConfig(yyjson_val* value, FFPercentageTypeFlags* result); diff --git a/src/options/display.c b/src/options/display.c index 0dc0ad6a9..111a5cdfc 100644 --- a/src/options/display.c +++ b/src/options/display.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/color.h" #include "common/jsonconfig.h" +#include "common/percent.h" #include "util/stringUtils.h" #include "options/display.h" @@ -166,7 +167,11 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va return "display.percent must be an object"; yyjson_val* type = yyjson_obj_get(val, "type"); - if (type) options->percentType = (uint8_t) yyjson_get_uint(type); + if (type) + { + const char* error = ffPercentParseTypeJsonConfig(type, &options->percentType); + if (error) return error; + } yyjson_val* ndigits = yyjson_obj_get(val, "ndigits"); if (ndigits) options->percentNdigits = (uint8_t) yyjson_get_uint(ndigits); From 6801fe3d9ca3756325a7bae98c8bd0070e46fbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Nov 2024 14:22:24 +0800 Subject: [PATCH 49/61] Doc: update schema for percent type config --- doc/json_schema.json | 38 +++++++++++++++++++++++++++++++++----- src/data/help.json | 18 ++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/doc/json_schema.json b/doc/json_schema.json index 7450e0884..3c0c9fa76 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -34,6 +34,35 @@ "description": "Output color of the module. Left empty to use `display.color.output`", "$ref": "#/$defs/colors" }, + "percentType": { + "description": "Set the percentage output type", + "oneOf": [ + { + "type": "number", + "description": "1 for percentage number, 2 for multi-color bar, 3 for both, 6 for bar only, 9 for colored number, 10 for monochrome bar", + "minimum": 0, + "maximum": 255, + "default": 9 + }, + { + "type": "array", + "description": "array of string flags", + "items": { + "enum": [ + "num", + "bar", + "hide-others", + "num-color", + "bar-monochrome" + ] + }, + "default": [ + "num", + "num-color" + ] + } + ] + }, "percent": { "description": "Threshold of percentage colors", "type": "object", @@ -50,6 +79,9 @@ "minimum": 0, "maximum": 100, "description": "Value greater than green and less then yellow will be shown in yellow.\nValue greater than yellow will be shown in red" + }, + "type": { + "$ref": "#/$defs/percentType" } } }, @@ -576,11 +608,7 @@ "description": "Set how a percentage value should be displayed", "properties": { "type": { - "type": "number", - "description": "Set the percentage output type. 1 for percentage number, 2 for multi-color bar, 3 for both, 6 for bar only, 9 for colored number, 10 for monochrome bar", - "minimum": 0, - "maximum": 255, - "default": 9 + "$ref": "#/$defs/percentType" }, "ndigits": { "type": "number", diff --git a/src/data/help.json b/src/data/help.json index c7e4a88ec..481b3a3e2 100644 --- a/src/data/help.json +++ b/src/data/help.json @@ -1602,6 +1602,24 @@ }, "pseudo": true }, + { + "long": "-percent-type", + "desc": "Set the percentage output type", + "remark": [ + "0 for use global `--percent-type` value", + "1 for percentage number", + "2 for multi-color bar", + "3 for both", + "6 for bar only", + "9 for colored number", + "10 for monochrome bar" + ], + "arg": { + "type": "num", + "default": 0 + }, + "pseudo": true + }, { "long": "-temp-green", "desc": [ From 782af250ff14a131eb5b6c1b2de402069e1513c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Nov 2024 15:33:43 +0800 Subject: [PATCH 50/61] Percent: in custom format, only set num and bar string if enabled in percent config Also fix `percentage-bar` printing in Brightness module --- src/modules/battery/battery.c | 7 +++++-- src/modules/bluetooth/bluetooth.c | 8 +++++--- src/modules/brightness/brightness.c | 9 ++++++--- src/modules/btrfs/btrfs.c | 14 ++++++++++---- src/modules/cpuusage/cpuusage.c | 19 +++++++++++++------ src/modules/disk/disk.c | 12 ++++++++---- src/modules/gamepad/gamepad.c | 8 +++++--- src/modules/memory/memory.c | 9 ++++++--- src/modules/sound/sound.c | 8 +++++--- src/modules/swap/swap.c | 8 +++++--- src/modules/wifi/wifi.c | 7 +++++-- src/modules/zpool/zpool.c | 13 +++++++++---- 12 files changed, 82 insertions(+), 40 deletions(-) diff --git a/src/modules/battery/battery.c b/src/modules/battery/battery.c index 013b9a695..c40f7a629 100644 --- a/src/modules/battery/battery.c +++ b/src/modules/battery/battery.c @@ -97,11 +97,14 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin else { FF_STRBUF_AUTO_DESTROY capacityNum = ffStrbufCreate(); - ffPercentAppendNum(&capacityNum, result->capacity, options->percent, false, &options->moduleArgs); + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&capacityNum, result->capacity, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY capacityBar = ffStrbufCreate(); - ffPercentAppendBar(&capacityBar, result->capacity, options->percent, &options->moduleArgs); + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&capacityBar, result->capacity, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate(); ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig, &options->moduleArgs); + FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) { FF_FORMAT_ARG(result->manufacturer, "manufacturer"), FF_FORMAT_ARG(result->modelName, "model-name"), diff --git a/src/modules/bluetooth/bluetooth.c b/src/modules/bluetooth/bluetooth.c index bd07ab0d3..0116ce236 100644 --- a/src/modules/bluetooth/bluetooth.c +++ b/src/modules/bluetooth/bluetooth.c @@ -9,13 +9,13 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* device, uint8_t index) { + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); bool showBatteryLevel = device->battery > 0 && device->battery <= 100; - FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if (showBatteryLevel && (percentType & FF_PERCENTAGE_TYPE_BAR_BIT)) { @@ -41,9 +41,11 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* de else { FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); - ffPercentAppendNum(&percentageNum, device->battery, options->percent, false, &options->moduleArgs); + if(percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&percentageNum, device->battery, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); - ffPercentAppendBar(&percentageBar, device->battery, options->percent, &options->moduleArgs); + if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&percentageBar, device->battery, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BLUETOOTH_NUM_FORMAT_ARGS, ((FFformatarg[]) { FF_FORMAT_ARG(device->name, "name"), diff --git a/src/modules/brightness/brightness.c b/src/modules/brightness/brightness.c index bc06b68ba..dc7e2f455 100644 --- a/src/modules/brightness/brightness.c +++ b/src/modules/brightness/brightness.c @@ -89,16 +89,19 @@ void ffPrintBrightness(FFBrightnessOptions* options) else { FF_STRBUF_AUTO_DESTROY valueNum = ffStrbufCreate(); - ffPercentAppendNum(&valueNum, percent, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&valueNum, percent, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY valueBar = ffStrbufCreate(); - ffPercentAppendBar(&valueBar, percent, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&valueBar, percent, options->percent, &options->moduleArgs); + FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BRIGHTNESS_NUM_FORMAT_ARGS, ((FFformatarg[]) { FF_FORMAT_ARG(valueNum, "percentage"), FF_FORMAT_ARG(item->name, "name"), FF_FORMAT_ARG(item->max, "max"), FF_FORMAT_ARG(item->min, "min"), FF_FORMAT_ARG(item->current, "current"), - FF_FORMAT_ARG(item->current, "percentage-bar"), + FF_FORMAT_ARG(valueBar, "percentage-bar"), })); } diff --git a/src/modules/btrfs/btrfs.c b/src/modules/btrfs/btrfs.c index 7054e8139..e295a2a26 100644 --- a/src/modules/btrfs/btrfs.c +++ b/src/modules/btrfs/btrfs.c @@ -45,6 +45,8 @@ static void printBtrfs(FFBtrfsOptions* options, FFBtrfsResult* result, uint8_t i double usedPercentage = total > 0 ? (double) used / (double) total * 100.0 : 0; double allocatedPercentage = total > 0 ? (double) allocated / (double) total * 100.0 : 0; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; + if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(buffer.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); @@ -60,14 +62,18 @@ static void printBtrfs(FFBtrfsOptions* options, FFBtrfsResult* result, uint8_t i else { FF_STRBUF_AUTO_DESTROY usedPercentageNum = ffStrbufCreate(); - ffPercentAppendNum(&usedPercentageNum, usedPercentage, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&usedPercentageNum, usedPercentage, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY usedPercentageBar = ffStrbufCreate(); - ffPercentAppendBar(&usedPercentageBar, usedPercentage, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&usedPercentageBar, usedPercentage, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY allocatedPercentageNum = ffStrbufCreate(); - ffPercentAppendNum(&allocatedPercentageNum, allocatedPercentage, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&allocatedPercentageNum, allocatedPercentage, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY allocatedPercentageBar = ffStrbufCreate(); - ffPercentAppendBar(&allocatedPercentageBar, allocatedPercentage, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&allocatedPercentageBar, allocatedPercentage, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY nodeSizePretty = ffStrbufCreate(); ffParseSize(result->nodeSize, &nodeSizePretty); diff --git a/src/modules/cpuusage/cpuusage.c b/src/modules/cpuusage/cpuusage.c index 1fc7490c6..a224517c6 100644 --- a/src/modules/cpuusage/cpuusage.c +++ b/src/modules/cpuusage/cpuusage.c @@ -76,17 +76,24 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options) else { FF_STRBUF_AUTO_DESTROY avgNum = ffStrbufCreate(); - ffPercentAppendNum(&avgNum, avgValue, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&avgNum, avgValue, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY avgBar = ffStrbufCreate(); - ffPercentAppendBar(&avgBar, avgValue, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&avgBar, avgValue, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY minNum = ffStrbufCreate(); - ffPercentAppendNum(&minNum, minValue, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&minNum, minValue, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY minBar = ffStrbufCreate(); - ffPercentAppendBar(&minBar, minValue, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&minBar, minValue, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY maxNum = ffStrbufCreate(); - ffPercentAppendNum(&maxNum, maxValue, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&maxNum, maxValue, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY maxBar = ffStrbufCreate(); - ffPercentAppendBar(&maxBar, maxValue, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&maxBar, maxValue, options->percent, &options->moduleArgs); + FF_PRINT_FORMAT_CHECKED(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPUUSAGE_NUM_FORMAT_ARGS, ((FFformatarg[]){ FF_FORMAT_ARG(avgNum, "avg"), FF_FORMAT_ARG(maxNum, "max"), diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c index b47c2bb0a..a095d8c59 100644 --- a/src/modules/disk/disk.c +++ b/src/modules/disk/disk.c @@ -108,15 +108,19 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index else { FF_STRBUF_AUTO_DESTROY bytesPercentageNum = ffStrbufCreate(); - ffPercentAppendNum(&bytesPercentageNum, bytesPercentage, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&bytesPercentageNum, bytesPercentage, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY bytesPercentageBar = ffStrbufCreate(); - ffPercentAppendBar(&bytesPercentageBar, bytesPercentage, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&bytesPercentageBar, bytesPercentage, options->percent, &options->moduleArgs); double filesPercentage = disk->filesTotal > 0 ? ((double) disk->filesUsed / (double) disk->filesTotal) * 100.0 : 0; FF_STRBUF_AUTO_DESTROY filesPercentageNum = ffStrbufCreate(); - ffPercentAppendNum(&filesPercentageNum, filesPercentage, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&filesPercentageNum, filesPercentage, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY filesPercentageBar = ffStrbufCreate(); - ffPercentAppendBar(&filesPercentageBar, filesPercentage, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&filesPercentageBar, filesPercentage, options->percent, &options->moduleArgs); bool isExternal = !!(disk->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT); bool isHidden = !!(disk->type & FF_DISK_VOLUME_TYPE_HIDDEN_BIT); diff --git a/src/modules/gamepad/gamepad.c b/src/modules/gamepad/gamepad.c index 154b71a6e..82e1b29af 100644 --- a/src/modules/gamepad/gamepad.c +++ b/src/modules/gamepad/gamepad.c @@ -9,13 +9,13 @@ static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device, uint8_t index) { + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); bool showBatteryLevel = device->battery > 0 && device->battery <= 100; - FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if (showBatteryLevel && (percentType & FF_PERCENTAGE_TYPE_BAR_BIT)) { @@ -37,9 +37,11 @@ static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device else { FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); - ffPercentAppendNum(&percentageNum, device->battery, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&percentageNum, device->battery, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); - ffPercentAppendBar(&percentageBar, device->battery, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&percentageBar, device->battery, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_GAMEPAD_NUM_FORMAT_ARGS, ((FFformatarg[]) { FF_FORMAT_ARG(device->name, "name"), diff --git a/src/modules/memory/memory.c b/src/modules/memory/memory.c index d364225c1..8cad52839 100644 --- a/src/modules/memory/memory.c +++ b/src/modules/memory/memory.c @@ -29,6 +29,7 @@ void ffPrintMemory(FFMemoryOptions* options) ? 0 : (double) storage.bytesUsed / (double) storage.bytesTotal * 100.0; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); @@ -37,7 +38,6 @@ void ffPrintMemory(FFMemoryOptions* options) else { FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); - FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { @@ -58,9 +58,12 @@ void ffPrintMemory(FFMemoryOptions* options) else { FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); - ffPercentAppendNum(&percentageNum, percentage, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&percentageNum, percentage, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); - ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs); + FF_PRINT_FORMAT_CHECKED(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_MEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]){ FF_FORMAT_ARG(usedPretty, "used"), FF_FORMAT_ARG(totalPretty, "total"), diff --git a/src/modules/sound/sound.c b/src/modules/sound/sound.c index dafc37619..1e0cd7e84 100644 --- a/src/modules/sound/sound.c +++ b/src/modules/sound/sound.c @@ -9,10 +9,10 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, uint8_t index) { + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_SOUND_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); - FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) @@ -48,9 +48,11 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui else { FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); - ffPercentAppendNum(&percentageNum, device->volume, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&percentageNum, device->volume, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); - ffPercentAppendBar(&percentageBar, device->volume, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&percentageBar, device->volume, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_SOUND_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_SOUND_NUM_FORMAT_ARGS, ((FFformatarg[]) { FF_FORMAT_ARG(device->main, "is-main"), diff --git a/src/modules/swap/swap.c b/src/modules/swap/swap.c index c71831571..6fba1f3aa 100644 --- a/src/modules/swap/swap.c +++ b/src/modules/swap/swap.c @@ -29,11 +29,11 @@ void ffPrintSwap(FFSwapOptions* options) ? 0 : (double) storage.bytesUsed / (double) storage.bytesTotal * 100.0; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); - FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if (storage.bytesTotal == 0) { @@ -68,9 +68,11 @@ void ffPrintSwap(FFSwapOptions* options) else { FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); - ffPercentAppendNum(&percentageNum, percentage, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&percentageNum, percentage, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); - ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_SWAP_NUM_FORMAT_ARGS, ((FFformatarg[]){ FF_FORMAT_ARG(usedPretty, "used"), FF_FORMAT_ARG(totalPretty, "total"), diff --git a/src/modules/wifi/wifi.c b/src/modules/wifi/wifi.c index be6b63649..b2d829d42 100644 --- a/src/modules/wifi/wifi.c +++ b/src/modules/wifi/wifi.c @@ -79,9 +79,12 @@ void ffPrintWifi(FFWifiOptions* options) else { FF_STRBUF_AUTO_DESTROY percentNum = ffStrbufCreate(); - ffPercentAppendNum(&percentNum, item->conn.signalQuality, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&percentNum, item->conn.signalQuality, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY percentBar = ffStrbufCreate(); - ffPercentAppendBar(&percentBar, item->conn.signalQuality, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&percentBar, item->conn.signalQuality, options->percent, &options->moduleArgs); + FF_PRINT_FORMAT_CHECKED(FF_WIFI_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_WIFI_NUM_FORMAT_ARGS, ((FFformatarg[]){ FF_FORMAT_ARG(item->inf.description, "inf-desc"), FF_FORMAT_ARG(item->inf.status, "inf-status"), diff --git a/src/modules/zpool/zpool.c b/src/modules/zpool/zpool.c index a8e56146f..a47cb244d 100644 --- a/src/modules/zpool/zpool.c +++ b/src/modules/zpool/zpool.c @@ -34,6 +34,7 @@ static void printZpool(FFZpoolOptions* options, FFZpoolResult* result, uint8_t i ffParseSize(result->total, &totalPretty); double bytesPercentage = result->total > 0 ? (double) result->used / (double) result->total * 100.0 : 0; + FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { @@ -50,14 +51,18 @@ static void printZpool(FFZpoolOptions* options, FFZpoolResult* result, uint8_t i else { FF_STRBUF_AUTO_DESTROY bytesPercentageNum = ffStrbufCreate(); - ffPercentAppendNum(&bytesPercentageNum, bytesPercentage, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&bytesPercentageNum, bytesPercentage, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY bytesPercentageBar = ffStrbufCreate(); - ffPercentAppendBar(&bytesPercentageBar, bytesPercentage, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&bytesPercentageBar, bytesPercentage, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY fragPercentageNum = ffStrbufCreate(); - ffPercentAppendNum(&fragPercentageNum, result->fragmentation, options->percent, false, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&fragPercentageNum, result->fragmentation, options->percent, false, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY fragPercentageBar = ffStrbufCreate(); - ffPercentAppendBar(&fragPercentageBar, result->fragmentation, options->percent, &options->moduleArgs); + if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffPercentAppendBar(&fragPercentageBar, result->fragmentation, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(buffer.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_ZPOOL_NUM_FORMAT_ARGS, ((FFformatarg[]) { FF_FORMAT_ARG(result->name, "name"), From e77a4e82624643e763ef8f60fc7a172a800f2455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Nov 2024 16:40:45 +0800 Subject: [PATCH 51/61] Doc: update changelog [ci skip] --- CHANGELOG.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3c50f40..98d2039c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,50 @@ +# 2.30.0 + +Changes: +* Percent: bar type must be enabled in `percent.type` before using percent bar in custom format + +Features: +* Port to MidnightBSD; add mport package manager support +* Support bluetooth battery detection for macOS and Windows (Bluetooth, macOS / Windows) +* Support M4 model detection (Host, macOS) +* Support CPU temperature detection on OpenBSD (CPU, OpenBSD) +* Display Android icon in Android devices (OS, Android) +* Support qi package manager detection (Packages, Linux) +* Detect WM / DE by enumerating running processes (WM / DE, NetBSD) +* Generate manual pages from `help.json` (Doc) +* Detect marketing name of vivo smartphone (Host, Android) +* Support percent type config in module level. Example: + +```json +{ + "type": "memory", + "percent": { + "green": 20, // [0%, 20%) will be displayed in green + "yellow": 40, // [20, 40) will be displayed in yellow and [40, 100] will be displayed in red + "type": [ // Display percent value in monochrome bar, same as 10 + "bar", + "bar-monochrome" + ] + } +} +``` + +Bugfixes: +* Don't display `()` in key if display name is not available (Display) +* Fix & normalize bluetooth mac address detection (Bluetooth, macOS / Windows) +* Don't print index in multi-battery devices (Battery) +* Fix segfault in macOS (#1388, macOS) +* Fix `CFStringGetCString() failed` errors (#1394, Media, macOS) +* Fix CPU frequency detection on Apple M4 (#1394, CPU, macOS) +* Fix exe path detection on macOS (Shell / Terminal, macOS) +* Fix logo fails to load from symlinked files on macOS (#1395, Logo, macOS) + +Logos: +* Fix Lilidog +* Add MidnightBSD +* Add Unifi +* Add Cosmic DE + # 2.29.0 Changes: From b8ec07092a66cea1dcb42b2af15e91dad1132f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 15 Nov 2024 08:40:52 +0800 Subject: [PATCH 52/61] Logo (Builtin): update openSUSE Tumbleweed Fix #1398 --- CHANGELOG.md | 1 + src/logo/ascii/opensuse_tumbleweed.txt | 29 +++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98d2039c3..5b134842b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Logos: * Add MidnightBSD * Add Unifi * Add Cosmic DE +* Update openSUSE Tumbleweed # 2.29.0 diff --git a/src/logo/ascii/opensuse_tumbleweed.txt b/src/logo/ascii/opensuse_tumbleweed.txt index bf857a76a..111a61fcb 100644 --- a/src/logo/ascii/opensuse_tumbleweed.txt +++ b/src/logo/ascii/opensuse_tumbleweed.txt @@ -1,21 +1,22 @@ - .,:looooooc;. - ,ool oo,;oo: + ,..., + .,:lloooooc;. + ,ool' oo,;oo: .lo' oo. oo: - oo. oo. oo: +.oo. oo. oo: :ol oo. 'oo :oo .oo. .oo. .oooooooooooooo. .oo. ;oo. .oo. - oo, .oo. - .ooc,'..........:ooc.......... - .cooooooooooooooooooooooooool;. + 'oo, .oo. + "ooc,',,,,,,,,,,:ooc,,,,,,,,,,, + ':cooooooooooooooooooooooooool;. .oo. .oo; .oo. .oo. - .oo. oooooooooo:ooo. - .oo. .oo. col - oo' .oo col - coo .oo oo' - coc .oo lo, - .oo, .oo .:oo - .oooooc,,,:lol - ,clc' \ No newline at end of file + .oo. 'oooooooooo:ooo. + .oo. 'oo. col + .oo' 'oo col + coo 'oo oo' + coc 'oo .lo, + `oo, 'oo .:oo + 'ooooc,, ,:lol + `''"clc"' \ No newline at end of file From 563ed58b4f94a338ec3e9407ddfbbce48429f848 Mon Sep 17 00:00:00 2001 From: Dariqq <77271900+Dariqq@users.noreply.github.com> Date: Fri, 15 Nov 2024 00:50:47 +0000 Subject: [PATCH 53/61] Scripts: `gen-man.py` honors SOURCE_DATE_EPOCH. (#1400) --- scripts/gen-man.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/gen-man.py b/scripts/gen-man.py index 77c32f461..def48b072 100755 --- a/scripts/gen-man.py +++ b/scripts/gen-man.py @@ -10,8 +10,9 @@ from json import load from datetime import date +from time import time from re import search -from os import path +from os import environ, path ###### Text Decorations Tags ###### @@ -34,7 +35,9 @@ # title (center header) titlePage = "Fastfetch man page" # date (center footer) -todayDate = date.today().strftime("%b %d %Y") # format : "Month (abbreviation) Day Year" +# format : "Month (abbreviation) Day Year" +todayDate = date.fromtimestamp( + int(environ.get("SOURCE_DATE_EPOCH", time()))).strftime("%b %d %Y") # file to fastfetch version (left footer) pathToVersionFile = path.join(pathToCurrentDir, "../CMakeLists.txt") From 56eb8b80c601016760e1005684add4747190df22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 15 Nov 2024 14:35:25 +0800 Subject: [PATCH 54/61] NetIO (macOS): fix 32bit trancation --- CHANGELOG.md | 1 + CMakeLists.txt | 2 +- src/detection/netio/netio_apple.c | 56 +++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/detection/netio/netio_apple.c diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b134842b..1267a3a92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ Bugfixes: * Fix CPU frequency detection on Apple M4 (#1394, CPU, macOS) * Fix exe path detection on macOS (Shell / Terminal, macOS) * Fix logo fails to load from symlinked files on macOS (#1395, Logo, macOS) +* Fix 32-bit truncation (NetIO, macOS) Logos: * Fix Lilidog diff --git a/CMakeLists.txt b/CMakeLists.txt index 440929008..fe7a99f2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -887,7 +887,7 @@ elseif(APPLE) src/detection/media/media_apple.m src/detection/memory/memory_apple.c src/detection/mouse/mouse_apple.c - src/detection/netio/netio_bsd.c + src/detection/netio/netio_apple.c src/detection/opengl/opengl_apple.c src/detection/os/os_apple.m src/detection/packages/packages_apple.c diff --git a/src/detection/netio/netio_apple.c b/src/detection/netio/netio_apple.c new file mode 100644 index 000000000..cd5106026 --- /dev/null +++ b/src/detection/netio/netio_apple.c @@ -0,0 +1,56 @@ +#include "netio.h" + +#include "common/netif/netif.h" +#include "util/mallocHelper.h" + +#include +#include +#include + +const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) +{ + int mib[] = {CTL_NET, PF_LINK, NETLINK_GENERIC, + options->defaultRouteOnly ? IFMIB_IFDATA : IFMIB_IFALLDATA, + options->defaultRouteOnly ? (int) ffNetifGetDefaultRouteIfIndex() : 0, + IFDATA_GENERAL}; + + size_t bufSize = 0; + if (sysctl(mib, ARRAY_SIZE(mib), NULL, &bufSize, 0, 0) < 0) + return "sysctl(mib, ARRAY_SIZE(mib), NULL, &bufSize, 0, 0) failed"; + + assert(bufSize % sizeof(struct ifmibdata) == 0); + + FF_AUTO_FREE struct ifmibdata* buf = (struct ifmibdata*) malloc(bufSize); + if (sysctl(mib, ARRAY_SIZE(mib), buf, &bufSize, 0, 0) < 0) + return "sysctl(mib, ARRAY_SIZE(mib), buf, &bufSize, 0, 0) failed"; + + size_t ifCount = bufSize / sizeof(struct ifmibdata); + + const char* defaultRouteIfName = ffNetifGetDefaultRouteIfName(); + + for (size_t i = 0; i < ifCount; i++) + { + struct ifmibdata* mibdata = &buf[i]; + if (!(mibdata->ifmd_flags & IFF_RUNNING) || (mibdata->ifmd_flags & IFF_NOARP)) + continue; + + if (options->namePrefix.length && strncmp(mibdata->ifmd_name, options->namePrefix.chars, options->namePrefix.length) != 0) + continue; + + FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result); + *counters = (FFNetIOResult) { + .name = ffStrbufCreateS(mibdata->ifmd_name), + .txBytes = mibdata->ifmd_data.ifi_obytes, + .rxBytes = mibdata->ifmd_data.ifi_ibytes, + .txPackets = mibdata->ifmd_data.ifi_opackets, + .rxPackets = mibdata->ifmd_data.ifi_ipackets, + .txErrors = mibdata->ifmd_data.ifi_oerrors, + .rxErrors = mibdata->ifmd_data.ifi_ierrors, + .txDrops = mibdata->ifmd_snd_drops, + .rxDrops = mibdata->ifmd_data.ifi_iqdrops, + .defaultRoute = strncmp(mibdata->ifmd_name, defaultRouteIfName, IFNAMSIZ) == 0, + }; + } + + return NULL; +} From 9f314a208b20d1aea76d9c758918521beb5dd406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 15 Nov 2024 14:48:17 +0800 Subject: [PATCH 55/61] NetIO (BSD): add txDrops detection if supported --- CHANGELOG.md | 1 + CMakeLists.txt | 10 ++++++++++ src/detection/netio/netio_bsd.c | 6 ++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1267a3a92..45309bc4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Features: * Detect WM / DE by enumerating running processes (WM / DE, NetBSD) * Generate manual pages from `help.json` (Doc) * Detect marketing name of vivo smartphone (Host, Android) +* Add txDrops detection if supported (NetIO, *BSD) * Support percent type config in module level. Example: ```json diff --git a/CMakeLists.txt b/CMakeLists.txt index fe7a99f2a..9bab8a0a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1180,6 +1180,16 @@ elseif(NetBSD) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/usr/X11R7/lib -Wl,-rpath,/usr/pkg/lib") # ditto endif() +if(FreeBSD OR OpenBSD OR NetBSD) + include(CheckStructHasMember) + set(CMAKE_REQUIRED_DEFINITIONS "-D_IFI_OQDROPS=1") + CHECK_STRUCT_HAS_MEMBER("struct if_data" ifi_oqdrops net/if.h HAVE_IFI_OQDROPS LANGUAGE C) + if(HAVE_IFI_OQDROPS) + target_compile_definitions(libfastfetch PUBLIC _IFI_OQDROPS FF_HAVE_IFI_OQDROPS) + endif() + unset(CMAKE_REQUIRED_DEFINITIONS) +endif() + if(HAVE_STATX) target_compile_definitions(libfastfetch PUBLIC FF_HAVE_STATX) endif() diff --git a/src/detection/netio/netio_bsd.c b/src/detection/netio/netio_bsd.c index 5328949a9..d1e4dbd81 100644 --- a/src/detection/netio/netio_bsd.c +++ b/src/detection/netio/netio_bsd.c @@ -1,8 +1,6 @@ #include "netio.h" -#include "common/io/io.h" #include "common/netif/netif.h" -#include "util/stringUtils.h" #include "util/mallocHelper.h" #include @@ -48,8 +46,8 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) .rxPackets = ifm->ifm_data.ifi_ipackets, .txErrors = ifm->ifm_data.ifi_oerrors, .rxErrors = ifm->ifm_data.ifi_ierrors, - #ifdef _IFI_OQDROPS - .txDrops = if2m->ifm_data.ifi_oqdrops, + #ifdef FF_HAVE_IFI_OQDROPS + .txDrops = ifm->ifm_data.ifi_oqdrops, #else .txDrops = 0, // unsupported #endif From e5451b6826bff70eaa27dca8783d0429740d8fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 15 Nov 2024 15:10:08 +0800 Subject: [PATCH 56/61] NetIO (BSD): remove unnecessary checks Seems... --- src/detection/netio/netio_bsd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/detection/netio/netio_bsd.c b/src/detection/netio/netio_bsd.c index d1e4dbd81..9044600e5 100644 --- a/src/detection/netio/netio_bsd.c +++ b/src/detection/netio/netio_bsd.c @@ -30,7 +30,6 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) struct sockaddr_dl* sdl = (struct sockaddr_dl*) (ifm + 1); assert(sdl->sdl_family == AF_LINK); - if (sdl->sdl_type != IFT_ETHER && !(ifm->ifm_flags & IFF_LOOPBACK)) continue; sdl->sdl_data[sdl->sdl_nlen] = 0; From b7a9fe58b42eac4a7dff0f4a34c1814c740bc97e Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 15 Nov 2024 16:18:43 +0800 Subject: [PATCH 57/61] Terminal (Linux): support tilix version detection --- CHANGELOG.md | 1 + src/detection/terminalshell/terminalshell.c | 23 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45309bc4f..379c12bcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Features: * Generate manual pages from `help.json` (Doc) * Detect marketing name of vivo smartphone (Host, Android) * Add txDrops detection if supported (NetIO, *BSD) +* Support tilix version detection (Terminal, Linux) * Support percent type config in module level. Example: ```json diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index b8f6e1159..7ce6854a5 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -641,6 +641,26 @@ FF_MAYBE_UNUSED static bool getTerminalVersionPtyxis(FF_MAYBE_UNUSED FFstrbuf* e ffStrbufSubstrAfterFirstC(version, ' '); return true; } + +FF_MAYBE_UNUSED static bool getTerminalVersionTilix(FFstrbuf* exe, FFstrbuf* version) +{ + if(ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "--version", + NULL + }) != NULL) + return false; + + uint32_t index = ffStrbufFirstIndexS(version, "Tilix version: "); + if (index == version->length) return false; + + index += (uint32_t) strlen("Tilix version:"); + uint32_t end = ffStrbufNextIndexC(version, index, '\n'); + + ffStrbufSubstrBefore(version, end); + ffStrbufSubstrAfter(version, index); + return true; +} #endif #ifdef _WIN32 @@ -740,6 +760,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe if(ffStrbufIgnCaseEqualS(processName, "ptyxis-agent")) return getTerminalVersionPtyxis(exe, version); + if(ffStrbufIgnCaseEqualS(processName, "tilix")) + return getTerminalVersionTilix(exe, version); + #endif #ifdef _WIN32 From ba7d3ed27b90ddabd236a1ba8904eecb6793205a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 15 Nov 2024 19:47:24 +0800 Subject: [PATCH 58/61] GPU (Windows): fix a bad assignment --- src/detection/gpu/gpu_amd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/gpu/gpu_amd.c b/src/detection/gpu/gpu_amd.c index 72e1d9fc0..7bc535382 100644 --- a/src/detection/gpu/gpu_amd.c +++ b/src/detection/gpu/gpu_amd.c @@ -66,7 +66,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu *result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE; if (result.index) - *result.type = (uint32_t) device->adlAdapterIndex; + *result.index = (uint32_t) device->adlAdapterIndex; if (result.name) ffStrbufSetS(result.name, device->adapterString); From dcdf2b570eb8d669c4519381225452106700a4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 15 Nov 2024 20:01:56 +0800 Subject: [PATCH 59/61] Display: concat flags --- src/modules/display/display.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/modules/display/display.c b/src/modules/display/display.c index 08aa89eea..6c720f31b 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -124,11 +124,21 @@ void ffPrintDisplay(FFDisplayOptions* options) if (inch > 1) ffStrbufAppendF(&buffer, " in %i\"", (uint32_t) (inch + 0.5)); - if(result->type != FF_DISPLAY_TYPE_UNKNOWN) - ffStrbufAppendS(&buffer, result->type == FF_DISPLAY_TYPE_BUILTIN ? " [Built-in]" : " [External]"); + bool flag = false; + if (result->type != FF_DISPLAY_TYPE_UNKNOWN) + { + ffStrbufAppendS(&buffer, result->type == FF_DISPLAY_TYPE_BUILTIN ? " [Built-in" : " [External"); + flag = true; + } if (result->hdrStatus == FF_DISPLAY_HDR_STATUS_ENABLED) - ffStrbufAppendS(&buffer, " [HDR]"); + { + ffStrbufAppendS(&buffer, flag ? ", HDR" : " [HDR"); + flag = true; + } + + if (flag) + ffStrbufAppendS(&buffer, "]"); if(moduleIndex > 0 && result->primary) ffStrbufAppendS(&buffer, " *"); From a73a3089afa91c577ea7e975aacb3d87cf6c06b5 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 18 Nov 2024 08:40:45 +0800 Subject: [PATCH 60/61] Doc: remove guix package installer as it's outdated [ci skip] --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 2246074f8..01f9d44bf 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,6 @@ Some distros package an outdated fastfetch version. Older versions receive no su * openSUSE: `zypper install fastfetch` * ALT Linux: `apt-get install fastfetch` * Exherbo: `cave resolve --execute app-misc/fastfetch` -* GNU Guix: `guix install fastfetch` * Solus: `eopkg install fastfetch` * Slackware: `sbopkg -i fastfetch` * Void Linux: `xbps-install fastfetch` From dbb6a4b2657398891aefffb98e95a94ead6b73df Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 18 Nov 2024 09:04:17 +0800 Subject: [PATCH 61/61] Release: v2.30.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bab8a0a7..ec7725f46 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 2.29.0 + VERSION 2.30.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"