Compare commits

...

74 Commits

Author SHA1 Message Date
Carter Li e9bb761a2d Merge pull request #1258 from fastfetch-cli/dev
Release v2.24.0
2024-09-11 13:36:44 +08:00
李通洲 fd432e3635 Presets: fix 9.jsonc [ci skip] 2024-09-11 13:35:05 +08:00
李通洲 174dde131c TerminalFont: silence CodeQL warnings 2024-09-11 13:28:21 +08:00
李通洲 99668771c7 Release: v2.24.0 2024-09-11 11:14:27 +08:00
李通洲 dc541ac781 Formatting: support syntax of sub string
Fix #1256; Ref #1255
2024-09-11 11:07:00 +08:00
Juanma 68ab41f748 Logo (Builtin): Add Lliurex Art (#1257)
* lainos to top of FFlogo K

* Add LliureX art

* Add lliurex detect

* OS (Linux): fix coding style

* Update lliurex.txt

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-09-11 09:08:40 +08:00
李通洲 e8f711830e Command: add new option --command-param
Fix #1255
2024-09-10 22:00:14 +08:00
李通洲 a052033dc6 IO: allow issuing multiple terminal queries in one call 2024-09-10 15:18:12 +08:00
李通洲 fed2c87f67 TerminalTheme (macOS): fix hanging on GNU screen 5.0 2024-09-10 11:12:16 +08:00
Carter Li b7fcd7fc0c Board (Linux): use model name as board name if SMBIOS is not available 2024-09-10 09:17:09 +08:00
Carter Li b2810bc030 CPU (Linux): update comments 2024-09-10 09:10:03 +08:00
Carter Li 8f1f1607da GPU (Linux): improve result for unknown Apple SOC 2024-09-09 20:49:25 +08:00
Carter Li 611d5f949b CPU (Linux): detect Qualcomm Snapdragon SOC 2024-09-09 20:49:25 +08:00
Carter Li 536e2fb42d Doc: update changelog [ci skip] 2024-09-09 16:41:27 +08:00
Carter Li 1e4601485a Binary (FreeBSD): update comments [ci skip] 2024-09-07 15:47:52 +08:00
Carter Li f8c58a9178 Terminal: add fast path of mate-terminal version detection 2024-09-07 15:23:42 +08:00
Carter Li d8fb8d439e Binary (FreeBSD): use system libelf
There are pkg elfutils. However it is not ABI compatible with system
libelf
2024-09-07 15:22:38 +08:00
李通洲 de59ffb31f Revert "TerminalTheme: fix hanging on screen 5.0"
It breaks kitty terminal font detection

This reverts commit 1ab86a8ab9.
2024-09-06 16:40:24 +08:00
Carter Li c24d378cf1 CPU (FreeBSD): detect the number of online cores 2024-09-06 15:37:37 +08:00
Carter Li de8efb39c8 CPU (ARM): add new microarchitectures 2024-09-06 14:11:57 +08:00
Carter Li 13452da076 CPU (Linux): add more Snapdragon SOCs 2024-09-06 14:01:56 +08:00
李通洲 7db8d7c3ce Doc: remove --lib-xxx [ci skip] 2024-09-05 10:39:53 +08:00
may f4424b4204 Uptime (Linux): fix linux bootTime (#1249)
the previous implementation was adding the elapsed time since
boot to the current time instead of subtracting it
2024-09-05 10:35:29 +08:00
Yonas Yanfa 8371920c6b Doc: Fix grammer in README.md (#1248) [ci skip] 2024-09-05 08:48:17 +08:00
李通洲 c9d539090d Global: remove --lib-xxx support 2024-09-04 15:56:11 +08:00
李通洲 d43c6ffe27 OpenGL (macOS): support EGL (ANGLE) on macOS 2024-09-04 14:50:29 +08:00
李通洲 cf7c5d3cfa Logo (image-raw): better Windows support 2024-09-04 11:01:28 +08:00
李通洲 3f67fac4fa TerminalTheme: support Windows 2024-09-04 11:01:28 +08:00
Carter Li 879d5594da Packaging: update debian stuff [ci skip] 2024-09-04 08:53:16 +08:00
李通洲 32bf85742c Format: improve performance; fix formatArgSet for bool 2024-09-04 08:53:16 +08:00
李通洲 37cc2c9c1b Globals: use generic selection when passing format args 2024-09-04 08:53:16 +08:00
李通洲 c39df1ae7b Uptime: fix custom format of bootTime 2024-09-04 08:53:16 +08:00
李通洲 4622604ee1 Monitor: fix custom format of refreshRate 2024-09-04 08:53:16 +08:00
李通洲 617661b546 Wifi: fix signal quality printing in custom format
Fix #1241
2024-09-04 08:53:16 +08:00
李通洲 9aae274cc7 CI (Windows): build x86-64 binaries with imagemagick support 2024-09-03 21:43:08 +08:00
李通洲 90b2bf0ad6 InitSystem (Linux): fix dinit version parsing
Ref: https://github.com/fastfetch-cli/fastfetch/issues/1245#issuecomment-2326516448
2024-09-03 21:36:15 +08:00
李通洲 aec27c3e50 Image (Windows): support sixel protocol 2024-09-03 21:31:43 +08:00
李通洲 d79bf0a460 TerminalSize (Windows): support size in pixel detection 2024-09-03 21:31:09 +08:00
李通洲 352ed51504 InitSystem (FreeBSD): fix build 2024-09-03 20:29:43 +08:00
Carter Li d824045973 CMake: use system system yyjson in unit tests
Fix #1244
2024-09-03 20:11:28 +08:00
Carter Li bbe4988054 InitSystem (Linux): support dinit
Fix #1245
2024-09-03 20:03:53 +08:00
Carter Li 636126c57d Merge pull request #1239 from fastfetch-cli/dev
Release: v2.23.0
2024-09-03 10:34:07 +08:00
李通洲 2e475d590f JsonSchema: update zpool 2024-09-03 10:08:23 +08:00
李通洲 0cf45c1dcd Release: v2.23.0 2024-09-03 09:31:25 +08:00
李通洲 435516373d Logo (Image): better Windows support 2024-09-02 20:57:47 +08:00
李通洲 64735245e7 Presets: use string padding syntax
Fix #1237
2024-09-02 16:02:05 +08:00
李通洲 85d89395a9 Format: support syntax of padded string
Ref: #1237
2024-09-02 16:01:25 +08:00
李通洲 093940e504 Logo (Builtin): add Huawei Cloud EulerOS
Fix #1236
2024-09-02 09:36:57 +08:00
李通洲 e427a5112b Logo (Builtin): add small Steam Deck
Fix #1232
2024-09-02 09:31:14 +08:00
李通洲 1ab86a8ab9 TerminalTheme: fix hanging on screen 5.0 2024-09-02 09:26:54 +08:00
李通洲 99e0dc9aaa Zpool: don't break -DBINARY_LINK_TYPE=dynamic
Fix #1233
2024-08-31 12:44:35 +08:00
Carter Li 73e9db5b6e Zpool (SunOS): fix the dlsym error 2024-08-31 12:43:03 +08:00
Linus adc03bd792 Logo (Builtin): Add Steam Deck Logo (#1229)
* Logo (Builtin): Add Steam Deck Logo

* accidentally removed newline after steam deck oled block

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-30 22:06:10 +08:00
李通洲 10fdc8e4a7 Logo (Builtin): make ubuntu logo colorable 2024-08-30 12:13:33 +08:00
李通洲 d75803794e Terminal: improve performance of xfce4-terminal version 2024-08-30 12:13:33 +08:00
AIT MEDDOUR Fouad-Eddine d25ac86283 Logo (Builtin): Add Magix (#1228)
* Add Magix (Correctly this time)

* Update magix.txt

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-30 11:24:50 +08:00
李通洲 de8bbc9a5c Camera (FreeBSD): fix module was incorrectly disabled (v2) 2024-08-29 15:57:05 +08:00
Md. Iftakhar Awal Chowdhury 66977de5c7 Completion (Zsh): add completion for --logo-color-{1..9} (#1222) 2024-08-29 15:55:12 +08:00
李通洲 f828d3a9b9 Camera (FreeBSD): fix module was incorrectly disabled 2024-08-28 21:33:17 +08:00
李通洲 f0bc08e006 CI: run all modules on FreeBSD and SunOS 2024-08-28 21:14:54 +08:00
李通洲 e0f8e39a47 CI: add zpool 2024-08-28 20:56:59 +08:00
李通洲 8b9f787095 Zpool: fix build on SunOS 2024-08-28 20:56:23 +08:00
Carter Li d946cf27fe Zpool: add new module 2024-08-28 16:45:26 +08:00
Carter Li 5842ad1d56 Battery: print model name in key 2024-08-28 16:00:06 +08:00
Md. Iftakhar Awal Chowdhury 201047251d Completion: add optional completion support for certain flags (#1219) 2024-08-28 10:18:38 +08:00
李通洲 5c8e771939 Binary (Linux): fix building without libelf enabled 2024-08-28 09:41:08 +08:00
李通洲 b22e28b548 NetIO: don't print * if defaultRouteOnly is set 2024-08-27 21:36:57 +08:00
李通洲 8c51836a47 Logo (Builtin): update amogos 2024-08-27 21:18:25 +08:00
李通洲 df729938c5 Binary: improve performance 2024-08-27 16:41:23 +08:00
Carter Li 67d0dfcef0 DE (Linux): support unity version detection 2024-08-27 14:31:05 +08:00
李通洲 03c95e5cad Shell: improve performance of bash and zsh version detection 2024-08-27 14:06:45 +08:00
Md. Iftakhar Awal Chowdhury c0a07002f2 Completion: update zsh-completion to reflect latest upstream changes (#1217) 2024-08-26 17:39:49 +08:00
李通洲 5a9c3154fa IO (Unix): fix isDir condition checking; skip hidden files
Fix #1216
2024-08-26 16:10:44 +08:00
Carter Li e35aed761b Packaging: update debian stuff [ci skip] 2024-08-26 10:58:52 +08:00
178 changed files with 2251 additions and 1585 deletions
+5 -5
View File
@@ -388,8 +388,8 @@ jobs:
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch
time ./fastfetch --format json
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
@@ -426,8 +426,8 @@ jobs:
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch
time ./fastfetch --format json
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
@@ -456,7 +456,7 @@ jobs:
with:
msystem: CLANG64
update: true
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt mingw-w64-clang-x86_64-imagemagick
- name: print msys version
run: uname -a
+58
View File
@@ -1,3 +1,61 @@
# 2.24.0
Changes:
* Support of `--lib-XXX` is removed
* If fastfetch fails to load some `.so` `.dylib` libraries, `LD_LIBRARY_PATH` should be used.
Features:
* Support sixel image protocol on Windows (Logo, Windows)
* Requires imagemagick7 to be installed. MSYS2 is recommended.
* Improve terminal query on Windows (Windows)
* TerminalSize, TerminalTheme
* Detect more ARM microarchitectures and SOC names (CPU, Linux)
* Detect the number of online cores (CPU, FreeBSD)
* Support board name detection for Asahi Linux (Board, Linux)
* Add new option `--command-param` to customize the parameters when running shell
* Support syntax of sub string in `--<module>-format`: `{variable~startIndex,endIndex}`
* See `fastfetch -h format` for detail
Bugfixes:
* Fix tests building when system yyjson is used (#1244)
* Fix dinit detection; support dinit version detection (#1245, InitSystem, Linux)
* Fix signal quality, refresh rate and maybe others in custom format (#1241)
* Fix boot time calculation (#1249, Uptime, Linux)
* Fix custom format for boolean values
* `{?false-value}This should not print{?}{?true-value}This should print{?}` will print `This should print`
* Fix possible hanging when running fastfetch in screen 5.0 (TerminalTheme, macOS)
Logos:
* Add Lliurex
# 2.23.0
Features:
* Support unity version detection (DE, Linux)
* Print model name in Battery keys if available (Battery)
* Add module `Zpool`
* Improve performance (Shell / Terminal, Linux)
* Support syntax of padded strings in `--<module>-format`. `{variable<padlength}` and `{variable>padlength}` are supported.
* If pad length is greater than the length of the variable, the variable will be padded with spaces.
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1<20})'` prints `Command: output(12345 )`
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1>20})'` prints `Command: output( 12345)`
* If pad length is less than the length of the variable, the variable will be truncated.
Bugfixes:
* Fix broken `--list-presets`
* Update zsh completion script
* Don't print `*` if `defaultRouteOnly` is set (NetIO)
* Fix Camera module incorrectly disabled on FreeBSD (Camera, FreeBSD)
* Fix hanging on screen 5.0 (Terminal)
* Improve image logo support on Windows (Logo, Windows)
Logos:
* Update AmogOS
* Add Magix
* Make ubuntu logo colorable
* Add Steam Deck Logo
* add Huawei Cloud EulerOS
# 2.22.0
Features:
+48 -4
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.22.0
VERSION 2.24.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -69,8 +69,9 @@ cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR ANDROID" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
@@ -392,11 +393,11 @@ set(LIBFASTFETCH_SRC
src/modules/wifi/wifi.c
src/modules/wm/wm.c
src/modules/wmtheme/wmtheme.c
src/modules/zpool/zpool.c
src/options/display.c
src/options/modules.c
src/options/logo.c
src/options/general.c
src/options/library.c
src/util/edidHelper.c
src/util/base64.c
src/util/FFlist.c
@@ -481,6 +482,7 @@ if(LINUX)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -543,6 +545,7 @@ elseif(ANDROID)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/detection/camera/camera_android.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -622,6 +625,7 @@ elseif(FreeBSD)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -686,6 +690,7 @@ elseif(APPLE)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/detection/camera/camera_apple.m
src/detection/zpool/zpool_nosupport.c
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
src/util/platform/FFPlatform_unix.c
@@ -750,6 +755,7 @@ elseif(WIN32)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_windows.c
src/detection/camera/camera_windows.cpp
src/detection/zpool/zpool_nosupport.c
src/util/windows/getline.c
src/util/windows/com.cpp
src/util/windows/registry.c
@@ -832,6 +838,7 @@ elseif(SunOS)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_nosupport.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -1091,6 +1098,25 @@ ff_lib_enable(DIRECTX_HEADERS
"DirectX-Headers"
"DirectX-Headers"
)
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
if(ENABLE_LIBZFS)
if(BINARY_LINK_TYPE STREQUAL "dlopen")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
else()
set(CMAKE_REQUIRED_LIBRARIES_BACKUP ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} zfs)
check_function_exists("libzfs_init" LIBZFS_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_BACKUP})
if(NOT LIBZFS_FOUND)
message(STATUS "Library: missing: LIBZFS")
else()
message(STATUS "Library: found LIBZFS")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
target_link_libraries(libfastfetch PRIVATE zfs)
endif()
endif()
endif()
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
@@ -1153,6 +1179,8 @@ elseif(SunOS)
PRIVATE "socket"
PRIVATE "kstat"
PRIVATE "proc"
PRIVATE "zfs"
PRIVATE "nvpair"
)
elseif(ANDROID)
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
@@ -1196,11 +1224,16 @@ if(WIN32)
endif()
set(CMAKE_CXX_STANDARD 17)
endif()
if(LINUX)
if(FreeBSD)
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
endif()
if(LINUX OR FreeBSD)
CHECK_INCLUDE_FILE("linux/videodev2.h" HAVE_LINUX_VIDEODEV2)
if(HAVE_LINUX_VIDEODEV2)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
endif()
endif()
if(LINUX)
CHECK_INCLUDE_FILE("linux/wireless.h" HAVE_LINUX_WIRELESS)
if(HAVE_LINUX_WIRELESS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_WIRELESS=1)
@@ -1308,9 +1341,20 @@ if (BUILD_TESTS)
PRIVATE libfastfetch
)
add_executable(fastfetch-test-format
tests/format.c
)
target_link_libraries(fastfetch-test-format
PRIVATE libfastfetch
)
if(yyjson_FOUND)
target_compile_definitions(fastfetch-test-format PRIVATE FF_USE_SYSTEM_YYJSON)
endif()
enable_testing()
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
add_test(NAME test-list COMMAND fastfetch-test-list)
add_test(NAME test-format COMMAND fastfetch-test-format)
endif()
##################
+1 -1
View File
@@ -81,7 +81,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
## Usage
* Run it with default configuration: `fastfetch`
* Run it with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) and find what you interest: `fastfetch -c all.jsonc`
* Run it with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) and find what interests you: `fastfetch -c all.jsonc`
* Find all data that fastfetch detects: `fastfetch -s <module> --format json`
* Display help messages: `fastfetch --help`
* Generate config file based on command line arguments: `fastfetch --arg1 --arg2 --gen-config`
+32 -23
View File
@@ -3,9 +3,8 @@
function _fastfetch() {
local state
local -a opts
opts=(${(f)"$(
python <<EOF
local -a opts=("${(f)$(
python3 <<EOF
import json
import subprocess
import sys
@@ -18,15 +17,21 @@ def main():
for key in data:
for flag in data[key]:
if flag["long"] == "logo-color-[1-9]":
for i in range(1, 10):
command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
print_command(command_prefix, flag)
continue
if flag.get("pseudo", False):
continue
if "short" in flag:
command_prefix = f"""-{flag["short"]}[{flag["desc"]}]"""
command_prefix = f"-{flag["short"]}[{flag["desc"]}]"
print_command(command_prefix, flag)
if "long" in flag:
command_prefix = f"""--{flag["long"]}[{flag["desc"]}]"""
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
print_command(command_prefix, flag)
@@ -34,22 +39,22 @@ def print_command(command_prefix: str, flag: dict):
if "arg" in flag:
type: str = flag["arg"]["type"]
if type == "bool":
print(f"{command_prefix}:bool:(true false)")
print(f"{command_prefix}::bool:(true false)")
elif type == "color":
print(f"{command_prefix}:color:(black red green yellow blue magenta cyan white default)")
print(f"{command_prefix}:color:->colors")
elif type == "command":
print(f"{command_prefix}:module:->modules")
print(f"{command_prefix}::module:->modules")
elif type == "config":
print(f"{command_prefix}:presets:->presets")
print(f"{command_prefix}:preset:->presets")
elif type == "enum":
temp: str = " ".join(flag["arg"]["enum"])
print(f'{command_prefix}:type:( {temp} )')
print(f'{command_prefix}:type:({temp})')
elif type == "logo":
print(f"{command_prefix}:logo:->logo")
print(f"{command_prefix}:logo:->logos")
elif type == "structure":
print(f"{command_prefix}:structure:->structure")
print(f"{command_prefix}:structure:->structures")
elif type == "path":
print(f"{command_prefix}:path:_files -/")
print(f"{command_prefix}::path:_files")
else:
print(f"{command_prefix}:")
else:
@@ -62,30 +67,34 @@ if __name__ == "__main__":
except Exception:
sys.exit(1)
EOF
)"})
)}")
_arguments -C "$opts[@]"
_arguments "$opts[@]"
case $state in
colors)
local -a colors=(black red green yellow blue magenta cyan white default)
_describe 'color' colors
;;
modules)
local -a modules=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
modules=( ${(L)^modules%%:*}-format format color )
local -a modules=("${(f)$(fastfetch --list-modules autocompletion)}")
modules=(${(L)^modules[@]%%:*}-format format color)
_describe 'module' modules
;;
presets)
local -a presets=(
${$(fastfetch --list-presets autocompletion):#.*}
"${(f)$(fastfetch --list-presets autocompletion)}"
"none:Disable loading config file"
)
_describe 'preset' presets
_describe 'preset' presets || _files
;;
structure)
local -a structures=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
structures)
local -a structures=("${(f)$(fastfetch --list-modules autocompletion)}")
_describe 'structure' structures
;;
logo)
logos)
local -a logos=(
$(fastfetch --list-logos autocompletion)
"${(f)$(fastfetch --list-logos autocompletion)}"
"none:Don't print logo"
"small:Print small ascii logo if available"
)
+12
View File
@@ -1,3 +1,15 @@
fastfetch (2.23.0) jammy; urgency=medium
* Update to 2.23.0
-- Carter Li <zhangsongcui@live.cn> Tue, 03 Sep 2024 18:44:11 +0800
fastfetch (2.22.0) jammy; urgency=medium
* Update to 2.22.0
-- Carter Li <zhangsongcui@live.cn> Mon, 26 Aug 2024 18:53:35 +0800
fastfetch (2.21.3) jammy; urgency=medium
* Update to 2.21.3
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.21.3_source.buildinfo universe/utils optional
fastfetch_2.23.0_source.buildinfo universe/utils optional
+10 -108
View File
@@ -638,113 +638,6 @@
}
}
},
"library": {
"description": "Set the path of a library to load",
"type": "object",
"additionalProperties": false,
"properties": {
"vulkan": {
"type": "string",
"description": "Vulkan module & fallback for GPU output"
},
"freetype": {
"type": "string",
"description": "Used for Termux font detection (Android)"
},
"wayland": {
"type": "string",
"description": "Better display performance and output in wayland sessions.\nSupports different refresh rates per monitor.\n(Linux, FreeBSD)"
},
"xcbRandr": {
"type": "string",
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
},
"xcb": {
"type": "string",
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
},
"xrandr": {
"type": "string",
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
},
"x11": {
"type": "string",
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
},
"drm": {
"type": "string",
"description": "Used for fast resolution and refresh rate detection (Linux, FreeBSD)"
},
"gio": {
"type": "string",
"description": "Needed for values that are only stored GSettings (Linux, FreeBSD, SunOS)"
},
"dconf": {
"type": "string",
"description": "Needed for values that are only stored in DConf + Fallback for GSettings (Linux, FreeBSD, SunOS)"
},
"dbus": {
"type": "string",
"description": "Bluetooth, Player & Media detection (Linux, FreeBSD, SunOS)"
},
"xfconf": {
"type": "string",
"description": "Needed for XFWM theme and XFCE Terminal font (Linux, FreeBSD, SunOS)"
},
"sqlite3": {
"type": "string",
"description": "Needed for pkg & rpm package count (Linux, FreeBSD)"
},
"rpm": {
"type": "string",
"description": "Slower fallback for rpm package count. Needed on openSUSE & old CentOS / Redhat. (Linux)"
},
"imagemagick": {
"type": "string",
"description": "Images in terminal using sixel or kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)"
},
"z": {
"description": "Libz. Faster image output when using kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)",
"type": "string"
},
"chafa": {
"type": "string",
"description": "Image output as ascii art (Linux, FreeBSD, SunOS, macOS)"
},
"egl": {
"type": "string",
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS, Windows)"
},
"glx": {
"type": "string",
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)"
},
"osmesa": {
"type": "string",
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)"
},
"opencl": {
"type": "string",
"description": "OpenCL module (Linux, FreeBSD, SunOS, Windows)"
},
"pulse": {
"description": "Pulseaudio. Used for Sound detection (Linux, FreeBSD, SunOS)",
"type": "string"
},
"nm": {
"description": "NetworkManager. Used for Wifi detection (Linux)",
"type": "string"
},
"ddcutil": {
"description": "Used for brightness detection of external displays (Linux)",
"type": "string"
},
"elf": {
"description": "Used for st terminal font detection and systemd version detection (Linux)",
"type": "string"
}
}
},
"modules": {
"description": "Fastfetch modules to run",
"type": "array",
@@ -820,7 +713,8 @@
"weather",
"wm",
"wifi",
"wmtheme"
"wmtheme",
"zpool"
]
},
{
@@ -993,6 +887,10 @@
{
"const": "wmtheme",
"description": "Print current theme of window manager"
},
{
"const": "zpool",
"description": "Print ZFS storage pools"
}
]
},
@@ -1338,6 +1236,10 @@
"description": "Set the shell program to execute the command text\nDefault: cmd for Windows, /bin/sh for *nix",
"type": "string"
},
"param": {
"description": "Set the parameter used when starting the shell\nDefault: /c for Windows, -c for *nix",
"type": "string"
},
"text": {
"description": "Set the command text to be executed",
"type": "string"
+1
View File
@@ -54,6 +54,7 @@
"physicalmemory",
"swap",
"disk",
"zpool",
"battery",
"poweradapter",
"player",
+1
View File
@@ -56,6 +56,7 @@
"physicalmemory",
"swap",
"disk",
"zpool",
"battery",
"poweradapter",
"player",
+1 -2
View File
@@ -111,8 +111,7 @@
{
"type": "loadavg",
"compact": false,
// {duration} is not fixed length, hack it
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│{$1}"
"key": "│ LOAD {duration>2}m │{$1}" // pad duration to 2 chars
},
{
"type": "custom",
+4 -1
View File
@@ -25,7 +25,10 @@
"type": "disk",
"folders": "/"
},
"battery",
{
"type": "battery",
"key": "Battery"
},
{
"type": "colors",
"paddingLeft": 10,
+1 -1
View File
@@ -7,7 +7,7 @@
static bool loadLibSymbols(FFDBusLibrary* lib)
{
FF_LIBRARY_LOAD(dbus, &instance.config.library.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD(dbus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_append_args, false)
+143 -55
View File
@@ -8,39 +8,53 @@
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
{
if(formatarg->type == FF_FORMAT_ARG_TYPE_INT)
ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT)
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT64)
ffStrbufAppendF(buffer, "%" PRIu64, *(uint64_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16)
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8)
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRING)
ffStrbufAppendS(buffer, (const char*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRBUF)
ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_FLOAT)
ffStrbufAppendF(buffer, "%f", *(float*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_DOUBLE)
ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_BOOL)
ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
else if(formatarg->type == FF_FORMAT_ARG_TYPE_LIST)
switch(formatarg->type)
{
const FFlist* list = formatarg->value;
for(uint32_t i = 0; i < list->length; i++)
case FF_FORMAT_ARG_TYPE_INT:
ffStrbufAppendF(buffer, "%" PRIi32, *(int32_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT:
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT64:
ffStrbufAppendF(buffer, "%" PRIu64, *(uint64_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT16:
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT8:
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_STRING:
ffStrbufAppendS(buffer, (const char*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_STRBUF:
ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_FLOAT:
ffStrbufAppendF(buffer, "%f", *(float*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_DOUBLE:
ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_BOOL:
ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
break;
case FF_FORMAT_ARG_TYPE_LIST:
{
ffStrbufAppend(buffer, ffListGet(list, i));
if(i < list->length - 1)
ffStrbufAppendS(buffer, ", ");
const FFlist* list = formatarg->value;
for(uint32_t i = 0; i < list->length; i++)
{
ffStrbufAppend(buffer, ffListGet(list, i));
if(i < list->length - 1)
ffStrbufAppendS(buffer, ", ");
}
break;
}
}
else if(formatarg->type != FF_FORMAT_ARG_TYPE_NULL)
{
fprintf(stderr, "Error: format string \"%s\": argument is not implemented: %i\n", buffer->chars, formatarg->type);
default:
if(formatarg->type != FF_FORMAT_ARG_TYPE_NULL)
fprintf(stderr, "Error: format string \"%s\": argument is not implemented: %i\n", buffer->chars, formatarg->type);
break;
}
}
@@ -100,7 +114,8 @@ static inline bool formatArgSet(const FFformatarg* arg)
(arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_BOOL && arg->value != NULL)
(arg->type == FF_FORMAT_ARG_TYPE_BOOL && *(bool*)arg->value) ||
(arg->type == FF_FORMAT_ARG_TYPE_LIST && ((FFlist*)arg->value)->length > 0)
);
}
@@ -265,18 +280,18 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
int32_t truncLength = INT32_MAX;
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
if (pColon != NULL)
char* pSep = placeholderValue.chars;
char cSep = '\0';
while (*pSep && *pSep != ':' && *pSep != '<' && *pSep != '>' && *pSep != '~')
++pSep;
if (*pSep)
{
char* pEnd = NULL;
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
if (*pEnd != '\0')
{
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
*pColon = '\0';
cSep = *pSep;
*pSep = '\0';
}
else
{
pSep = NULL;
}
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
@@ -287,26 +302,99 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
if (index > numArgs)
{
if (pColon) *pColon = ':';
if (pSep) *pSep = cSep;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
bool ellipsis = false;
if (truncLength < 0)
if (!cSep)
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
else if (cSep == '~')
{
ellipsis = true;
truncLength = -truncLength;
}
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
uint32_t oldLength = buffer->length;
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
if (buffer->length - oldLength > (uint32_t) truncLength)
char* pEnd = NULL;
int32_t start = (int32_t) strtol(pSep + 1, &pEnd, 10);
if (start < 0)
start = (int32_t) tempString.length + start;
if (start >= 0 && (uint32_t) start < tempString.length)
{
if (*pEnd == '\0')
ffStrbufAppendNS(buffer, tempString.length - (uint32_t) start, &tempString.chars[start]);
else if (*pEnd == ',')
{
int32_t end = (int32_t) strtol(pEnd + 1, &pEnd, 10);
if (!*pEnd)
{
if (end < 0)
end = (int32_t) tempString.length + end;
if ((uint32_t) end > tempString.length)
end = (int32_t) tempString.length;
if (end > start)
ffStrbufAppendNS(buffer, (uint32_t) (end - start), &tempString.chars[start]);
}
}
}
if (*pEnd)
{
*pSep = cSep;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
}
else
{
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
ffStrbufTrimRightSpace(buffer);
if (ellipsis)
ffStrbufAppendS(buffer, "");
char* pEnd = NULL;
int32_t truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
if (*pEnd != '\0')
{
*pSep = cSep;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
bool ellipsis = false;
if (truncLength < 0)
{
ellipsis = true;
truncLength = -truncLength;
}
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
if (tempString.length == (uint32_t) truncLength)
ffStrbufAppend(buffer, &tempString);
else if (tempString.length > (uint32_t) truncLength)
{
if (cSep == ':')
{
ffStrbufSubstrBefore(&tempString, (uint32_t) truncLength);
ffStrbufTrimRightSpace(&tempString);
}
else
ffStrbufSubstrBefore(&tempString, (uint32_t) (!ellipsis? truncLength : truncLength - 1));
ffStrbufAppend(buffer, &tempString);
if (ellipsis)
ffStrbufAppendS(buffer, "");
}
else if (cSep == ':')
ffStrbufAppend(buffer, &tempString);
else
{
if (cSep == '<')
{
ffStrbufAppend(buffer, &tempString);
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
}
else
{
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
ffStrbufAppend(buffer, &tempString);
}
}
}
}
+18 -3
View File
@@ -2,7 +2,7 @@
#include "util/FFstrbuf.h"
typedef enum FFformatargtype
typedef enum FFformatArgType
{
FF_FORMAT_ARG_TYPE_NULL = 0,
FF_FORMAT_ARG_TYPE_UINT,
@@ -16,11 +16,26 @@ typedef enum FFformatargtype
FF_FORMAT_ARG_TYPE_DOUBLE,
FF_FORMAT_ARG_TYPE_LIST,
FF_FORMAT_ARG_TYPE_BOOL
} FFformatargtype;
} FFformatArgType;
#define FF_FORMAT_ARG(variable, var_name) { _Generic((variable), \
uint32_t: FF_FORMAT_ARG_TYPE_UINT, \
uint64_t: FF_FORMAT_ARG_TYPE_UINT64, \
uint16_t: FF_FORMAT_ARG_TYPE_UINT16, \
uint8_t: FF_FORMAT_ARG_TYPE_UINT8, \
int32_t: FF_FORMAT_ARG_TYPE_INT, \
char*: FF_FORMAT_ARG_TYPE_STRING, \
const char*: FF_FORMAT_ARG_TYPE_STRING, \
FFstrbuf: FF_FORMAT_ARG_TYPE_STRBUF, \
float: FF_FORMAT_ARG_TYPE_FLOAT, \
double: FF_FORMAT_ARG_TYPE_DOUBLE, \
FFlist: FF_FORMAT_ARG_TYPE_LIST, \
bool: FF_FORMAT_ARG_TYPE_BOOL \
), _Generic((variable), char*: (variable), const char*: (variable), default: &(variable) ), (var_name) }
typedef struct FFformatarg
{
FFformatargtype type;
FFformatArgType type;
const void* value;
const char* name; // argument name, must start with an alphabet
} FFformatarg;
+4 -3
View File
@@ -43,7 +43,6 @@ static void defaultConfig(void)
ffOptionsInitGeneral(&instance.config.general);
ffOptionsInitModules(&instance.config.modules);
ffOptionsInitDisplay(&instance.config.display);
ffOptionsInitLibrary(&instance.config.library);
}
void ffInitInstance(void)
@@ -148,7 +147,6 @@ static void destroyConfig(void)
ffOptionsDestroyGeneral(&instance.config.general);
ffOptionsDestroyModules(&instance.config.modules);
ffOptionsDestroyDisplay(&instance.config.display);
ffOptionsDestroyLibrary(&instance.config.library);
}
static void destroyState(void)
@@ -244,9 +242,12 @@ void ffListFeatures(void)
#if FF_HAVE_DDCUTIL
"libddcutil\n"
#endif
#if FF_HAVE_ELF
#if FF_HAVE_ELF || __sun || __FreeBSD__
"libelf\n"
#endif
#if FF_HAVE_LIBZFS
"libzfs\n"
#endif
#if FF_HAVE_DIRECTX_HEADERS
"Directx Headers\n"
#endif
+2 -2
View File
@@ -130,8 +130,8 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out);
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
FF_C_SCANF(2, 3)
const char* ffGetTerminalResponse(const char* request, const char* format, ...);
FF_C_SCANF(3, 4)
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...);
// Not thread safe!
bool ffSuppressIO(bool suppress);
+44 -17
View File
@@ -4,9 +4,13 @@
#include <fcntl.h>
#include <termios.h>
#include <poll.h>
#include <dirent.h>
#include <errno.h>
#ifndef __APPLE__
#include <poll.h>
#else
#include <sys/select.h>
#endif
#if FF_HAVE_WORDEXP
#include <wordexp.h>
@@ -140,7 +144,7 @@ void restoreTerm(void)
tcsetattr(ftty, TCSAFLUSH, &oldTerm);
}
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...)
{
if (ftty < 0)
{
@@ -161,20 +165,44 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
ffWriteFDData(ftty, strlen(request), request);
//Give the terminal some time to respond
#ifndef __APPLE__
if(poll(&(struct pollfd) { .fd = ftty, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
return "poll() timeout or failed";
return "poll(/dev/tty) timeout or failed";
#else
{
// On macOS, poll(/dev/tty) always returns immediately
// See also https://nathancraddock.com/blog/macos-dev-tty-polling/
fd_set rd;
FD_ZERO(&rd);
FD_SET(ftty, &rd);
if(select(ftty + 1, &rd, NULL, NULL, &(struct timeval) { .tv_sec = FF_IO_TERM_RESP_WAIT_MS / 1000, .tv_usec = (FF_IO_TERM_RESP_WAIT_MS % 1000) * 1000 }) <= 0)
return "select(/dev/tty) timeout or failed";
}
#endif
char buffer[512];
ssize_t bytesRead = read(ftty, buffer, sizeof(buffer) - 1);
if(bytesRead <= 0)
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
buffer[bytesRead] = '\0';
char buffer[1024];
size_t bytesRead = 0;
va_list args;
va_start(args, format);
vsscanf(buffer, format, args);
while (true)
{
ssize_t nRead = read(ftty, buffer + bytesRead, sizeof(buffer) - bytesRead - 1);
if (nRead <= 0)
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
bytesRead += (size_t) nRead;
buffer[bytesRead] = '\0';
int ret = vsscanf(buffer, format, args);
if (ret <= 0)
return "vsscanf(buffer, format, args) failed";
if (ret >= nParams)
break;
}
va_end(args);
return NULL;
@@ -232,12 +260,15 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
while((entry = readdir(dir)) != NULL)
{
if(entry->d_name[0] == '.') // skip hidden files
continue;
bool isDir = false;
#ifdef _DIRENT_HAVE_D_TYPE
#ifndef __sun
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
isDir = entry->d_type == DT_DIR;
else
#else
#endif
{
struct stat stbuf;
if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0)
@@ -245,12 +276,8 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
else
isDir = S_ISDIR(stbuf.st_mode);
}
#endif
if (isDir)
{
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
continue;
ffStrbufAppendS(folder, entry->d_name);
ffStrbufAppendC(folder, '/');
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
+22 -12
View File
@@ -205,7 +205,7 @@ void ffListFilesRecursively(const char* path, bool pretty)
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
}
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...)
{
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE;
@@ -256,20 +256,30 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
ReadConsoleInputW(hInput, &record, 1, &len);
}
char buffer[512];
DWORD bytes = 0;
ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL);
va_list args;
va_start(args, format);
char buffer[1024];
uint32_t bytesRead = 0;
while (true)
{
DWORD bytes = 0;
if (!ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL) || bytes == 0)
return "ReadFile() failed";
bytesRead += bytes;
buffer[bytesRead] = '\0';
int ret = vsscanf(buffer, format, args);
if (ret <= 0)
return "vsscanf(buffer, format, args) failed";
if (ret >= nParams)
break;
}
SetConsoleMode(hInput, inputMode);
if(bytes <= 0)
return "ReadFile() failed";
buffer[bytes] = '\0';
va_list args;
va_start(args, format);
vsscanf(buffer, format, args);
va_end(args);
return NULL;
+16 -16
View File
@@ -55,28 +55,28 @@ static void* libraryLoad(const char* path, int maxVersion)
return result;
}
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...)
void* ffLibraryLoad(const char* path, int maxVersion, ...)
{
if(userProvidedName != NULL && userProvidedName->length > 0)
return dlopen(userProvidedName->chars, FF_DLOPEN_FLAGS);
void* result = libraryLoad(path, maxVersion);
va_list defaultNames;
va_start(defaultNames, userProvidedName);
void* result = NULL;
while(result == NULL)
if (!result)
{
const char* path = va_arg(defaultNames, const char*);
if(path == NULL)
break;
va_list defaultNames;
va_start(defaultNames, maxVersion);
int maxVersion = va_arg(defaultNames, int);
result = libraryLoad(path, maxVersion);
do
{
const char* pathRest = va_arg(defaultNames, const char*);
if(pathRest == NULL)
break;
int maxVersionRest = va_arg(defaultNames, int);
result = libraryLoad(pathRest, maxVersionRest);
} while (!result);
va_end(defaultNames);
}
va_end(defaultNames);
return result;
}
+4 -4
View File
@@ -33,8 +33,8 @@ static inline void ffLibraryUnload(void** handle)
#define FF_LIBRARY_SYMBOL(symbolName) \
__typeof__(&symbolName) ff ## symbolName;
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
void* __attribute__((__cleanup__(ffLibraryUnload))) libraryObjectName = ffLibraryLoad(userLibraryName, __VA_ARGS__, NULL);\
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
void* __attribute__((__cleanup__(ffLibraryUnload))) libraryObjectName = ffLibraryLoad(__VA_ARGS__, NULL);\
if(libraryObjectName == NULL) \
return returnValue;
@@ -72,7 +72,7 @@ static inline void ffLibraryUnload(void** handle)
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
void* ffLibraryLoad(const char* path, int maxVersion, ...);
#else
@@ -81,7 +81,7 @@ void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
#define FF_LIBRARY_SYMBOL(symbolName) \
__typeof__(&symbolName) ff ## symbolName;
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
FF_MAYBE_UNUSED void* libraryObjectName = NULL; // Placeholder
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
+1
View File
@@ -169,6 +169,7 @@ static FFModuleBaseInfo* Y[] = {
};
static FFModuleBaseInfo* Z[] = {
(void*) &instance.config.modules.zpool,
NULL,
};
+2 -2
View File
@@ -51,8 +51,8 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 2, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex, "index"},
{FF_FORMAT_ARG_TYPE_STRBUF, &moduleArgs->keyIcon, "icon"},
FF_FORMAT_ARG(moduleIndex, "index"),
FF_FORMAT_ARG(moduleArgs->keyIcon, "icon"),
}));
ffStrbufWriteTo(&key, stdout);
}
+4 -4
View File
@@ -60,7 +60,7 @@ static const GSettingsData* getGSettingsData(void)
if (!data.inited)
{
data.inited = true;
FF_LIBRARY_LOAD(libgsettings, &instance.config.library.libGIO, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(libgsettings, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_lookup, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_has_key, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_new_full, NULL)
@@ -141,7 +141,7 @@ static const DConfData* getDConfData(void)
{
data.inited = true;
FF_LIBRARY_LOAD(libdconf, &instance.config.library.libDConf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2);
FF_LIBRARY_LOAD(libdconf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2);
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_read_full, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_new, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_dup_string, NULL)
@@ -218,7 +218,7 @@ static const XFConfData* getXFConfData(void)
if (!data.inited)
{
data.inited = true;
FF_LIBRARY_LOAD(libxfconf, &instance.config.library.libXFConf, NULL, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD(libxfconf, NULL, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_has_property, NULL)
@@ -292,7 +292,7 @@ static const SQLiteData* getSQLiteData(void)
if (!data.inited)
{
data.inited = true;
FF_LIBRARY_LOAD(libsqlite, &instance.config.library.libSQLite3, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(libsqlite, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_open_v2, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_prepare_v2, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_step, NULL)
+9 -178
View File
@@ -766,184 +766,6 @@
}
}
],
"Library path": [
{
"long": "lib-vulkan",
"desc": "Vulkan module & fallback for GPU output",
"arg": {
"type": "path"
}
},
{
"long": "lib-wayland",
"desc": "Better display performance and output in wayland sessions",
"arg": {
"type": "path"
}
},
{
"long": "lib-xcb-randr",
"desc": "X11 sessions for better display detection and faster WM detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-xcb",
"desc": "X11 sessions for better display detection and faster WM detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-xrandr",
"desc": "X11 sessions for better display detection and faster WM detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-x11",
"desc": "X11 sessions for better display detection and faster WM detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-drm",
"desc": "Used for fast resolution and refresh rate detection",
"remark": "Linux only",
"arg": {
"type": "path"
}
},
{
"long": "lib-gio",
"desc": "Needed for values that are only stored GSettings",
"arg": {
"type": "path"
}
},
{
"long": "lib-dconf",
"desc": "Needed for values that are only stored in DConf + Fallback for GSettings",
"arg": {
"type": "path"
}
},
{
"long": "lib-dbus",
"desc": "Bluetooth, Player & Media detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-xfconf",
"desc": "Needed for XFWM theme and XFCE Terminal font",
"arg": {
"type": "path"
}
},
{
"long": "lib-sqlite3",
"desc": "Needed for pkg & rpm package count",
"arg": {
"type": "path"
}
},
{
"long": "lib-rpm",
"desc": "Slower fallback for rpm package count",
"arg": {
"type": "path"
}
},
{
"long": "lib-imagemagick",
"desc": "Images in terminal using sixel or kitty graphics protocol",
"arg": {
"type": "path"
}
},
{
"long": "lib-z",
"desc": "Libz. Faster image output when using kitty graphics protocol",
"arg": {
"type": "path"
}
},
{
"long": "lib-chafa",
"desc": "Image output as ascii art",
"arg": {
"type": "path"
}
},
{
"long": "lib-egl",
"desc": "Needed by the OpenGL module for gl context creation",
"arg": {
"type": "path"
}
},
{
"long": "lib-glx",
"desc": "Needed by the OpenGL module for gl context creation",
"arg": {
"type": "path"
}
},
{
"long": "lib-osmesa",
"desc": "Needed by the OpenGL module for gl context creation",
"arg": {
"type": "path"
}
},
{
"long": "lib-opencl",
"desc": "OpenCL module",
"arg": {
"type": "path"
}
},
{
"long": "lib-pulse",
"desc": "Pulseaudio. Used for Sound detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-nm",
"desc": "NetworkManager. Used for Wifi detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-freetype",
"desc": "Used for Termux font detection",
"arg": {
"type": "path"
}
},
{
"long": "lib-ddcutil",
"desc": "Used for brightness detection of external displays",
"arg": {
"type": "path"
}
},
{
"long": "lib-elf",
"desc": "Used for st terminal font detection and systemd version detection",
"arg": {
"type": "path"
}
}
],
"Module specific": [
{
"long": "title-fqdn",
@@ -1554,6 +1376,15 @@
"default": "\"cmd\" for Windows; \"/bin/sh\" for *nix"
}
},
{
"long": "command-param",
"desc": "Set the parameter used when starting the shell",
"remark": "Due to the difference of how OSes handle command line parameters, Windows will parse whitespaces as param separators, while *nix will not",
"arg": {
"type": "str",
"default": "\"/c\" for Windows; \"-c\" for *nix"
}
},
{
"long": "command-key",
"desc": "Set the module key to display",
+8
View File
@@ -13,6 +13,14 @@ For example: "--title-format '{user-name:5}'" will truncate user name into 5-len
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
In 2.23.0 or newer, `<` or `>` can be specified instead of `:` to set a left or right padding.
For example: "--title-format '{user-name<20}'" will generate `<user-name> `;
"--title-format '{user-name>20}'" will generate ` <user-name>`
In 2.24.0 or newer, `{~startIndex,endIndex}` can be specified to slice a string. Negative index counts back from the end of the string.
If an index is omitted, 0 is used. For example, both `{~,0}` `{~0,}` and `{~,}` are same as `{~0,0}` and will always generate a empty string.
If `,endIndex` is omitted or greater than the length of the string, the length of string is used.
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
+1 -1
View File
@@ -10,7 +10,7 @@
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
{
// Actually bluetoothapis.dll, but it's missing on Windows 7
FF_LIBRARY_LOAD(bluetoothapis, NULL, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstDevice)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextDevice)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindDeviceClose)
@@ -54,7 +54,7 @@ static_assert(sizeof(BTH_LOCAL_RADIO_INFO) == 292, "BTH_LOCAL_RADIO_INFO should
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
{
// Actually bluetoothapis.dll, but it's missing on Windows 7
FF_LIBRARY_LOAD(bluetoothapis, NULL, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstRadio)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextRadio)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindRadioClose)
+16 -4
View File
@@ -6,9 +6,21 @@
const char* ffDetectBoard(FFBoardResult* board)
{
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->name);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_serial", "/sys/class/dmi/id/board_serial", &board->serial);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &board->vendor);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &board->version);
if (ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->name))
{
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_serial", "/sys/class/dmi/id/board_serial", &board->serial);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &board->vendor);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &board->version);
}
else if (ffReadFileBuffer("/proc/device-tree/compatible", &board->vendor))
{
// use model name as board name
uint32_t comma = ffStrbufFirstIndexC(&board->vendor, ',');
if (comma < board->vendor.length)
{
ffStrbufSetS(&board->name, board->vendor.chars + comma + 1);
ffStrbufSubstrBefore(&board->vendor, comma);
}
}
return NULL;
}
+1 -1
View File
@@ -101,7 +101,7 @@ DDCA_Status ddca_init(const char *libopts, int syslog_level, int opts);
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
{
FF_LIBRARY_LOAD(libddcutil, &instance.config.library.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
FF_LIBRARY_LOAD(libddcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
@@ -39,7 +39,7 @@ static const char* detectWithWmi(FFlist* result)
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist* result)
{
FF_LIBRARY_LOAD(dxva2, NULL, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD(dxva2, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetPhysicalMonitorsFromHMONITOR)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetMonitorBrightness)
+2 -2
View File
@@ -21,9 +21,9 @@ private:
extern "C"
const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
{
FF_LIBRARY_LOAD(mfplat, NULL, "dlopen mfplat" FF_LIBRARY_EXTENSION " failed", "mfplat" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD(mfplat, "dlopen mfplat" FF_LIBRARY_EXTENSION " failed", "mfplat" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(mfplat, MFCreateAttributes)
FF_LIBRARY_LOAD(mf, NULL, "dlopen mf" FF_LIBRARY_EXTENSION " failed", "mf" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD(mf, "dlopen mf" FF_LIBRARY_EXTENSION " failed", "mf" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(mf, MFEnumDeviceSources)
const char* error = ffInitCom();
+14 -1
View File
@@ -37,6 +37,19 @@ const char* ffCPUAppleCodeToName(uint32_t code)
case 6031:
case 6034: return "Apple M3 Max";
case 8132: return "Apple M4";
default: return "Apple Silicon";
default: return NULL;
}
}
const char* ffCPUQualcommCodeToName(uint32_t code)
{
// https://github.com/AsahiLinux/docs/wiki/Codenames
switch (code)
{
case 7180: return "Qualcomm Snapdragon 7c";
case 7280: return "Qualcomm Snapdragon 7c+ Gen 3";
case 8180: return "Qualcomm Snapdragon 8cx Gen 2 5G";
case 8280: return "Qualcomm Snapdragon 8cx Gen 3";
default: return NULL;
}
}
+1 -1
View File
@@ -30,7 +30,7 @@ typedef struct FFCPUResult
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
const char* ffCPUAppleCodeToName(uint32_t code);
const char* ffCPUQualcommCodeToName(uint32_t code);
#if defined(__x86_64__) || defined(__i386__)
+3
View File
@@ -106,6 +106,9 @@ static const char* armPartId2name(uint32_t partId)
case 0xd80: return "Cortex-A520";
case 0xd81: return "Cortex-A720";
case 0xd82: return "Cortex-X4";
case 0xd84: return "Neoverse-V3";
case 0xd85: return "Cortex-X925";
case 0xd87: return "Cortex-A725";
default: return NULL;
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
cpu->coresLogical = cpu->coresPhysical;
cpu->coresOnline = cpu->coresPhysical;
cpu->coresOnline = (uint16_t) ffSysctlGetInt("kern.smp.cpus", cpu->coresLogical);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0)
+51 -17
View File
@@ -15,6 +15,8 @@
static void detectQualcomm(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips
if (ffStrbufEqualS(&cpu->name, "SM8635"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8s Gen 3 [SM8635]");
else if (ffStrbufEqualS(&cpu->name, "SM8650-AC"))
@@ -32,6 +34,8 @@ static void detectQualcomm(FFCPUResult* cpu)
else if (ffStrbufEqualS(&cpu->name, "SM7675"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7+ Gen 3 [SM7675]");
else if (ffStrbufEqualS(&cpu->name, "SM7635"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7s Gen 3 [SM7635]");
else if (ffStrbufEqualS(&cpu->name, "SM7550"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7 Gen 3 [SM7550]");
else if (ffStrbufEqualS(&cpu->name, "SM7475"))
@@ -43,6 +47,10 @@ static void detectQualcomm(FFCPUResult* cpu)
else if (ffStrbufEqualS(&cpu->name, "SM6375-AC"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6s Gen 3 [SM6375-AC]");
else if (ffStrbufEqualS(&cpu->name, "SM6475"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6 Gen 3 [SM6475]");
else if (ffStrbufEqualS(&cpu->name, "SM6115"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6s Gen 1 [SM6115]");
else if (ffStrbufEqualS(&cpu->name, "SM6450"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6 Gen 1 [SM6450]");
@@ -311,25 +319,51 @@ FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
}
}
FF_MAYBE_UNUSED static void detectAsahi(FFCPUResult* cpu)
FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
{
// In Asahi Linux, reading /proc/device-tree/compatible gives
// information on the device model. It consists of 3 NUL terminated
// strings, the second of which gives the actual SoC model. But it
// is not the marketing name, i.e. for M2 there is "apple,t8112" in
// the compatible string.
if (cpu->name.length == 0 && ffStrbufEqualS(&cpu->vendor, "Apple"))
{
char content[32];
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
if (length <= 0) return;
if (cpu->name.length > 0)
return;
// get the second NUL terminated string
char* modelName = memchr(content, '\0', (size_t) length) + 1;
if (modelName - content < length && ffStrStartsWith(modelName, "apple,t"))
// device-vendor,device-model\0soc-vendor,soc-model\0
char content[64];
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
if (length <= 2) return;
// get the second NUL terminated string
char* modelName = memchr(content, '\0', (size_t) length) + 1;
if (!modelName || modelName - content >= length) return;
if (ffStrStartsWith(modelName, "apple,t"))
{
// https://elixir.bootlin.com/linux/v6.11-rc7/source/arch/arm64/boot/dts/apple
const char* code = modelName + strlen("apple,t");
uint32_t deviceId = (uint32_t) strtoul(code, NULL, 10);
ffStrbufSetStatic(&cpu->name, ffCPUAppleCodeToName(deviceId));
if (!cpu->name.length)
{
uint32_t deviceId = (uint32_t) strtoul(modelName + strlen("apple,t"), NULL, 10);
ffStrbufSetStatic(&cpu->name, ffCPUAppleCodeToName(deviceId));
ffStrbufAppendS(&cpu->name, "Apple Silicon T");
ffStrbufAppendS(&cpu->name, code);
}
}
else if (ffStrStartsWith(modelName, "qcom,"))
{
// https://elixir.bootlin.com/linux/v6.11-rc7/source/arch/arm64/boot/dts/qcom
if (ffStrStartsWith(modelName + strlen("qcom,"), "x"))
{
ffStrbufSetS(&cpu->name, "Qualcomm Snapdragon X Elite ");
for (const char* p = modelName + strlen("qcom,"); *p; ++p)
ffStrbufAppendC(&cpu->name, (char) toupper(*p));
}
else if (ffStrStartsWith(modelName + strlen("qcom,"), "sc"))
{
const char* code = modelName + strlen("qcom,sc");
uint32_t deviceId = (uint32_t) strtoul(code, NULL, 10);
ffStrbufSetStatic(&cpu->name, ffCPUQualcommCodeToName(deviceId));
if (!cpu->name.length)
{
ffStrbufAppendS(&cpu->name, "Qualcomm Snapdragon SC");
ffStrbufAppendS(&cpu->name, code);
}
}
}
}
@@ -384,7 +418,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
#if __ANDROID__
detectAndroid(cpu);
#elif __aarch64__
detectAsahi(cpu);
detectArmSoc(cpu);
#endif
if (cpu->name.length == 0)
+9 -1
View File
@@ -121,7 +121,7 @@ static const char* getXfce4ByLib(FFstrbuf* result)
{
#ifndef FF_DISABLE_DLOPEN
const char* xfce_version_string(void); // from `xfce4/libxfce4util/xfce-misutils.h
FF_LIBRARY_LOAD(xfce4util, NULL, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
FF_LIBRARY_LOAD(xfce4util, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xfce4util, xfce_version_string);
ffStrbufSetS(result, ffxfce_version_string());
return NULL;
@@ -178,6 +178,12 @@ static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
}
static void getUnity(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
if (ffParsePropFile("/usr/bin/unity", "parser = OptionParser(version= \"%prog ", result))
ffStrbufSubstrBeforeFirstC(result, '"');
}
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
{
if (!instance.config.general.detectVersion) return "Disabled by config";
@@ -196,6 +202,8 @@ const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOpti
getLXQt(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
getBudgie(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_UNITY))
getUnity(result, options);
else
return "Unsupported DE";
return NULL;
@@ -9,13 +9,13 @@ bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName);
const char* ffdsConnectWayland(FFDisplayServerResult* result);
void ffdsConnectXcbRandr(FFDisplayServerResult* result);
void ffdsConnectXcb(FFDisplayServerResult* result);
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result);
const char* ffdsConnectXcb(FFDisplayServerResult* result);
void ffdsConnectXrandr(FFDisplayServerResult* result);
void ffdsConnectXlib(FFDisplayServerResult* result);
const char* ffdsConnectXrandr(FFDisplayServerResult* result);
const char* ffdsConnectXlib(FFDisplayServerResult* result);
void ffdsConnectDrm(FFDisplayServerResult* result);
const char* ffdsConnectDrm(FFDisplayServerResult* result);
void ffdsDetectWMDE(FFDisplayServerResult* result);
+6 -4
View File
@@ -199,7 +199,7 @@ static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen libdrm" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD(libdrm, "dlopen libdrm" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmGetDevices)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetResources)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetConnectorCurrent)
@@ -376,17 +376,19 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
#endif
void ffdsConnectDrm(FFDisplayServerResult* result)
const char* ffdsConnectDrm(FFDisplayServerResult* result)
{
#ifdef FF_HAVE_DRM
if (instance.config.general.dsForceDrm != FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY)
{
if (drmConnectLibdrm(result) == NULL)
return;
return NULL;
}
#endif
#ifdef __linux__
drmParseSysfs(result);
return drmParseSysfs(result);
#endif
return "fastfetch was compiled without drm support";
}
@@ -150,7 +150,7 @@ const char* ffdsConnectWayland(FFDisplayServerResult* result)
if (getenv("XDG_RUNTIME_DIR") == NULL)
return "Wayland requires $XDG_RUNTIME_DIR being set";
FF_LIBRARY_LOAD(wayland, &instance.config.library.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD(wayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wayland, wl_display_connect)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wayland, wl_display_get_fd)
+7
View File
@@ -238,6 +238,13 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
ffStrbufSetS(&result->deProcessName, "ukui-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UKUI);
}
else if(
ffStrStartsWithIgnCase(name, "Unity:Unity")
) {
ffStrbufSetS(&result->deProcessName, "unity-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UNITY);
}
}
+45 -39
View File
@@ -82,21 +82,21 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
ffStrbufSetS(&result->wmProcessName, wmName);
}
void ffdsConnectXcb(FFDisplayServerResult* result)
const char* ffdsConnectXcb(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(xcb, &instance.config.library.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,)
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,)
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,)
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_screen_next,)
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_disconnect,)
FF_LIBRARY_LOAD(xcb, "dlopen lbxcb failed", "libxcb" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_connect)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_get_setup)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_setup_roots_iterator)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_screen_next)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_disconnect)
XcbPropertyData propertyData;
bool propertyDataInitialized = xcbInitPropertyData(xcb, &propertyData);
xcb_connection_t* connection = ffxcb_connect(NULL, NULL);
if(connection == NULL)
return;
return "xcb_connect failed";
xcb_screen_iterator_t iterator = ffxcb_setup_roots_iterator(ffxcb_get_setup(connection));
@@ -128,14 +128,17 @@ void ffdsConnectXcb(FFDisplayServerResult* result)
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
if(result->wmProtocolName.length == 0)
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
return NULL;
}
#else
void ffdsConnectXcb(FFDisplayServerResult* result)
const char* ffdsConnectXcb(FFDisplayServerResult* result)
{
//Do nothing. There are other implementations coming
FF_UNUSED(result)
return "Fastfetch was compiled without XCB support";
}
#endif
@@ -388,45 +391,45 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
);
}
void ffdsConnectXcbRandr(FFDisplayServerResult* result)
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(xcbRandr, &instance.config.library.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,)
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,)
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,)
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_screen_next,)
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_disconnect,)
FF_LIBRARY_LOAD(xcbRandr, "dlopen lbxcb-randr failed", "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_connect)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_get_setup)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_setup_roots_iterator)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_screen_next)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_disconnect)
XcbRandrData data;
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_modes_iterator,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_mode_info_next,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_monitors_iterator,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_next,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_outputs_length,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_outputs,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_output_next,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_data,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_data_length,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info_reply,)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_intern_atom)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_intern_atom_reply)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_screen_resources_current)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_screen_resources_current_reply)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_screen_resources_current_modes_iterator)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_mode_info_next)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_monitors)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_monitors_reply)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_monitors_monitors_iterator)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_monitor_info_next)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_monitor_info_outputs_length)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_monitor_info_outputs)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_output_next)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_info)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_info_reply)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property_reply)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property_data)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property_data_length)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_crtc_info)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_crtc_info_reply)
bool propertyDataInitialized = xcbInitPropertyData(xcbRandr, &data.propData);
data.connection = ffxcb_connect(NULL, NULL);
if(data.connection == NULL)
return;
return "xcb_connect failed";
data.result = result;
@@ -450,14 +453,17 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
if(result->wmProtocolName.length == 0)
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
return NULL;
}
#else
void ffdsConnectXcbRandr(FFDisplayServerResult* result)
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
{
//Do nothing. There are other implementations coming
FF_UNUSED(result)
return "Fastfetch was compiled without libxcb-randr support";
}
#endif
+30 -24
View File
@@ -58,18 +58,18 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl
data->ffXFree(wmWindow);
}
void ffdsConnectXlib(FFDisplayServerResult* result)
const char* ffdsConnectXlib(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(x11, &instance.config.library.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,)
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,)
FF_LIBRARY_LOAD(x11, "dlopen libX11 failed", "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(x11, XOpenDisplay)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(x11, XCloseDisplay)
X11PropertyData propertyData;
bool propertyDataInitialized = x11InitPropertyData(x11, &propertyData);
Display* display = ffXOpenDisplay(x11);
if(display == NULL)
return;
return "XOpenDisplay failed";
if(propertyDataInitialized && ScreenCount(display) > 0)
x11DetectWMFromEWMH(&propertyData, display, result);
@@ -98,14 +98,17 @@ void ffdsConnectXlib(FFDisplayServerResult* result)
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
if(result->wmProtocolName.length == 0)
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
return NULL;
}
#else
void ffdsConnectXlib(FFDisplayServerResult* result)
const char* ffdsConnectXlib(FFDisplayServerResult* result)
{
//Do nothing. WM / DE detection will use environment vars to detect as much as possible.
FF_UNUSED(result);
return "Fastfetch was compiled without libX11 support";
}
#endif //FF_HAVE_X11
@@ -308,34 +311,34 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
);
}
void ffdsConnectXrandr(FFDisplayServerResult* result)
const char* ffdsConnectXrandr(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(xrandr, &instance.config.library.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3)
FF_LIBRARY_LOAD(xrandr, "dlopen libXrandr failed", "libXrandr" FF_LIBRARY_EXTENSION, 3)
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,)
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XOpenDisplay)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XCloseDisplay)
XrandrData data;
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XFree,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetMonitors,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResourcesCurrent,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputInfo,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputProperty,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetCrtcInfo,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeCrtcInfo,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeOutputInfo,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeScreenResources,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeMonitors,);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XInternAtom);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XGetAtomName);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XFree);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetMonitors);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetScreenResourcesCurrent);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetOutputInfo);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetOutputProperty);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetCrtcInfo);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeCrtcInfo);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeOutputInfo);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeScreenResources);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeMonitors);
X11PropertyData propertyData;
bool propertyDataInitialized = x11InitPropertyData(xrandr, &propertyData);
data.display = ffXOpenDisplay(NULL);
if(data.display == NULL)
return;
return "XOpenDisplay() failed";
if(propertyDataInitialized && ScreenCount(data.display) > 0)
x11DetectWMFromEWMH(&propertyData, data.display, result);
@@ -350,14 +353,17 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
if(result->wmProtocolName.length == 0)
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
return NULL;
}
#else
void ffdsConnectXrandr(FFDisplayServerResult* result)
const char* ffdsConnectXrandr(FFDisplayServerResult* result)
{
//Do nothing here. There are more x11 implementations to come.
FF_UNUSED(result);
return "Fastfetch was compiled without libXrandr support";
}
#endif // FF_HAVE_XRANDR
+6 -9
View File
@@ -14,26 +14,23 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso
}
#endif
static bool extractNvimVersionFromBinary(const char* str, uint32_t len, void* userdata)
static bool extractNvimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (len < strlen("NVIM v0.0.0")) return true;
if (!ffStrStartsWith(str, "NVIM v")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
return false;
}
static bool extractVimVersionFromBinary(const char* str, uint32_t len, void* userdata)
static bool extractVimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (len < strlen("VIM - Vi IMproved 0.0")) return true;
if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved "));
ffStrbufSubstrBeforeFirstC(userdata, ' ');
return false;
}
static bool extractNanoVersionFromBinary(const char* str, uint32_t len, void* userdata)
static bool extractNanoVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (len < strlen("GNU nano 0.0")) return true;
if (!ffStrStartsWith(str, "GNU nano ")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
return false;
@@ -97,11 +94,11 @@ const char* ffDetectEditor(FFEditorResult* result)
if (!instance.config.general.detectVersion) return NULL;
if (ffStrbufEqualS(&result->exe, "nvim"))
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version);
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version, (uint32_t) strlen("NVIM v0.0.0"));
else if (ffStrbufEqualS(&result->exe, "vim"))
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version);
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
else if (ffStrbufEqualS(&result->exe, "nano"))
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version);
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
if (result->version.length > 0) return NULL;
+1 -1
View File
@@ -17,7 +17,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
if (!inited)
{
inited = true;
FF_LIBRARY_LOAD(libags, NULL, "dlopen amd_ags failed", soName , 1);
FF_LIBRARY_LOAD(libags, "dlopen amd_ags failed", soName , 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsInitialize)
struct AGSContext* apiHandle;
+1 -1
View File
@@ -34,7 +34,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
if (!igclData.inited)
{
igclData.inited = true;
FF_LIBRARY_LOAD(libigcl, NULL, "dlopen igcl (ControlLib) failed", soName , 1);
FF_LIBRARY_LOAD(libigcl, "dlopen igcl (ControlLib) failed", soName , 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libigcl, ctlInit)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlClose)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumerateDevices)
+2
View File
@@ -407,6 +407,8 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
gpu->deviceId = strtoul(buffer->chars + index, NULL, 10);
ffStrbufInitStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
if (!gpu->name.length)
ffStrbufAppendF(&gpu->name, "Apple Silicon T%u", (uint32_t) gpu->deviceId);
ffStrbufInitStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
ffStrbufInit(&gpu->driver);
ffStrbufInitF(&gpu->platformApi, "DRM (%s)", drmKey);
+1 -1
View File
@@ -41,7 +41,7 @@ const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDrive
if (!mtmlData.inited)
{
mtmlData.inited = true;
FF_LIBRARY_LOAD(libmtml, NULL, "dlopen mtml failed", soName, 1);
FF_LIBRARY_LOAD(libmtml, "dlopen mtml failed", soName, 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex)
+1 -1
View File
@@ -26,7 +26,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
if (!nvmlData.inited)
{
nvmlData.inited = true;
FF_LIBRARY_LOAD(libnvml, NULL, "dlopen nvml failed", soName , 1);
FF_LIBRARY_LOAD(libnvml, "dlopen nvml failed", soName , 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlInit_v2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlShutdown)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetCount_v2)
+1 -1
View File
@@ -28,7 +28,7 @@ private:
extern "C"
const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
{
FF_LIBRARY_LOAD(libdxcore, nullptr, "dlopen libdxcore.so failed", "/usr/lib/wsl/lib/libdxcore" FF_LIBRARY_EXTENSION, 4)
FF_LIBRARY_LOAD(libdxcore, "dlopen libdxcore.so failed", "/usr/lib/wsl/lib/libdxcore" FF_LIBRARY_EXTENSION, 4)
// DXCoreCreateAdapterFactory is a reloaded function, so we can't use FF_LIBRARY_LOAD_SYMBOL_MESSAGE here
typedef HRESULT (*DXCoreCreateAdapterFactory_t)(REFIID riid, void** ppvFactory);
+28 -12
View File
@@ -1,20 +1,19 @@
#include "initsystem.h"
#include "common/processing.h"
#include "util/binary.h"
#include "util/stringUtils.h"
#include <libgen.h>
#include <unistd.h>
FF_MAYBE_UNUSED static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* data)
FF_MAYBE_UNUSED static bool extractSystemdVersion(const char* str, uint32_t len, void* userdata)
{
if (len > strlen("systemd 0.0 running in ") && memcmp(str, "systemd ", strlen("systemd ")) == 0)
{
const char* pend = memmem(str + strlen("systemd "), len - strlen("systemd "), " running in ", strlen(" running in "));
if (pend)
{
ffStrbufSetNS((FFstrbuf*) data, (uint32_t) (pend - str) - (uint32_t) strlen("systemd "), str + strlen("systemd "));
return false;
}
}
return true;
if (!ffStrStartsWith(str, "systemd ")) return true;
const char* pstart = str + strlen("systemd ");
const char* pend = memmem(pstart, len - strlen("systemd "), " running in ", strlen(" running in "));
if (!pend) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (pend - pstart), pstart);
return false;
}
const char* ffDetectInitSystem(FFInitSystemResult* result)
@@ -41,7 +40,10 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
// In some old system, /sbin/init is a symlink
char buf[PATH_MAX];
if (realpath(result->exe.chars, buf))
{
ffStrbufSetS(&result->exe, buf);
ffStrbufSetS(&result->name, basename(result->exe.chars));
}
}
if (instance.config.general.detectVersion)
@@ -49,7 +51,7 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
#if __linux__ && !__ANDROID__
if (ffStrbufEqualS(&result->name, "systemd"))
{
ffBinaryExtractStrings(result->exe.chars, elfExtractStringsCallBack, &result->version);
ffBinaryExtractStrings(result->exe.chars, extractSystemdVersion, &result->version, (uint32_t) strlen("systemd 0.0 running in x"));
if (result->version.length == 0)
{
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
@@ -68,6 +70,20 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
}
}
}
else if (ffStrbufEqualS(&result->name, "dinit"))
{
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
ffStrbufEndsWithS(&result->exe, "/dinit") ? result->exe.chars : "dinit",
"--version",
NULL,
}) == NULL && result->version.length)
{
// Dinit version 0.18.0.
ffStrbufSubstrBeforeFirstC(&result->version, '\n');
ffStrbufTrimRight(&result->version, '.');
ffStrbufSubstrAfterLastC(&result->version, ' ');
}
}
#elif __APPLE__
if (ffStrbufEqualS(&result->name, "launchd"))
{
+1 -1
View File
@@ -54,7 +54,7 @@ static const char* getSshdVersion(FFstrbuf* version)
static const char* getSddmVersion(FFstrbuf* version)
{
FF_LIBRARY_LOAD(zlib, &instance.config.library.libZ, "dlopen libz failed", "libz" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD(zlib, "dlopen libz failed", "libz" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzopen)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzread)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzerror)
+1 -1
View File
@@ -5,7 +5,7 @@
static const char* getMedia(FFMediaResult* media)
{
FF_LIBRARY_LOAD(libffwinrt, NULL, "dlopen libffwinrt" FF_LIBRARY_EXTENSION " failed", "libffwinrt" FF_LIBRARY_EXTENSION, 0)
FF_LIBRARY_LOAD(libffwinrt, "dlopen libffwinrt" FF_LIBRARY_EXTENSION " failed", "libffwinrt" FF_LIBRARY_EXTENSION, 0)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libffwinrt, ffWinrtDetectMedia)
libffwinrt = NULL; // Don't close libffwinrt or it may crash
+1 -1
View File
@@ -135,7 +135,7 @@ static const char* xrandrHandleMonitors(XrandrData* data, Screen* screen, FFlist
static const char* detectByXrandr(FFlist* results)
{
FF_LIBRARY_LOAD(xrandr, &instance.config.library.libXrandr, "dlopen libXrandr" FF_LIBRARY_EXTENSION " failed", "libXrandr" FF_LIBRARY_EXTENSION, 3)
FF_LIBRARY_LOAD(xrandr, "dlopen libXrandr" FF_LIBRARY_EXTENSION " failed", "libXrandr" FF_LIBRARY_EXTENSION, 3)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XOpenDisplay)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XCloseDisplay)
+1 -1
View File
@@ -148,7 +148,7 @@ static const char* detectOpenCL(FFOpenCLResult* result)
#ifndef __APPLE__
FF_LIBRARY_LOAD(opencl, &instance.config.library.libOpenCL, "dlopen libOpenCL" FF_LIBRARY_EXTENSION" failed",
FF_LIBRARY_LOAD(opencl, "dlopen libOpenCL" FF_LIBRARY_EXTENSION" failed",
#ifdef _WIN32
"OpenCL"FF_LIBRARY_EXTENSION, -1,
#endif
+18 -1
View File
@@ -34,7 +34,7 @@ static const char* cglHandlePixelFormat(FFOpenGLResult* result, CGLPixelFormatOb
return error;
}
const char* ffDetectOpenGL(FF_MAYBE_UNUSED FFOpenGLOptions* options, FFOpenGLResult* result)
const char* cglDetectOpenGL(FFOpenGLResult* result)
{
CGLPixelFormatObj pixelFormat;
CGLPixelFormatAttribute attrs[] = {
@@ -51,3 +51,20 @@ const char* ffDetectOpenGL(FF_MAYBE_UNUSED FFOpenGLOptions* options, FFOpenGLRes
CGLDestroyPixelFormat(pixelFormat);
return error;
}
const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result)
{
if (options->library == FF_OPENGL_LIBRARY_AUTO)
return cglDetectOpenGL(result);
else if (options->library == FF_OPENGL_LIBRARY_EGL)
{
#if __has_include(<EGL/egl.h>)
const char* ffOpenGLDetectByEGL(FFOpenGLResult* result);
return ffOpenGLDetectByEGL(result);
#else
return "fastfetch was compiled without egl support";
#endif
}
else
return "Unsupported OpenGL library";
}
+2 -2
View File
@@ -120,7 +120,7 @@ static const char* detectByGlx(FFOpenGLResult* result)
{
GLXData data;
FF_LIBRARY_LOAD(glx, &instance.config.library.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(glx, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXQueryVersion);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay);
@@ -189,7 +189,7 @@ static const char* detectByOsMesa(FFOpenGLResult* result)
{
OSMesaData data;
FF_LIBRARY_LOAD(osmesa, &instance.config.library.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8);
FF_LIBRARY_LOAD(osmesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent);
+4 -9
View File
@@ -74,14 +74,8 @@ static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data)
static const char* eglHandleDisplay(FFOpenGLResult* result, EGLData* data)
{
if(data->ffeglBindAPI(
#ifdef _WIN32
EGL_OPENGL_ES_API
#else
EGL_OPENGL_API
#endif
) != EGL_TRUE)
return "eglBindAPI returned EGL_FALSE";
// try use OpenGL API. If failed, use the default API (usually OpenGL ES)
data->ffeglBindAPI(EGL_OPENGL_API);
EGLint eglConfigCount;
data->ffeglGetConfigs(data->display, &data->config, 1, &eglConfigCount);
@@ -121,11 +115,12 @@ static const char* eglHandleData(FFOpenGLResult* result, EGLData* data)
return error;
}
const char* ffOpenGLDetectByEGL(FFOpenGLResult* result)
{
EGLData eglData;
FF_LIBRARY_LOAD(egl, &instance.config.library.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(egl, "dlopen libEGL" FF_LIBRARY_EXTENSION " failed", "libEGL" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglQueryString);
+1 -1
View File
@@ -81,7 +81,7 @@ static LRESULT CALLBACK wglHandleWndProc(HWND hWnd, UINT message, WPARAM wParam,
static const char* wglDetectOpenGL(FFOpenGLResult* result)
{
FF_LIBRARY_LOAD(opengl32, NULL, "dlopen opengl32" FF_LIBRARY_EXTENSION " failed", "opengl32" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(opengl32, "dlopen opengl32" FF_LIBRARY_EXTENSION " failed", "opengl32" FF_LIBRARY_EXTENSION, 1);
WGLData data = { .result = result };
+9
View File
@@ -132,6 +132,15 @@ static void getUbuntuFlavour(FFOSResult* result)
ffStrbufSetS(&result->idLike, "ubuntu");
return;
}
if(ffStrContains(xdgConfigDirs, "lliurex"))
{
ffStrbufSetS(&result->name, "LliureX");
ffStrbufSetS(&result->prettyName, "LliureX");
ffStrbufSetS(&result->id, "lliurex");
ffStrbufSetS(&result->idLike, "ubuntu");
return;
}
}
static void getDebianVersion(FFOSResult* result)
+1 -1
View File
@@ -31,7 +31,7 @@ PWSTR WINAPI BrandingFormatString(PCWSTR format);
static const char* getOsNameByWinbrand(FFstrbuf* osName)
{
//https://dennisbabkin.com/blog/?t=how-to-tell-the-real-version-of-windows-your-app-is-running-on#ver_string
FF_LIBRARY_LOAD(winbrand, nullptr, "dlopen winbrand" FF_LIBRARY_EXTENSION " failed", "winbrand" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(winbrand, "dlopen winbrand" FF_LIBRARY_EXTENSION " failed", "winbrand" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(winbrand, BrandingFormatString);
const wchar_t* rawName = ffBrandingFormatString(L"%WINDOWS_LONG%");
+1 -1
View File
@@ -322,7 +322,7 @@ static uint32_t getSnap(FFstrbuf* baseDir)
static uint32_t getRpmFromLibrpm(void)
{
FF_LIBRARY_LOAD(rpm, &instance.config.library.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12)
FF_LIBRARY_LOAD(rpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0)
+1 -1
View File
@@ -41,7 +41,7 @@ static void paServerInfoCallback(pa_context *c, const pa_server_info *i, void *u
static const char* detectSound(FFlist* devices)
{
FF_LIBRARY_LOAD(pulse, &instance.config.library.libPulse, "Failed to load libpulse" FF_LIBRARY_EXTENSION, "libpulse" FF_LIBRARY_EXTENSION, 0)
FF_LIBRARY_LOAD(pulse, "Failed to load libpulse" FF_LIBRARY_EXTENSION, "libpulse" FF_LIBRARY_EXTENSION, 0)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_new)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_get_api)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_iterate)
+21 -24
View File
@@ -72,35 +72,32 @@ FF_MAYBE_UNUSED static void detectTTY(FFTerminalFontResult* terminalFont)
ffStrbufAppendS(&terminalFont->error, "Couldn't find Font in "FASTFETCH_TARGET_DIR_ETC"/vconsole.conf");
}
static bool queryKittyTerm(const char* query, FFstrbuf* res)
{
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
char buffer[256] = "";
if (ffGetTerminalResponse(
query, // kitty-query-font_family;kitty-query-font_size
"\eP1+r%*[^=]=%255[^\e]\e\\", buffer) == NULL)
{
// decode hex string
for (const char* p = buffer; p[0] && p[1]; p += 2)
{
unsigned value;
if (sscanf(p, "%2x", &value) == 1)
ffStrbufAppendC(res, (char) value);
}
return true;
}
return false;
}
FF_MAYBE_UNUSED static bool detectKitty(const FFstrbuf* exe, FFTerminalFontResult* result)
{
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate();
// Kitty generates response independently even if we query font family and size in one query
// which may result in short read in `ffGetTerminalResponse`
if (queryKittyTerm("\eP+q6b697474792d71756572792d666f6e745f66616d696c79\e\\", &fontName)) // kitty-query-font_family
queryKittyTerm("\eP+q6b697474792d71756572792d666f6e745f73697a65\e\\", &fontSize); // kitty-query-font_size
char fontHex[512] = "", sizeHex[512] = "";
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
if (ffGetTerminalResponse(
"\eP+q6b697474792d71756572792d666f6e745f66616d696c79;6b697474792d71756572792d666f6e745f73697a65\e\\", // kitty-query-font_family;kitty-query-font_size
2,
"\eP1+r%*[^=]=%64[^\e]\e\\\eP1+r%*[^=]=%64[^\e]\e\\", fontHex, sizeHex) == NULL && *fontHex && *sizeHex)
{
// decode hex string
for (const char* p = fontHex; p[0] && p[1]; p += 2)
{
unsigned value;
if (sscanf(p, "%2x", &value) == 1)
ffStrbufAppendC(&fontName, (char) value);
}
for (const char* p = sizeHex; p[0] && p[1]; p += 2)
{
unsigned value;
if (sscanf(p, "%2x", &value) == 1)
ffStrbufAppendC(&fontSize, (char) value);
}
}
else
{
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
@@ -15,7 +15,7 @@ const char* detectTermux(FFTerminalFontResult* terminalFont)
{
#ifdef FF_HAVE_FREETYPE
FF_LIBRARY_LOAD(freetype, &instance.config.library.libfreetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD(freetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Init_FreeType);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_New_Face);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Done_Face);
@@ -287,10 +287,10 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
}
static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* userData)
static bool extractStTermFont(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (!ffStrContains(str, "size=")) return true;
ffStrbufSetNS((FFstrbuf*) userData, len, str);
ffStrbufSetNS((FFstrbuf*) userdata, len, str);
return false;
}
@@ -315,7 +315,7 @@ static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult*
{
ffStrbufClear(&font);
const char* error = ffBinaryExtractStrings(terminal->exePath.chars, elfExtractStringsCallBack, &font);
const char* error = ffBinaryExtractStrings(terminal->exePath.chars, extractStTermFont, &font, (uint32_t) strlen("size=0"));
if (error)
{
ffStrbufAppendS(&terminalFont->error, error);
+62 -11
View File
@@ -64,16 +64,29 @@ static bool getExeVersionGeneral(FFstrbuf* exe, FFstrbuf* version)
return true;
}
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* version)
static bool extractBashVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffStrStartsWith(line, "@(#)Bash version ")) return true;
const char* start = line + strlen("@(#)Bash version ");
const char* end = strchr(start, '(');
if (!end) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
return false;
}
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
{
const char* path = exePath->chars;
if (*path == '\0')
path = exe->chars;
ffBinaryExtractStrings(path, extractBashVersion, version, (uint32_t) strlen("@(#)Bash version 0.0.0(0) release GNU"));
if(!getExeVersionRaw(exe, version))
return false;
// GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)\nCopyright...
ffStrbufSubstrBeforeFirstC(version, '\n'); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)
ffStrbufSubstrBeforeLastC(version, ' '); // GNU bash, version 5.1.16(1)-release
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16(1)-release
ffStrbufSubstrBeforeFirstC(version, '('); // 5.1.16
ffStrbufSubstrBeforeFirstC(version, '('); // GNU bash, version 5.1.16
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16
return true;
}
@@ -189,6 +202,29 @@ static bool getShellVersionXonsh(FFstrbuf* exe, FFstrbuf* version)
return true;
}
static bool extractZshVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffStrStartsWith(line, "zsh-")) return true;
const char* start = line + strlen("zsh-");
const char* end = strchr(start, '-');
if (!end) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
return false;
}
static bool getShellVersionZsh(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
{
const char* path = exePath->chars;
if (*path == '\0')
path = exe->chars;
ffBinaryExtractStrings(path, extractZshVersion, version, (uint32_t) strlen("zsh-0.0-0"));
if (version->length) return true;
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
}
#ifdef _WIN32
static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
{
@@ -203,7 +239,7 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
}
#endif
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version)
{
if (!instance.config.general.detectVersion) return false;
@@ -211,9 +247,9 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
return false;
if(ffStrEqualsIgnCase(exeName, "bash"))
return getShellVersionBash(exe, version);
return getShellVersionBash(exe, exePath, version);
if(ffStrEqualsIgnCase(exeName, "zsh"))
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
return getShellVersionZsh(exe, exePath, version);
if(ffStrEqualsIgnCase(exeName, "fish"))
return getShellVersionFish(exe, version);
if(ffStrEqualsIgnCase(exeName, "pwsh"))
@@ -251,7 +287,7 @@ FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version)
return version->length > 0;
}
static bool extractGnomeTerminalVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata)
static bool extractGeneralVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffCharIsDigit(str[0])) return true;
int count = 0;
@@ -265,7 +301,7 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* ver
{
if (exe->chars[0] == '/')
{
ffBinaryExtractStrings(exe->chars, extractGnomeTerminalVersion, version);
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
if (version->length) return true;
}
@@ -281,6 +317,17 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* ver
return true;
}
FF_MAYBE_UNUSED static bool getTerminalVersionXfce4Terminal(FFstrbuf* exe, FFstrbuf* version)
{
if (exe->chars[0] == '/')
{
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
if (version->length) return true;
}
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
}
FF_MAYBE_UNUSED static bool getTerminalVersionKgx(FFstrbuf* version)
{
if(ffProcessAppendStdOut(version, (char* const[]){
@@ -328,6 +375,9 @@ FF_MAYBE_UNUSED static bool getTerminalVersionFoot(FFstrbuf* exe, FFstrbuf* vers
FF_MAYBE_UNUSED static bool getTerminalVersionMateTerminal(FFstrbuf* exe, FFstrbuf* version)
{
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
if (version->length > 0) return true;
if(!getExeVersionRaw(exe, version)) return false;
//MATE Terminal 1.26.1
@@ -533,6 +583,7 @@ static bool getTerminalVersionKitty(FFstrbuf* exe, FFstrbuf* version)
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
if (ffGetTerminalResponse(
"\eP+q6b697474792d71756572792d76657273696f6e\e\\", // kitty-query-version
1,
"\eP1+r%*[^=]=%63[^\e]\e\\\\", versionHex) == NULL)
{
// decode hex string
@@ -616,7 +667,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
return getExeVersionGeneral(exe, version);//yakuake 22.12.3
if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal"))
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
return getTerminalVersionXfce4Terminal(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "terminator"))
return getExeVersionGeneral(exe, version);//terminator 2.1.3
@@ -274,14 +274,14 @@ static void getUserShellFromEnv(FFShellResult* result)
}
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version);
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
static void setShellInfoDetails(FFShellResult* result)
{
ffStrbufClear(&result->version);
fftsGetShellVersion(&result->exe, result->exeName, &result->version);
fftsGetShellVersion(&result->exe, result->exeName, &result->exePath, &result->version);
if(ffStrbufEqualS(&result->processName, "pwsh"))
ffStrbufInitStatic(&result->prettyName, "PowerShell");
@@ -38,7 +38,7 @@ static bool getProductVersion(const wchar_t* filePath, FFstrbuf* version)
return false;
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, const FFstrbuf* exePath, FFstrbuf* version);
static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
{
@@ -359,7 +359,7 @@ const FFShellResult* ffDetectShell(void)
strcpy(tmp, result.exeName);
char* ext = strrchr(tmp, '.');
if (ext) *ext = '\0';
fftsGetShellVersion(&result.exe, tmp, &result.version);
fftsGetShellVersion(&result.exe, tmp, &result.exePath, &result.version);
}
return &result;
@@ -14,10 +14,10 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result)
ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize);
if (winsize.ws_row == 0 || winsize.ws_col == 0)
ffGetTerminalResponse("\e[18t", "\e[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col);
ffGetTerminalResponse("\e[18t", 2, "\e[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col);
if (winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0)
ffGetTerminalResponse("\e[14t", "\e[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel);
ffGetTerminalResponse("\e[14t", 2, "\e[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel);
if (winsize.ws_row == 0 && winsize.ws_col == 0)
return false;
@@ -24,7 +24,8 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result)
}
else
{
ffGetTerminalResponse("\e[18t", "\e[8;%hu;%hut", &result->rows, &result->columns);
// Windows Terminal doesn't report `\e` for some reason
ffGetTerminalResponse("\e[18t", 2, "%*[^;];%hu;%hut", &result->rows, &result->columns);
}
}
@@ -38,12 +39,10 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result)
result->width = result->columns * (uint16_t) cfi.dwFontSize.X;
result->height = result->rows * (uint16_t) cfi.dwFontSize.Y;
}
else
if (result->width == 0 || result->height == 0)
{
// Pending https://github.com/microsoft/terminal/issues/8581
// if (result->width == 0 && result->height == 0)
// ffGetTerminalResponse("\033[14t", "\033[4;%hu;%hut", &result->height, &result->width);
return false;
// Windows Terminal doesn't report `\e` for some reason
ffGetTerminalResponse("\e[14t", 2, "%*[^;];%hu;%hut", &result->height, &result->width);
}
}
+6 -13
View File
@@ -6,22 +6,15 @@
static bool detectByEscapeCode(FFTerminalThemeResult* result)
{
int command = 0;
if (ffGetTerminalResponse("\e]10;?\e\\", "\e]%d;rgb:%" SCNx16 "/%" SCNx16 "/%" SCNx16 "\e\\", &command, &result->fg.r, &result->fg.g, &result->fg.b) == NULL)
// Windows Terminal removes all `\e`s in its output
if (ffGetTerminalResponse("\e]10;?\e\\" /*fg*/ "\e]11;?\e\\" /*bg*/,
6,
"%*[^0-9]10;rgb:%" SCNx16 "/%" SCNx16 "/%" SCNx16 /*"\e\\"*/ "%*[^0-9]11;rgb:%" SCNx16 "/%" SCNx16 "/%" SCNx16 /*"\e\\"*/,
&result->fg.r, &result->fg.g, &result->fg.b,
&result->bg.r, &result->bg.g, &result->bg.b) == NULL)
{
if (command != 10)
return false;
if (result->fg.r > 0x0100 || result->fg.g > 0x0100 || result->fg.b > 0x0100)
result->fg.r /= 0x0100, result->fg.g /= 0x0100, result->fg.b /= 0x0100;
}
else
return false;
if (ffGetTerminalResponse("\e]11;?\e\\", "\e]%d;rgb:%" SCNx16 "/%" SCNx16 "/%" SCNx16 "\e\\", &command, &result->bg.r, &result->bg.g, &result->bg.b) == NULL)
{
if (command != 11)
return false;
if (result->bg.r > 0x0100 || result->bg.g > 0x0100 || result->bg.b > 0x0100)
result->bg.r /= 0x0100, result->bg.g /= 0x0100, result->bg.b /= 0x0100;
}
+2 -2
View File
@@ -20,7 +20,7 @@ const char* ffDetectUptime(FFUptimeResult* result)
if(err != buf)
{
result->uptime = (uint64_t) (sec * 1000);
result->bootTime = ffTimeGetNow() + result->uptime;
result->bootTime = ffTimeGetNow() - result->uptime;
return NULL;
}
}
@@ -32,7 +32,7 @@ const char* ffDetectUptime(FFUptimeResult* result)
return "clock_gettime(CLOCK_BOOTTIME) failed";
result->uptime = (uint64_t) uptime.tv_sec * 1000 + (uint64_t) uptime.tv_nsec / 1000000;
result->bootTime = ffTimeGetNow() + result->uptime;
result->bootTime = ffTimeGetNow() - result->uptime;
return NULL;
}
+1 -1
View File
@@ -39,7 +39,7 @@ static void applyDriverName(VkPhysicalDeviceDriverPropertiesKHR* properties, FFs
static const char* detectVulkan(FFVulkanResult* result)
{
FF_LIBRARY_LOAD(vulkan, &instance.config.library.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed",
FF_LIBRARY_LOAD(vulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed",
#ifdef __APPLE__
"libMoltenVK"FF_LIBRARY_EXTENSION, -1
#elif defined(_WIN32)
+1 -1
View File
@@ -43,7 +43,7 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result)
const char* ffDetectWifi(FFlist* result)
{
FF_LIBRARY_LOAD(wlanapi, NULL, "dlopen wlanapi"FF_LIBRARY_EXTENSION" failed", "wlanapi"FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD(wlanapi, "dlopen wlanapi" FF_LIBRARY_EXTENSION " failed", "wlanapi" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanOpenHandle)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanEnumInterfaces)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanQueryInterface)
+89
View File
@@ -0,0 +1,89 @@
#pragma once
#include "fastfetch.h"
// From https://github.com/openzfs/zfs/blob/master/include/libzfs.h
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
typedef enum {
ZPOOL_PROP_INVAL = -1,
ZPOOL_PROP_NAME,
ZPOOL_PROP_SIZE,
ZPOOL_PROP_CAPACITY,
ZPOOL_PROP_ALTROOT,
ZPOOL_PROP_HEALTH,
ZPOOL_PROP_GUID,
ZPOOL_PROP_VERSION,
ZPOOL_PROP_BOOTFS,
ZPOOL_PROP_DELEGATION,
ZPOOL_PROP_AUTOREPLACE,
ZPOOL_PROP_CACHEFILE,
ZPOOL_PROP_FAILUREMODE,
ZPOOL_PROP_LISTSNAPS,
ZPOOL_PROP_AUTOEXPAND,
ZPOOL_PROP_DEDUPDITTO,
ZPOOL_PROP_DEDUPRATIO,
ZPOOL_PROP_FREE,
ZPOOL_PROP_ALLOCATED,
ZPOOL_PROP_READONLY,
ZPOOL_PROP_ASHIFT,
ZPOOL_PROP_COMMENT,
ZPOOL_PROP_EXPANDSZ,
ZPOOL_PROP_FREEING,
ZPOOL_PROP_FRAGMENTATION,
ZPOOL_PROP_LEAKED,
ZPOOL_PROP_MAXBLOCKSIZE,
ZPOOL_PROP_TNAME,
ZPOOL_PROP_MAXDNODESIZE,
ZPOOL_PROP_MULTIHOST,
ZPOOL_PROP_CHECKPOINT,
ZPOOL_PROP_LOAD_GUID,
ZPOOL_PROP_AUTOTRIM,
ZPOOL_PROP_COMPATIBILITY,
ZPOOL_PROP_BCLONEUSED,
ZPOOL_PROP_BCLONESAVED,
ZPOOL_PROP_BCLONERATIO,
ZPOOL_NUM_PROPS
} zpool_prop_t;
typedef enum {
ZPROP_SRC_NONE = 0x1,
ZPROP_SRC_DEFAULT = 0x2,
ZPROP_SRC_TEMPORARY = 0x4,
ZPROP_SRC_LOCAL = 0x8,
ZPROP_SRC_INHERITED = 0x10,
ZPROP_SRC_RECEIVED = 0x20
} zprop_source_t;
typedef bool boolean_t;
typedef struct libzfs_handle libzfs_handle_t;
typedef struct zpool_handle zpool_handle_t;
typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
extern libzfs_handle_t *libzfs_init(void);
extern void libzfs_fini(libzfs_handle_t *);
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *);
extern const char *zpool_get_name(zpool_handle_t *);
extern const char *zpool_get_state_str(zpool_handle_t *);
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "fastfetch.h"
typedef struct FFZpoolResult
{
FFstrbuf name;
FFstrbuf state;
uint64_t used;
uint64_t total;
uint64_t version;
uint64_t fragmentation;
} FFZpoolResult;
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */);
+111
View File
@@ -0,0 +1,111 @@
#include "zpool.h"
#ifdef FF_HAVE_LIBZFS
#ifdef __sun
#define FF_DISABLE_DLOPEN
#include <libzfs.h>
const char* zpool_get_state_str(zpool_handle_t* zpool)
{
if (zpool_get_state(zpool) == POOL_STATE_UNAVAIL)
return "FAULTED";
else
{
const char *str;
zpool_errata_t errata;
zpool_status_t status = zpool_get_status(zpool, (char**) &str, &errata);
if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
status == ZPOOL_STATUS_IO_FAILURE_CONTINUE ||
status == ZPOOL_STATUS_IO_FAILURE_MMP)
return "SUSPENDED";
else
{
nvlist_t *nvroot = fnvlist_lookup_nvlist(zpool_get_config(zpool, NULL), ZPOOL_CONFIG_VDEV_TREE);
uint_t vsc;
vdev_stat_t *vs;
#ifdef __x86_64__
if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint64_t**) &vs, &vsc) != 0)
#else
if (nvlist_lookup_uint32_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint32_t**) &vs, &vsc) != 0)
#endif
return "UNKNOWN";
else
return zpool_state_to_name(vs->vs_state, vs->vs_aux);
}
}
}
#else
#include "libzfs_simplified.h"
#endif
#include "common/library.h"
typedef struct FFZfsData
{
FF_LIBRARY_SYMBOL(libzfs_fini)
FF_LIBRARY_SYMBOL(zpool_iter)
FF_LIBRARY_SYMBOL(zpool_get_prop_int)
FF_LIBRARY_SYMBOL(zpool_get_name)
FF_LIBRARY_SYMBOL(zpool_get_state_str)
libzfs_handle_t* handle;
FFlist* result;
} FFZfsData;
static inline void cleanLibzfs(FFZfsData* data)
{
if (data->fflibzfs_fini && data->handle)
{
data->fflibzfs_fini(data->handle);
data->handle = NULL;
}
}
static int enumZpoolCallback(zpool_handle_t* zpool, void* param)
{
FFZfsData* data = (FFZfsData*) param;
zprop_source_t source;
FFZpoolResult* item = ffListAdd(data->result);
ffStrbufInitS(&item->name, data->ffzpool_get_name(zpool));
ffStrbufInitS(&item->state, data->ffzpool_get_state_str(zpool));
item->version = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_VERSION, &source);
item->total = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_SIZE, &source);
item->used = item->total - data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FREE, &source);
item->fragmentation = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FRAGMENTATION, &source);
return 0;
}
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */)
{
FF_LIBRARY_LOAD(libzfs, "dlopen libzfs" FF_LIBRARY_EXTENSION " failed", "libzfs" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init);
libzfs_handle_t* handle = fflibzfs_init();
if (!handle) return "libzfs_init() failed";
__attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = {
.handle = handle,
.result = result,
};
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_iter);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, libzfs_fini);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop_int);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_name);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_state_str);
if (ffzpool_iter(handle, enumZpoolCallback, &data) < 0)
return "zpool_iter() failed";
return NULL;
}
#else
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result)
{
return "Fastfetch was compiled without libzfs support";
}
#endif
+6
View File
@@ -0,0 +1,6 @@
#include "zpool.h"
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result /* list of FFZpoolResult */)
{
return "Not supported on this platform";
}
-3
View File
@@ -353,7 +353,6 @@ static bool parseJsoncFile(const char* path)
(error = ffOptionsParseLogoJsonConfig(&instance.config.logo, root)) ||
(error = ffOptionsParseGeneralJsonConfig(&instance.config.general, root)) ||
(error = ffOptionsParseDisplayJsonConfig(&instance.config.display, root)) ||
(error = ffOptionsParseLibraryJsonConfig(&instance.config.library, root)) ||
false
) {
fprintf(stderr, "JsonConfig Error: %s\n", error);
@@ -596,7 +595,6 @@ static void parseOption(FFdata* data, const char* key, const char* value)
ffOptionsParseGeneralCommandLine(&instance.config.general, key, value) ||
ffOptionsParseLogoCommandLine(&instance.config.logo, key, value) ||
ffOptionsParseDisplayCommandLine(&instance.config.display, key, value) ||
ffOptionsParseLibraryCommandLine(&instance.config.library, key, value) ||
ffParseModuleOptions(key, value)
) {}
@@ -688,7 +686,6 @@ static void writeConfigFile(FFdata* data, const FFstrbuf* filename)
ffOptionsGenerateLogoJsonConfig(&instance.config.logo, doc);
ffOptionsGenerateDisplayJsonConfig(&instance.config.display, doc);
ffOptionsGenerateGeneralJsonConfig(&instance.config.general, doc);
ffOptionsGenerateLibraryJsonConfig(&instance.config.library, doc);
ffMigrateCommandOptionToJsonc(data, doc);
if (ffStrbufEqualS(filename, "-"))
-2
View File
@@ -27,7 +27,6 @@
#include "options/logo.h"
#include "options/display.h"
#include "options/general.h"
#include "options/library.h"
typedef struct FFconfig
{
@@ -35,7 +34,6 @@ typedef struct FFconfig
FFOptionsDisplay display;
FFOptionsGeneral general;
FFOptionsModules modules;
FFOptionsLibrary library;
} FFconfig;
typedef struct FFstate
+19 -19
View File
@@ -1,19 +1,19 @@
${c1} ___________
/ \
/ ${c2}______${c1} \
/ ${c2}/ \${c1} \
| ${c2}( )${c1} \
/ ${c2}\______/${c1} |
| |
/ \
| |
| |
/ |
| |
| _______ |
____/ / \ |
/ | | |
| / ____/ |
\_________/ / |
\ __/
\_______/
___________
/ \
/ ${c2}______${c1} \
/ ${c2}/ \${c1} \
| ${c2}( )${c1} \
/ ${c2}\______/${c1} |
| |
/ \
| |
| |
/ |
| |
| _______ |
____/ / \ |
/ | | |
| / ____/ |
\_________/ / |
\ __/
\_______/
+24
View File
@@ -0,0 +1,24 @@
ti
jGGGGj
tGGGGGGt
,LGGLGGGGGGGG,
jGGGGjGGGGGGGGGj
GGGGGGGGGGGGGGGGGGGG
iGGGGGGt tLLLLLLi
,GGGGGi iGGGGG,
,jGGGG LGGGG,
,LjGGj LLLL,
,LLGG. iiii.
,LLj
,LLj jLL,
,LLLL. GGLL,
,LLLLt GGLL,
,LGGGG LGGGj,
,GGGGGi iGGGGG,
iGGGGGGj tGGGGGG,
GGGGGGGGGGGGGGGGGGGG
jGGGGGGGGGjGGGGj
,LGGGGGGGGGGG,
tGGGGGGt
jGGGGj
it
+16
View File
@@ -0,0 +1,16 @@
~. ........
::~~ +=: ~:========:~
..~:+oo===oo:.~+oooooooooooo+~
.:+==ooooooooooo==ooooooooooooooo:
.:=oooooooooooooooooooooooooooooooo=
.. .=oooooooooooooooooooooooooooooooooo=
==. .+ooooooooooooooooooooooooooooooooooo=
~+:~:oooooooooooooooooooooooooooooooooooo:
~ooooooooooooooooooooooooooooooooooooo=:
~oooooooooooooooooooooooooooooooooo==:.
.+oooooooooooooooooooooooooo=~::::~..
~+oooooooooooooooooooooooo=:
.:=ooooooooooooooooooooo=:
.:==ooooooooooooooo==:.
~~:===oooooo==+:~
...~~:~::..
+19
View File
@@ -0,0 +1,19 @@
${c2}@
@@--=====@@
@@--==@@ @@====+@
@-@@ @==@
@=@
@=@${c1} @=@ @-==== @=@${c2}
@=@${c1} @-===@==++@===+@${c2}
@=@${c1} @--====@@=====+@${c2}
-=@${c1} @--==========++@${c2}
==${c1} @--==========++@${c2} @=@
@==${c1} @--=======@==++@${c2} @=+@
@==${c1} @-==========++${c2} @=@
@==${c1} @-=======@=%${c2} @=@
@==${c1} @@@@@@${c2} @=@
@====@@@ @@===+%
@@=====@@==++++@@
=#@=@
@==@++@
@@@
+24
View File
@@ -0,0 +1,24 @@
$2 .xXK0kdc'..
.OMMMMWNK0Odc'.
.OMMMMMMMMMMWNOl'.
.OMMMMMMMMMMMMMWXx;.
.:ddk0XWMMMMMMMMMMNx'
..;oxONMMMMMMMWKc.
$1 ..,;::::;,'.$2 .;xXMMMMMMMNo.
$1 .':looooooooool:,..$2 .;OWMMMMMMNl.
$1 .:oooooooooooooooooc'$2 .xWMMMMMMK:
$1 'coooooooooooooooooool,$2 'OMMMMMMWx.
$1.coooooooooooooooooooool.$2 cNMMMMMM0,
$1'loooooooooooooooooooooo,$2 ,KMMMMMMX:
$1'loooooooooooooooooooooo,$2 ,KMMMMMMX:
$1.:oooooooooooooooooooooc.$2 lNMMMMMM0,
$1 .coooooooooooooooooool'$2 ,0MMMMMMWd.
$1 .:looooooooooooooolc.$2 'OWMMMMMMK;
$1 ..;cloooooooooc;'..$2 .c0WMMMMMMXc.
$1 ..',;;;;,'..$2 ..cONMMMMMMMXc.
..,cxOKWMMMMMMMW0;.
.cxk0KNWMMMMMMMMMWXo.
.OMMMMMMMMMMMMMWKo'
.OMMMMMMMMMMWKx:.
.OMMMWNX0Oxl;.
.o0Oxoc,..
+5
View File
@@ -0,0 +1,5 @@
$2__
\
$1## $2\
$1## $2/
__/
+20 -20
View File
@@ -1,20 +1,20 @@
....
.',:clooo: .:looooo:.
.;looooooooc .oooooooooo'
.;looooool:,''. :ooooooooooc
;looool;. 'oooooooooo,
;clool' .cooooooc. ,,
... ...... .:oo,
.;clol:,. .loooo'
:ooooooooo, 'ooool
'ooooooooooo. loooo.
'ooooooooool coooo.
,loooooooc. .loooo.
.,;;;'. ;ooooc
... ,ooool.
.cooooc. ..',,'. .cooo.
;ooooo:. ;oooooooc. :l.
.coooooc,.. coooooooooo.
.:ooooooolc:. .ooooooooooo'
.':loooooo; ,oooooooooc
..';::c' .;loooo:'
....
$2.',:clooo: $1.:looooo:.
$2.;looooooooc $1.oooooooooo'
$2.;looooool:,''. $1:ooooooooooc
$2;looool;. $1'oooooooooo,
$2;clool' $1.cooooooc. $2,,
$2... $1...... $2.:oo,
$1.;clol:,. $2.loooo'
$1:ooooooooo, $2'ooool
$1'ooooooooooo. $2loooo.
$1'ooooooooool $2coooo.
$1,loooooooc. $2.loooo.
$1.,;;;'. $2;ooooc
$2... $2,ooool.
$2.cooooc. $1..',,'. $2.cooo.
$2;ooooo:. $1;oooooooc. $2:l.
$2.coooooc,.. $1coooooooooo.
$2.:ooooooolc:. $1.ooooooooooo'
$2.':loooooo; $1,oooooooooc
$2..';::c' $1.;loooo:'
-11
View File
@@ -1,11 +0,0 @@
..;,; .,;,.
.,lool: .ooooo,
;oo;: .coool.
.... ''' ,l;
:oooo, 'oo.
looooc :oo'
'::' ,oo:
,., .... co,
lo:;. :oooo; .
':ooo; cooooc
''' ''''
+5 -5
View File
@@ -3,16 +3,16 @@
-+ssssssssssssssssssyyssss+-
.ossssssssssssssssssd$2MMMNy$1sssso.
/sssssssssss$2hdmmNNmmyNMMMMh$1ssssss/
+sssssssss$2hmydMMMMMMMNddddy$1ssssssss+
/ssssssss$2hNMMMyhhyyyyhmNMMMNh$1ssssssss/
+sssssssss$2hm$1yd$2MMMMMMMNddddy$1ssssssss+
/ssssssss$2hNMMM$1yh$2hyyyyhmNMMMNh$1ssssssss/
.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.
+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+
oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso
oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso
oss$2yNMMMNyMMh$1sssssssssssssshmmmhssssssso
+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+
.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.
/ssssssss$2hNMMMyhhyyyyhdNMMMNh$1ssssssss/
+sssssssss$2dmydMMMMMMMMddddy$1ssssssss+
/ssssssss$2hNMMM$1yh$2hyyyyhdNMMMNh$1ssssssss/
+sssssssss$2dm$1yd$2MMMMMMMMddddy$1ssssssss+
/sssssssssss$2hdmNNNNmyNMMMMh$1ssssss/
.ossssssssssssssssss$2dMMMNy$1sssso.
-+sssssssssssssssss$2yyy$1ssss+-
+6
View File
@@ -0,0 +1,6 @@
_
---(_)
_/ --- \
(_) | |
\ --- _/
---(_)
+11 -6
View File
@@ -1,6 +1,11 @@
_
---(_)
_/ --- \
(_) | |
\ --- _/
---(_)
$2..;,; $1.,;,.
$2.,lool: $1.ooooo,
$2;oo;: $1.coool.
$1.... $1''' $2,l;
$1:oooo, $2'oo.
$1looooc $2:oo'
$1'::' $2,oo:
$2,., $1.... $2co,
$2lo:;. $1:oooo; $2.
$2':ooo; $1cooooc
$2''' $1''''
+119 -56
View File
@@ -1987,6 +1987,16 @@ static const FFlogo H[] = {
FF_COLOR_FG_256 "123",
},
},
// Huawei Cloud EulerOS
{
.names = {"Huawei Cloud EulerOS", "hce"},
.lines = FASTFETCH_DATATEXT_LOGO_HCE,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Huayra
{
.names = {"Huayra"},
@@ -2285,6 +2295,16 @@ static const FFlogo K[] = {
};
static const FFlogo L[] = {
// LainOS
{
.names = {"LainOS"},
.lines = FASTFETCH_DATATEXT_LOGO_LAINOS,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_256 "14",
FF_COLOR_FG_WHITE,
},
},
// LangitKetujuh
{
.names = {"langitketujuh", "l7"},
@@ -2459,6 +2479,16 @@ static const FFlogo L[] = {
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_WHITE,
},
// LliureX
{
.names = {"LliureX"},
.lines = FASTFETCH_DATATEXT_LOGO_LLIUREX,
.colors = {
FF_COLOR_FG_BLUE,
},
.colorKeys = FF_COLOR_FG_WHITE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// LMDE
{
.names = {"LMDE"},
@@ -2470,16 +2500,6 @@ static const FFlogo L[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// LainOS
{
.names = {"LainOS"},
.lines = FASTFETCH_DATATEXT_LOGO_LAINOS,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_256 "14",
FF_COLOR_FG_WHITE,
},
},
// Loc-OS
{
.names = {"locos", "loc-os", "Loc-OS Linux"},
@@ -2623,6 +2643,17 @@ static const FFlogo M[] = {
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// Magix
{
.names = {"Magix","MagixOS"},
.lines = FASTFETCH_DATATEXT_LOGO_MAGIX,
.colors = {
FF_COLOR_FG_LIGHT_MAGENTA,
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_LIGHT_MAGENTA,
},
// MagpieOS
{
.names = {"MagpieOS", "Magpie"},
@@ -4127,7 +4158,7 @@ static const FFlogo S[] = {
},
// SteamOS
{
.names = {"steamos"},
.names = {"SteamOS"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMOS,
.colors = {
FF_COLOR_FG_BLUE,
@@ -4136,6 +4167,39 @@ static const FFlogo S[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck
{
.names = {"SteamDeck"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck Small
{
.names = {"SteamDeck_small"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK_SMALL,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck OLED
{
.names = {"SteamDeckOled"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Sulin
{
.names = {"Sulin"},
@@ -4273,6 +4337,26 @@ static const FFlogo U[] = {
{
.names = {"ubuntu", "ubuntu-linux"},
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_RED,
},
},
// UbuntuSmall
{
.names = {"ubuntu_small", "ubuntu-linux-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_RED,
},
},
// UbuntuOld
{
.names = {"ubuntu_old", "ubuntu-linux_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
@@ -4280,6 +4364,30 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuOld2
{
.names = {"ubuntu_old2"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_YELLOW,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuOld2Small
{
.names = {"ubuntu_old2_small", "ubuntu_old2-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuBudgie
{
.names = {"ubuntu budgie", "ubuntu-budgie"},
@@ -4337,18 +4445,6 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// UbuntuOld
{
.names = {"ubuntu_old", "ubuntu-linux_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuKde
{
.names = {"ubuntu kde", "ubuntu-kde", "ubuntu-plasma"},
@@ -4360,17 +4456,6 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// UbuntuSmall
{
.names = {"ubuntu_small", "ubuntu-linux-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuStudio
{
.names = {"ubuntu studio", "ubuntu-studio"},
@@ -4407,28 +4492,6 @@ static const FFlogo U[] = {
FF_COLOR_FG_WHITE,
},
},
// Ubuntu2Small
{
.names = {"ubuntu2_small", "ubuntu2-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Ubuntu2Old
{
.names = {"ubuntu2_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_YELLOW,
},
},
// Ultramarine
{
.names = {"Ultramarine", "Ultramarine Linux"},
+1 -1
View File
@@ -14,7 +14,7 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex
FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData)
{
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
+1 -1
View File
@@ -14,7 +14,7 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex
FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData)
{
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR,
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR,
"libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11,
"libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11,
"libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, -1 // Required for Windows
+24 -32
View File
@@ -3,6 +3,7 @@
#include "common/printing.h"
#include "util/stringUtils.h"
#include "util/base64.h"
#include "detection/terminalsize/terminalsize.h"
#include <limits.h>
#include <math.h>
@@ -77,12 +78,14 @@ static bool printImageIterm(bool printError)
if (options->position == FF_LOGO_POSITION_LEFT || options->position == FF_LOGO_POSITION_RIGHT)
{
uint16_t X = 0, Y = 0;
const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X);
const char* error = ffGetTerminalResponse("\e[6n", 2, "%*[^0-9]%hu;%huR", &Y, &X);
if (error)
{
fprintf(stderr, "\nLogo (iterm): fail to query cursor position: %s\n", error);
return true; // We already printed image logo, don't print ascii logo then
}
if (X < options->paddingLeft + options->width)
X = (uint16_t) (options->paddingLeft + options->width);
if (options->position == FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = X + options->paddingRight - 1;
instance.state.logoHeight = Y;
@@ -200,13 +203,15 @@ static bool printImageKittyDirect(bool printError)
if (options->position == FF_LOGO_POSITION_LEFT || options->position == FF_LOGO_POSITION_RIGHT)
{
uint16_t X = 0, Y = 0;
const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X);
const char* error = ffGetTerminalResponse("\e[6n", 2, "%*[^0-9]%hu;%huR", &Y, &X);
if (error)
{
if (printError)
fprintf(stderr, "\nLogo (kitty-direct): fail to query cursor position: %s\n", error);
return true; // We already printed image logo, don't print ascii logo then
}
if (X < options->paddingLeft + options->width)
X = (uint16_t) (options->paddingLeft + options->width);
if (options->position == FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = X + options->paddingRight - 1;
instance.state.logoHeight = Y;
@@ -300,7 +305,7 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso
static bool compressBlob(void** blob, size_t* length)
{
FF_LIBRARY_LOAD(zlib, &instance.config.library.libZ, false, "libz" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD(zlib, false, "libz" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL(zlib, compressBound, false)
FF_LIBRARY_LOAD_SYMBOL(zlib, compress2, false)
@@ -485,7 +490,7 @@ static bool printImageKitty(FFLogoRequestData* requestData, const ImageData* ima
#include <chafa.h>
static bool printImageChafa(FFLogoRequestData* requestData, const ImageData* imageData)
{
FF_LIBRARY_LOAD(chafa, &instance.config.library.libChafa, false,
FF_LIBRARY_LOAD(chafa, false,
"libchafa" FF_LIBRARY_EXTENSION, 1,
"libchafa-0" FF_LIBRARY_EXTENSION, -1 // Required for Windows
)
@@ -831,38 +836,25 @@ static bool printCached(FFLogoRequestData* requestData)
static bool getCharacterPixelDimensions(FFLogoRequestData* requestData)
{
#ifndef _WIN32
struct winsize winsize;
//Initialize every member to 0, because it isn't guaranteed that every terminal sets them all
memset(&winsize, 0, sizeof(struct winsize));
ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize);
if(winsize.ws_row == 0 || winsize.ws_col == 0)
ffGetTerminalResponse("\033[18t", "\033[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col);
if(winsize.ws_row == 0 || winsize.ws_col == 0)
return false;
if(winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0)
ffGetTerminalResponse("\033[14t", "\033[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel);
requestData->characterPixelWidth = winsize.ws_xpixel / (double) winsize.ws_col;
requestData->characterPixelHeight = winsize.ws_ypixel / (double) winsize.ws_row;
#else
#ifdef _WIN32
CONSOLE_FONT_INFO cfi;
if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi) == FALSE) // Only works for ConHost
return false;
requestData->characterPixelWidth = cfi.dwFontSize.X;
requestData->characterPixelHeight = cfi.dwFontSize.Y;
if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi)) // Only works for ConHost
{
requestData->characterPixelWidth = cfi.dwFontSize.X;
requestData->characterPixelHeight = cfi.dwFontSize.Y;
}
if (requestData->characterPixelWidth > 1.0 && requestData->characterPixelHeight > 1.0)
return true;
#endif
FFTerminalSizeResult termSize = {};
if (ffDetectTerminalSize(&termSize))
{
requestData->characterPixelWidth = termSize.width / (double) termSize.columns;
requestData->characterPixelHeight = termSize.height / (double) termSize.rows;
}
return requestData->characterPixelWidth > 1.0 && requestData->characterPixelHeight > 1.0;
}
+7 -2
View File
@@ -40,7 +40,7 @@ static bool ffLogoPrintCharsRaw(const char* data, size_t length, bool printError
if (!options->width)
{
if (printError)
fputs("Logo (iterm): Must set logo width when using position right\n", stderr);
fputs("Logo (image-raw): Must set logo width when using position right\n", stderr);
return false;
}
ffStrbufAppendF(&buf, "\e[2J\e[3J\e[%u;9999999H\e[%uD", (unsigned) options->paddingTop + 1, (unsigned) options->paddingRight + options->width);
@@ -51,7 +51,8 @@ static bool ffLogoPrintCharsRaw(const char* data, size_t length, bool printError
if (options->position == FF_LOGO_POSITION_LEFT || options->position == FF_LOGO_POSITION_RIGHT)
{
uint16_t X = 0, Y = 0;
const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X);
// Windows Terminal doesn't report `\e` for some reason
const char* error = ffGetTerminalResponse("\e[6n", 2, "%*[^0-9]%hu;%huR", &Y, &X); // %*[^0-9]: ignore optional \e[
if (error)
{
if (printError)
@@ -59,7 +60,11 @@ static bool ffLogoPrintCharsRaw(const char* data, size_t length, bool printError
return true;
}
if (options->position == FF_LOGO_POSITION_LEFT)
{
if (options->width + options->paddingLeft > X)
X = (uint16_t) (options->width + options->paddingLeft);
instance.state.logoWidth = X + instance.config.logo.paddingRight - 1;
}
instance.state.logoHeight = Y;
fputs("\e[H", stdout);
}
+29 -12
View File
@@ -11,9 +11,26 @@
static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uint8_t index)
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
if (options->moduleArgs.key.length == 0)
{
if (result->modelName.length > 0)
ffStrbufSetF(&key, "%s (%s)", FF_BATTERY_MODULE_NAME, result->modelName.chars);
else
ffStrbufSetS(&key, FF_BATTERY_MODULE_NAME);
}
else
{
ffStrbufClear(&key);
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 2, ((FFformatarg[]){
FF_FORMAT_ARG(index, "index"),
FF_FORMAT_ARG(result->modelName, "name"),
}));
}
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
bool showStatus =
@@ -63,17 +80,17 @@ 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(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer, "manufacturer"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName, "model-name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->technology, "technology"},
{FF_FORMAT_ARG_TYPE_STRBUF, &capacityNum, "capacity"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->status, "status"},
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr, "temperature"},
{FF_FORMAT_ARG_TYPE_UINT, &result->cycleCount, "cycle-count"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->serial, "serial"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufactureDate, "manufacture-date"},
{FF_FORMAT_ARG_TYPE_STRBUF, &capacityBar, "capacity-bar"},
FF_PRINT_FORMAT_CHECKED(key.chars, index, &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"),
FF_FORMAT_ARG(capacityNum, "capacity"),
FF_FORMAT_ARG(result->status, "status"),
FF_FORMAT_ARG(tempStr, "temperature"),
FF_FORMAT_ARG(result->cycleCount, "cycle-count"),
FF_FORMAT_ARG(result->serial, "serial"),
FF_FORMAT_ARG(result->manufactureDate, "manufacture-date"),
FF_FORMAT_ARG(capacityBar, "capacity-bar"),
}));
}
}

Some files were not shown because too many files have changed in this diff Show More