mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
117 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9bb761a2d | |||
| fd432e3635 | |||
| 174dde131c | |||
| 99668771c7 | |||
| dc541ac781 | |||
| 68ab41f748 | |||
| e8f711830e | |||
| a052033dc6 | |||
| fed2c87f67 | |||
| b7fcd7fc0c | |||
| b2810bc030 | |||
| 8f1f1607da | |||
| 611d5f949b | |||
| 536e2fb42d | |||
| 1e4601485a | |||
| f8c58a9178 | |||
| d8fb8d439e | |||
| de59ffb31f | |||
| c24d378cf1 | |||
| de8efb39c8 | |||
| 13452da076 | |||
| 7db8d7c3ce | |||
| f4424b4204 | |||
| 8371920c6b | |||
| c9d539090d | |||
| d43c6ffe27 | |||
| cf7c5d3cfa | |||
| 3f67fac4fa | |||
| 879d5594da | |||
| 32bf85742c | |||
| 37cc2c9c1b | |||
| c39df1ae7b | |||
| 4622604ee1 | |||
| 617661b546 | |||
| 9aae274cc7 | |||
| 90b2bf0ad6 | |||
| aec27c3e50 | |||
| d79bf0a460 | |||
| 352ed51504 | |||
| d824045973 | |||
| bbe4988054 | |||
| 636126c57d | |||
| 2e475d590f | |||
| 0cf45c1dcd | |||
| 435516373d | |||
| 64735245e7 | |||
| 85d89395a9 | |||
| 093940e504 | |||
| e427a5112b | |||
| 1ab86a8ab9 | |||
| 99e0dc9aaa | |||
| 73e9db5b6e | |||
| adc03bd792 | |||
| 10fdc8e4a7 | |||
| d75803794e | |||
| d25ac86283 | |||
| de8bbc9a5c | |||
| 66977de5c7 | |||
| f828d3a9b9 | |||
| f0bc08e006 | |||
| e0f8e39a47 | |||
| 8b9f787095 | |||
| d946cf27fe | |||
| 5842ad1d56 | |||
| 201047251d | |||
| 5c8e771939 | |||
| b22e28b548 | |||
| 8c51836a47 | |||
| df729938c5 | |||
| 67d0dfcef0 | |||
| 03c95e5cad | |||
| c0a07002f2 | |||
| 5a9c3154fa | |||
| e35aed761b | |||
| 823f2ef028 | |||
| 11cfdba5cb | |||
| 5b78b2e897 | |||
| 773b8db337 | |||
| d15d4c621c | |||
| 788cad3cbe | |||
| f6ccbf7711 | |||
| e6fb545d1d | |||
| ce7ecd3863 | |||
| c8d85e09d7 | |||
| 34bc662065 | |||
| a54cbee79a | |||
| df873a19e1 | |||
| b5695b50c2 | |||
| f22b8ede02 | |||
| 893b3a6bff | |||
| e199a2fb79 | |||
| b4aac9d7d7 | |||
| cf9bd0f373 | |||
| 17deaf963e | |||
| e66a83a4cf | |||
| 96905012a4 | |||
| 591dba8829 | |||
| d10dd2095a | |||
| 22e25d0c78 | |||
| 1c8375908c | |||
| 099a390f2f | |||
| dd2d343630 | |||
| 543eed9a53 | |||
| 4860bc35d6 | |||
| 8559ab2dcd | |||
| 811485661f | |||
| 31ead528f1 | |||
| 8641442c3f | |||
| 418902512d | |||
| fbfe2b2d1a | |||
| f71c4f6d5a | |||
| b46d9d8b8e | |||
| 9d27106964 | |||
| bbb873c27b | |||
| da50a48dd5 | |||
| c8e4de9831 | |||
| e0d733f030 |
@@ -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
|
||||
|
||||
@@ -1,3 +1,85 @@
|
||||
# 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:
|
||||
* Small performance improvements (Terminal, Editor)
|
||||
* Improve arm32 and loongarch support (CPU, Linux)
|
||||
* Ignore the parent process if env `$FFTS_IGNORE_PARENT` is set to `1` (Shell)
|
||||
* Add code name of Apple M4 (CPU, Linux)
|
||||
* Add ethernet speed rate detection support (LocalIP)
|
||||
* Add zsh completion script
|
||||
* Add Linglong package manager detection support (Packages, Linux)
|
||||
|
||||
Bugfixes:
|
||||
* Fix building on macOS 10.14
|
||||
* Fix tmux in linux TTY (Colors)
|
||||
* Fix hang in WSL when custom format is used (Disk, Linux)
|
||||
* Fix `/proc/loadavg` parsing (Loadavg, Linux)
|
||||
* Disable use of `LC_NUMERIC` locale settings to fix parsing of decimal numbers
|
||||
* Fix possible segfault (DiskIO, Linux)
|
||||
* Honor `preciseRefreshRate` in custom format (Display)
|
||||
|
||||
Logos:
|
||||
* Add Lingmo OS
|
||||
* Add Sleeper OS
|
||||
|
||||
# 2.21.3
|
||||
|
||||
Bugfixes:
|
||||
|
||||
+62
-7
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.21.3
|
||||
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 SunOS" 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,15 +393,16 @@ 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
|
||||
src/util/FFstrbuf.c
|
||||
src/util/path.c
|
||||
src/util/platform/FFPlatform.c
|
||||
src/util/smbiosHelper.c
|
||||
)
|
||||
@@ -480,8 +482,9 @@ 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/linux/elf.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -542,7 +545,9 @@ 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
|
||||
)
|
||||
elseif(FreeBSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -620,8 +625,9 @@ 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/linux/elf.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -684,9 +690,11 @@ 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
|
||||
src/util/binary_apple.c
|
||||
)
|
||||
elseif(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -747,12 +755,14 @@ 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
|
||||
src/util/windows/unicode.c
|
||||
src/util/windows/wmi.cpp
|
||||
src/util/platform/FFPlatform_windows.c
|
||||
src/util/binary_windows.c
|
||||
)
|
||||
elseif(SunOS)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -828,8 +838,9 @@ 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/linux/elf.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -1087,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)
|
||||
@@ -1135,6 +1165,7 @@ elseif(WIN32)
|
||||
PRIVATE "setupapi"
|
||||
PRIVATE "hid"
|
||||
PRIVATE "wtsapi32"
|
||||
PRIVATE "imagehlp"
|
||||
)
|
||||
elseif(FreeBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1148,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)
|
||||
@@ -1191,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)
|
||||
@@ -1303,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()
|
||||
|
||||
##################
|
||||
@@ -1332,6 +1381,12 @@ install(
|
||||
RENAME "${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.zsh"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/zsh/site-functions"
|
||||
RENAME "_${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.fish"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/fish/vendor_completions.d"
|
||||
|
||||
@@ -30,17 +30,23 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
|
||||
Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version.
|
||||
|
||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||
* Debian: `sudo apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian: `apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
|
||||
* Arch Linux: `pacman -S fastfetch`
|
||||
* Fedora: `dnf install fastfetch`
|
||||
* Gentoo: `emerge --ask app-misc/fastfetch`
|
||||
* Alpine: `apk add --upgrade fastfetch`
|
||||
* NixOS: `nix-shell -p fastfetch`
|
||||
* openSUSE: `sudo zypper install fastfetch`
|
||||
* ALT Linux: `sudo apt-get install fastfetch`
|
||||
* openSUSE: `zypper install fastfetch`
|
||||
* ALT Linux: `apt-get install fastfetch`
|
||||
* Exherbo: `cave resolve --execute app-misc/fastfetch`
|
||||
* GNU Guix: `guix install fastfetch`
|
||||
* Solus: `eopkg install fastfetch`
|
||||
* Slackware: `sbopkg -i fastfetch`
|
||||
* Void Linux: `xbps-install fastfetch`
|
||||
* Venom Linux: `scratch install fastfetch`
|
||||
|
||||
Replace sudo with doas depending on what you use.
|
||||
You may need `sudo`, `doas` or `sup` to run these commands.
|
||||
|
||||
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging).
|
||||
|
||||
@@ -54,8 +60,9 @@ If fastfetch is not packaged for your distro or an outdated version is packaged,
|
||||
### Windows
|
||||
|
||||
* [scoop](https://scoop.sh/#/apps?q=fastfetch): `scoop install fastfetch`
|
||||
* [Chocolatey](https://community.chocolatey.org/packages/fastfetch): `choco install fastfetch`
|
||||
* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch`
|
||||
* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
* [MSYS2 MinGW](https://packages.msys2.org/base/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
|
||||
You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file.
|
||||
|
||||
@@ -74,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`
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
#compdef fastfetch
|
||||
|
||||
function _fastfetch() {
|
||||
local state
|
||||
|
||||
local -a opts=("${(f)$(
|
||||
python3 <<EOF
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
data: dict[str, list[dict]] = json.loads(
|
||||
subprocess.check_output(["fastfetch", "--help-raw"])
|
||||
)
|
||||
|
||||
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"]}]"
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
if "long" in flag:
|
||||
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
|
||||
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)")
|
||||
elif type == "color":
|
||||
print(f"{command_prefix}:color:->colors")
|
||||
elif type == "command":
|
||||
print(f"{command_prefix}::module:->modules")
|
||||
elif type == "config":
|
||||
print(f"{command_prefix}:preset:->presets")
|
||||
elif type == "enum":
|
||||
temp: str = " ".join(flag["arg"]["enum"])
|
||||
print(f'{command_prefix}:type:({temp})')
|
||||
elif type == "logo":
|
||||
print(f"{command_prefix}:logo:->logos")
|
||||
elif type == "structure":
|
||||
print(f"{command_prefix}:structure:->structures")
|
||||
elif type == "path":
|
||||
print(f"{command_prefix}::path:_files")
|
||||
else:
|
||||
print(f"{command_prefix}:")
|
||||
else:
|
||||
print(f"{command_prefix}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
EOF
|
||||
)}")
|
||||
|
||||
_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)
|
||||
_describe 'module' modules
|
||||
;;
|
||||
presets)
|
||||
local -a presets=(
|
||||
"${(f)$(fastfetch --list-presets autocompletion)}"
|
||||
"none:Disable loading config file"
|
||||
)
|
||||
_describe 'preset' presets || _files
|
||||
;;
|
||||
structures)
|
||||
local -a structures=("${(f)$(fastfetch --list-modules autocompletion)}")
|
||||
_describe 'structure' structures
|
||||
;;
|
||||
logos)
|
||||
local -a logos=(
|
||||
"${(f)$(fastfetch --list-logos autocompletion)}"
|
||||
"none:Don't print logo"
|
||||
"small:Print small ascii logo if available"
|
||||
)
|
||||
_describe 'logo' logos
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_fastfetch "$@"
|
||||
Vendored
+18
@@ -1,3 +1,21 @@
|
||||
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
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 15 Aug 2024 16:14:52 +0800
|
||||
|
||||
fastfetch (2.21.2) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.2
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.21.2_source.buildinfo universe/utils optional
|
||||
fastfetch_2.23.0_source.buildinfo universe/utils optional
|
||||
|
||||
+10
-108
@@ -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"
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"zpool",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"zpool",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -11,45 +11,51 @@
|
||||
},
|
||||
"separator": ""
|
||||
},
|
||||
"modules": [
|
||||
"modules": [
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "Vanilla ",
|
||||
"key": "[_Kernel___> ",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"outputColor": "white",
|
||||
"key": " [_Packages_> ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"outputColor": "white",
|
||||
"key": " [_Local_IP_> ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": " [_CPU______> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"format": "[{3}] {1} / {2}",
|
||||
"key": " [_RAM______> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"format": "[{3}] {1} / {2}",
|
||||
"key": " [_SWAP_____> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"format": "[{3}] {1} / {2} {9}",
|
||||
"key": " [_Disk_____> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"format": "[{4}] {5}",
|
||||
"key": " [_Battery__> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type":"colors",
|
||||
"type": "colors",
|
||||
"paddingLeft": 9,
|
||||
"symbol": "circle"
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@
|
||||
"type": "disk",
|
||||
"folders": "/"
|
||||
},
|
||||
"battery",
|
||||
{
|
||||
"type": "battery",
|
||||
"key": "Battery"
|
||||
},
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 10,
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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
-7
@@ -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)
|
||||
@@ -54,10 +53,6 @@ void ffInitInstance(void)
|
||||
#else
|
||||
// Never use `setlocale(LC_ALL, "")`
|
||||
setlocale(LC_TIME, "");
|
||||
setlocale(LC_NUMERIC, "");
|
||||
#ifdef LC_MESSAGES
|
||||
setlocale(LC_MESSAGES, "");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
initState(&instance.state);
|
||||
@@ -152,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)
|
||||
@@ -248,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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -169,6 +169,7 @@ static FFModuleBaseInfo* Y[] = {
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* Z[] = {
|
||||
(void*) &instance.config.modules.zpool,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
+15
-1
@@ -36,6 +36,20 @@ const char* ffCPUAppleCodeToName(uint32_t code)
|
||||
case 6030: return "Apple M3 Pro";
|
||||
case 6031:
|
||||
case 6034: return "Apple M3 Max";
|
||||
default: return "Apple Silicon";
|
||||
case 8132: return "Apple M4";
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,3 +30,30 @@ 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__)
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
// WARNING: CPUID may report frequencies of efficient cores
|
||||
inline static const char* ffCPUDetectSpeedByCpuid(FFCPUResult* cpu)
|
||||
{
|
||||
uint32_t base = 0, max = 0, bus = 0, unused = 0;
|
||||
if (!__get_cpuid(0x16, &base, &max, &bus, &unused))
|
||||
return "Unsupported instruction";
|
||||
|
||||
// cpuid returns 0 MHz when hyper-v is enabled
|
||||
if (base) cpu->frequencyBase = base;
|
||||
if (max) cpu->frequencyMax = max;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline static const char* ffCPUDetectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
|
||||
{
|
||||
return "Unsupported platform";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -39,6 +39,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
}
|
||||
}
|
||||
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
|
||||
for (uint16_t i = 0; i < cpu->coresLogical; ++i)
|
||||
{
|
||||
ffStrbufClear(&buffer);
|
||||
|
||||
@@ -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]");
|
||||
|
||||
@@ -137,36 +145,52 @@ static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* parseCpuInfo(FILE* cpuinfo, FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch, FFstrbuf* cpuImplementer)
|
||||
static const char* parseCpuInfo(
|
||||
FF_MAYBE_UNUSED FILE* cpuinfo,
|
||||
FF_MAYBE_UNUSED FFCPUResult* cpu,
|
||||
FF_MAYBE_UNUSED FFstrbuf* physicalCoresBuffer,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuMHz,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuIsa,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuUarch,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuImplementer)
|
||||
{
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while(getline(&line, &len, cpuinfo) != -1)
|
||||
{
|
||||
//Stop after the first CPU
|
||||
if(*line == '\0' || *line == '\n')
|
||||
//Stop after reasonable information is acquired
|
||||
if((*line == '\0' || *line == '\n')
|
||||
#if __arm__ || __loongarch__
|
||||
&& cpu->name.length > 0 // #1202 #1204
|
||||
#endif
|
||||
)
|
||||
break;
|
||||
|
||||
(void)(
|
||||
ffParsePropLine(line, "model name :", &cpu->name) ||
|
||||
ffParsePropLine(line, "vendor_id :", &cpu->vendor) ||
|
||||
ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) ||
|
||||
ffParsePropLine(line, "cpu MHz :", cpuMHz) ||
|
||||
ffParsePropLine(line, "isa :", cpuIsa) ||
|
||||
ffParsePropLine(line, "uarch :", cpuUarch) ||
|
||||
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
|
||||
// "Hardware" should always be used in this case
|
||||
#if !(__arm__ || __aarch64__)
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) ||
|
||||
(physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) ||
|
||||
#endif
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
|
||||
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
|
||||
#endif
|
||||
|
||||
#if __arm__ || __aarch64__
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
|
||||
#endif
|
||||
#if __ANDROID__
|
||||
(cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
|
||||
#endif
|
||||
#if __powerpc__ || __powerpc
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
#endif
|
||||
#if __mips__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS
|
||||
#endif
|
||||
false
|
||||
);
|
||||
@@ -265,16 +289,19 @@ static double detectCPUTemp(void)
|
||||
{
|
||||
if(
|
||||
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
|
||||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
|
||||
ffStrbufCompS(&value->name, "coretemp") == 0
|
||||
ffStrbufEqualS(&value->name, "k10temp") ||
|
||||
ffStrbufEqualS(&value->name, "coretemp")
|
||||
) return value->value;
|
||||
}
|
||||
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
static void parseIsa(FFstrbuf* cpuIsa)
|
||||
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
|
||||
{
|
||||
// Always use the last part of the ISA string. Ref: #590 #1204
|
||||
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||
|
||||
if(ffStrbufStartsWithS(cpuIsa, "rv"))
|
||||
{
|
||||
// RISC-V ISA string example: "rv64imafdch_zicsr_zifencei".
|
||||
@@ -290,31 +317,53 @@ static void parseIsa(FFstrbuf* cpuIsa)
|
||||
}
|
||||
// The final ISA output of the above example is "rv64gch".
|
||||
}
|
||||
if(ffStrbufStartsWithS(cpuIsa, "mips"))
|
||||
{
|
||||
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -340,9 +389,12 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
|
||||
|
||||
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
if(cpuUarch.length > 0)
|
||||
{
|
||||
if(cpu->name.length > 0)
|
||||
@@ -357,6 +409,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
ffStrbufAppendC(&cpu->name, ' ');
|
||||
ffStrbufAppend(&cpu->name, &cpuIsa);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __arm__ || __aarch64__
|
||||
uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16);
|
||||
@@ -365,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)
|
||||
|
||||
@@ -29,10 +29,10 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id");
|
||||
ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
if (kn->value.ui32 > cpu->frequencyBase)
|
||||
cpu->frequencyBase = kn->value.ui32;
|
||||
}
|
||||
|
||||
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
||||
if (ks && kstat_read(kc, ks, NULL) >= 0)
|
||||
|
||||
@@ -54,31 +54,6 @@ typedef struct FFSmbiosProcessorInfo
|
||||
static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30,
|
||||
"FFSmbiosProcessorInfo: Wrong struct alignment");
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
inline static const char* detectSpeedByCpuid(FFCPUResult* cpu)
|
||||
{
|
||||
uint32_t base = 0, max = 0, bus = 0, unused = 0;
|
||||
if (!__get_cpuid(0x16, &base, &max, &bus, &unused))
|
||||
return "Unsupported instruction";
|
||||
|
||||
// cpuid returns 0 MHz when hyper-v is enabled
|
||||
if (base) cpu->frequencyBase = base;
|
||||
if (max) cpu->frequencyMax = max;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
|
||||
{
|
||||
return "Unsupported platform";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
@@ -193,7 +168,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
detectSpeedByCpuid(cpu);
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (options->showPeCoreCount) detectCoreTypes(cpu);
|
||||
|
||||
if (cpu->frequencyMax == 0)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -72,7 +72,7 @@ static bool isPhysicalDevice(const struct mntent* device)
|
||||
) return false;
|
||||
|
||||
// https://source.android.com/docs/core/ota/apex?hl=zh-cn
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
return false;
|
||||
|
||||
#endif // __ANDROID__
|
||||
@@ -240,8 +240,16 @@ static void detectStats(FFDisk* disk)
|
||||
disk->bytesAvailable = fs.f_bavail * fs.f_frsize;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
if (fs.f_files >= fs.f_ffree)
|
||||
{
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Windows filesystem in WSL
|
||||
disk->filesTotal = disk->filesUsed = 0;
|
||||
}
|
||||
|
||||
if(fs.f_flag & ST_RDONLY)
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
|
||||
@@ -37,24 +37,23 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInit(&device->name);
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
|
||||
if (ffAppendFileBuffer(pathSysBlock, &device->name))
|
||||
if (ffAppendFileBuffer(pathSysBlock, &name))
|
||||
{
|
||||
ffStrbufTrimRightSpace(&device->name);
|
||||
if (device->name.length > 0)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
ffStrbufTrimRightSpace(&name);
|
||||
if (name.length > 0)
|
||||
ffStrbufAppendC(&name, ' ');
|
||||
}
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
|
||||
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||
ffStrbufTrimRightSpace(&device->name);
|
||||
ffAppendFileBuffer(pathSysBlock, &name);
|
||||
ffStrbufTrimRightSpace(&name);
|
||||
|
||||
if (device->name.length == 0)
|
||||
ffStrbufSetS(&device->name, devName);
|
||||
if (name.length == 0)
|
||||
ffStrbufSetS(&name, devName);
|
||||
else if (ffStrStartsWith(devName, "nvme"))
|
||||
{
|
||||
int devid, nsid;
|
||||
@@ -69,17 +68,13 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (multiNs)
|
||||
{
|
||||
// In Asahi Linux, there are multiple namespaces for the same NVMe drive.
|
||||
ffStrbufAppendF(&device->name, " - %d", nsid);
|
||||
ffStrbufAppendF(&name, " - %d", nsid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// I/Os merges sectors ticks ...
|
||||
@@ -94,6 +89,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
continue;
|
||||
}
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
|
||||
device->bytesRead = sectorRead * 512;
|
||||
device->bytesWritten = sectorWritten * 512;
|
||||
|
||||
@@ -89,10 +89,12 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
display->bitDepth = (uint8_t) bitDepth;
|
||||
}
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
if (CoreDisplay_Display_IsHDRModeEnabled)
|
||||
{
|
||||
display->hdrEnabled = CoreDisplay_Display_IsHDRModeEnabled(screen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
CGDisplayModeRelease(mode);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,17 +1,41 @@
|
||||
#include "editor.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/library.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/path.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
static inline char* realpath(const char* restrict file_name, char* restrict resolved_name)
|
||||
{
|
||||
return _fullpath(resolved_name, file_name, _MAX_PATH);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool extractNvimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(str, "NVIM v")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool extractVimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
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, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(str, "GNU nano ")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* ffDetectEditor(FFEditorResult* result)
|
||||
{
|
||||
ffStrbufSetS(&result->name, getenv("VISUAL"));
|
||||
@@ -26,41 +50,26 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
return "$VISUAL or $EDITOR not set";
|
||||
}
|
||||
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
if (result->name.chars[0] != '/')
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->path, (char* const[]){
|
||||
FASTFETCH_TARGET_DIR_USR "/bin/which",
|
||||
result->name.chars,
|
||||
NULL,
|
||||
}) != NULL || result->path.length == 0)
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (!(result->name.length > 3 && ffCharIsEnglishAlphabet(result->name.chars[0]) && result->name.chars[1] == ':' && result->name.chars[2] == '\\'))
|
||||
{
|
||||
char buf[32];
|
||||
uint32_t len = GetSystemDirectoryA(buf, sizeof(buf));
|
||||
if (len < strlen("C:\\WINDOWS\\system32")) return NULL;
|
||||
strncpy(buf + len, "\\where.exe", sizeof(buf) - len);
|
||||
if (ffProcessAppendStdOut(&result->path, (char* const[]){
|
||||
buf,
|
||||
result->name.chars,
|
||||
NULL,
|
||||
}) != NULL || result->path.length == 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
if (ffIsAbsolutePath(result->name.chars))
|
||||
ffStrbufSet(&result->path, &result->name);
|
||||
else
|
||||
{
|
||||
const char* error = ffFindExecutableInPath(result->name.chars, &result->path);
|
||||
if (error) return NULL;
|
||||
}
|
||||
|
||||
char buf[PATH_MAX + 1];
|
||||
if (!realpath(result->path.chars, buf))
|
||||
return NULL;
|
||||
{
|
||||
char buf[PATH_MAX + 1];
|
||||
if (!realpath(result->path.chars, buf))
|
||||
return NULL;
|
||||
|
||||
ffStrbufSetS(&result->path, buf);
|
||||
// WIN32: Should we handle scoop shim exe here?
|
||||
|
||||
#ifdef __linux__
|
||||
if (!ffStrEndsWith(buf, "/snap"))
|
||||
#endif
|
||||
ffStrbufSetS(&result->path, buf);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t index = ffStrbufLastIndexC(&result->path,
|
||||
@@ -82,6 +91,17 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
if (ffStrbufEqualS(&result->exe, "nvim"))
|
||||
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, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
|
||||
else if (ffStrbufEqualS(&result->exe, "nano"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
|
||||
|
||||
if (result->version.length > 0) return NULL;
|
||||
|
||||
const char* param = NULL;
|
||||
if (
|
||||
ffStrbufEqualS(&result->exe, "nano") ||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
#include "initsystem.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/linux/elf.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"))
|
||||
{
|
||||
ffElfExtractStrings(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"))
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -9,12 +9,12 @@ const char* ffDetectLoadavg(double result[3])
|
||||
|
||||
// Don't use syscall for container compatibility. #620
|
||||
char buf[64];
|
||||
ssize_t nRead = ffReadFileData("/proc/uptime", sizeof(buf) - 1, buf);
|
||||
ssize_t nRead = ffReadFileData("/proc/loadavg", sizeof(buf) - 1, buf);
|
||||
if (nRead > 0)
|
||||
{
|
||||
buf[nRead] = '\0';
|
||||
|
||||
if (sscanf(buf, "%lf %lf %lf", &result[0], &result[1], &result[2]) == 3)
|
||||
if (sscanf(buf, "%lf%lf%lf", &result[0], &result[1], &result[2]) == 3)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,19 +8,9 @@ void ffDetectLocale(FFstrbuf* result)
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
ffStrbufAppendS(result, getenv("LC_MESSAGES"));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
ffStrbufAppendS(result, getenv("LANG"));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
#ifdef LC_MESSAGES
|
||||
ffStrbufAppendS(result, setlocale(LC_MESSAGES, NULL));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
ffStrbufAppendS(result, setlocale(LC_TIME, NULL));
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ typedef struct FFLocalIpResult
|
||||
FFstrbuf ipv6;
|
||||
FFstrbuf mac;
|
||||
int32_t mtu;
|
||||
int32_t speed;
|
||||
bool defaultRoute;
|
||||
} FFLocalIpResult;
|
||||
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/sockios.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
#include <netpacket/packet.h>
|
||||
@@ -40,6 +46,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->mtu = -1;
|
||||
ip->speed = -1;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
@@ -172,9 +179,388 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, iface->name.chars, IFNAMSIZ - 1);
|
||||
|
||||
if (ioctl(sockfd, SIOCGIFMTU, &ifr) == 0)
|
||||
iface->mtu = (int32_t) ifr.ifr_mtu;
|
||||
|
||||
#ifdef __linux__
|
||||
struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET };
|
||||
ifr.ifr_data = (void*) &edata;
|
||||
if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0)
|
||||
iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android
|
||||
#elif __FreeBSD__ || __APPLE__
|
||||
struct ifmediareq ifmr = {};
|
||||
strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1);
|
||||
if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0)
|
||||
{
|
||||
switch (IFM_SUBTYPE(ifmr.ifm_active))
|
||||
{
|
||||
#ifdef IFM_HPNA_1
|
||||
case IFM_HPNA_1:
|
||||
#endif
|
||||
iface->speed = 1; break;
|
||||
#ifdef IFM_1000_CX
|
||||
case IFM_1000_CX:
|
||||
#endif
|
||||
#ifdef IFM_1000_CX_SGMII
|
||||
case IFM_1000_CX_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_1000_KX
|
||||
case IFM_1000_KX:
|
||||
#endif
|
||||
#ifdef IFM_1000_LX
|
||||
case IFM_1000_LX:
|
||||
#endif
|
||||
#ifdef IFM_1000_SGMII
|
||||
case IFM_1000_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_1000_SX
|
||||
case IFM_1000_SX:
|
||||
#endif
|
||||
#ifdef IFM_1000_T
|
||||
case IFM_1000_T:
|
||||
#endif
|
||||
iface->speed = 1000; break;
|
||||
#ifdef IFM_100G_AUI2
|
||||
case IFM_100G_AUI2:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI2_AC
|
||||
case IFM_100G_AUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI4
|
||||
case IFM_100G_AUI4:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI4_AC
|
||||
case IFM_100G_AUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI2
|
||||
case IFM_100G_CAUI2:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI2_AC
|
||||
case IFM_100G_CAUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI4
|
||||
case IFM_100G_CAUI4:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI4_AC
|
||||
case IFM_100G_CAUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CP2
|
||||
case IFM_100G_CP2:
|
||||
#endif
|
||||
#ifdef IFM_100G_CR4
|
||||
case IFM_100G_CR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_CR_PAM4
|
||||
case IFM_100G_CR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_DR
|
||||
case IFM_100G_DR:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR2_PAM4
|
||||
case IFM_100G_KR2_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR4
|
||||
case IFM_100G_KR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR_PAM4
|
||||
case IFM_100G_KR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_LR4
|
||||
case IFM_100G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_SR2
|
||||
case IFM_100G_SR2:
|
||||
#endif
|
||||
#ifdef IFM_100G_SR4
|
||||
case IFM_100G_SR4:
|
||||
#endif
|
||||
iface->speed = 100000; break;
|
||||
#ifdef IFM_100_FX
|
||||
case IFM_100_FX:
|
||||
#endif
|
||||
#ifdef IFM_100_SGMII
|
||||
case IFM_100_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_100_T
|
||||
case IFM_100_T:
|
||||
#endif
|
||||
#ifdef IFM_100_T2
|
||||
case IFM_100_T2:
|
||||
#endif
|
||||
#ifdef IFM_100_T4
|
||||
case IFM_100_T4:
|
||||
#endif
|
||||
#ifdef IFM_100_TX
|
||||
case IFM_100_TX:
|
||||
#endif
|
||||
#ifdef IFM_100_VG
|
||||
case IFM_100_VG:
|
||||
#endif
|
||||
iface->speed = 100; break;
|
||||
#ifdef IFM_10G_AOC
|
||||
case IFM_10G_AOC:
|
||||
#endif
|
||||
#ifdef IFM_10G_CR1
|
||||
case IFM_10G_CR1:
|
||||
#endif
|
||||
#ifdef IFM_10G_CX4
|
||||
case IFM_10G_CX4:
|
||||
#endif
|
||||
#ifdef IFM_10G_ER
|
||||
case IFM_10G_ER:
|
||||
#endif
|
||||
#ifdef IFM_10G_KR
|
||||
case IFM_10G_KR:
|
||||
#endif
|
||||
#ifdef IFM_10G_KX4
|
||||
case IFM_10G_KX4:
|
||||
#endif
|
||||
#ifdef IFM_10G_LR
|
||||
case IFM_10G_LR:
|
||||
#endif
|
||||
#ifdef IFM_10G_LRM
|
||||
case IFM_10G_LRM:
|
||||
#endif
|
||||
#ifdef IFM_10G_SFI
|
||||
case IFM_10G_SFI:
|
||||
#endif
|
||||
#ifdef IFM_10G_SR
|
||||
case IFM_10G_SR:
|
||||
#endif
|
||||
#ifdef IFM_10G_T
|
||||
case IFM_10G_T:
|
||||
#endif
|
||||
#ifdef IFM_10G_TWINAX
|
||||
case IFM_10G_TWINAX:
|
||||
#endif
|
||||
#ifdef IFM_10G_TWINAX_LONG
|
||||
case IFM_10G_TWINAX_LONG:
|
||||
#endif
|
||||
iface->speed = 10000; break;
|
||||
#ifdef IFM_10_2
|
||||
case IFM_10_2:
|
||||
#endif
|
||||
#ifdef IFM_10_5
|
||||
case IFM_10_5:
|
||||
#endif
|
||||
#ifdef IFM_10_FL
|
||||
case IFM_10_FL:
|
||||
#endif
|
||||
#ifdef IFM_10_STP
|
||||
case IFM_10_STP:
|
||||
#endif
|
||||
#ifdef IFM_10_T
|
||||
case IFM_10_T:
|
||||
#endif
|
||||
iface->speed = 10; break;
|
||||
#ifdef IFM_200G_AUI4
|
||||
case IFM_200G_AUI4:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI4_AC
|
||||
case IFM_200G_AUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI8
|
||||
case IFM_200G_AUI8:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI8_AC
|
||||
case IFM_200G_AUI8_AC:
|
||||
#endif
|
||||
#ifdef IFM_200G_CR4_PAM4
|
||||
case IFM_200G_CR4_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_200G_DR4
|
||||
case IFM_200G_DR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_FR4
|
||||
case IFM_200G_FR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_KR4_PAM4
|
||||
case IFM_200G_KR4_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_200G_LR4
|
||||
case IFM_200G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_SR4
|
||||
case IFM_200G_SR4:
|
||||
#endif
|
||||
iface->speed = 200000; break;
|
||||
#ifdef IFM_20G_KR2
|
||||
case IFM_20G_KR2:
|
||||
#endif
|
||||
iface->speed = 20000; break;
|
||||
#ifdef IFM_2500_KX
|
||||
case IFM_2500_KX:
|
||||
#endif
|
||||
#ifdef IFM_2500_SX
|
||||
case IFM_2500_SX:
|
||||
#endif
|
||||
#ifdef IFM_2500_T
|
||||
case IFM_2500_T:
|
||||
#endif
|
||||
#ifdef IFM_2500_X
|
||||
case IFM_2500_X:
|
||||
#endif
|
||||
iface->speed = 2500; break;
|
||||
#ifdef IFM_25G_ACC
|
||||
case IFM_25G_ACC:
|
||||
#endif
|
||||
#ifdef IFM_25G_AOC
|
||||
case IFM_25G_AOC:
|
||||
#endif
|
||||
#ifdef IFM_25G_AUI
|
||||
case IFM_25G_AUI:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR
|
||||
case IFM_25G_CR:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR1
|
||||
case IFM_25G_CR1:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR_S
|
||||
case IFM_25G_CR_S:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR
|
||||
case IFM_25G_KR:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR1
|
||||
case IFM_25G_KR1:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR_S
|
||||
case IFM_25G_KR_S:
|
||||
#endif
|
||||
#ifdef IFM_25G_LR
|
||||
case IFM_25G_LR:
|
||||
#endif
|
||||
#ifdef IFM_25G_PCIE
|
||||
case IFM_25G_PCIE:
|
||||
#endif
|
||||
#ifdef IFM_25G_SR
|
||||
case IFM_25G_SR:
|
||||
#endif
|
||||
#ifdef IFM_25G_T
|
||||
case IFM_25G_T:
|
||||
#endif
|
||||
iface->speed = 25000; break;
|
||||
#ifdef IFM_400G_AUI8
|
||||
case IFM_400G_AUI8:
|
||||
#endif
|
||||
#ifdef IFM_400G_AUI8_AC
|
||||
case IFM_400G_AUI8_AC:
|
||||
#endif
|
||||
#ifdef IFM_400G_DR4
|
||||
case IFM_400G_DR4:
|
||||
#endif
|
||||
#ifdef IFM_400G_FR8
|
||||
case IFM_400G_FR8:
|
||||
#endif
|
||||
#ifdef IFM_400G_LR8
|
||||
case IFM_400G_LR8:
|
||||
#endif
|
||||
iface->speed = 400000; break;
|
||||
#ifdef IFM_40G_CR4
|
||||
case IFM_40G_CR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_ER4
|
||||
case IFM_40G_ER4:
|
||||
#endif
|
||||
#ifdef IFM_40G_KR4
|
||||
case IFM_40G_KR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_LR4
|
||||
case IFM_40G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_SR4
|
||||
case IFM_40G_SR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLAUI
|
||||
case IFM_40G_XLAUI:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLAUI_AC
|
||||
case IFM_40G_XLAUI_AC:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLPPI
|
||||
case IFM_40G_XLPPI:
|
||||
#endif
|
||||
#ifdef IFM_40G_LM4
|
||||
case IFM_40G_LM4:
|
||||
#endif
|
||||
iface->speed = 40000; break;
|
||||
#ifdef IFM_5000_KR
|
||||
case IFM_5000_KR:
|
||||
#endif
|
||||
#ifdef IFM_5000_KR1
|
||||
case IFM_5000_KR1:
|
||||
#endif
|
||||
#ifdef IFM_5000_KR_S
|
||||
case IFM_5000_KR_S:
|
||||
#endif
|
||||
#ifdef IFM_5000_T
|
||||
case IFM_5000_T:
|
||||
#endif
|
||||
iface->speed = 5000; break;
|
||||
#ifdef IFM_50G_AUI1
|
||||
case IFM_50G_AUI1:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI1_AC
|
||||
case IFM_50G_AUI1_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI2
|
||||
case IFM_50G_AUI2:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI2_AC
|
||||
case IFM_50G_AUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_CP
|
||||
case IFM_50G_CP:
|
||||
#endif
|
||||
#ifdef IFM_50G_CR2
|
||||
case IFM_50G_CR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_FR
|
||||
case IFM_50G_FR:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR2
|
||||
case IFM_50G_KR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR_PAM4
|
||||
case IFM_50G_KR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_50G_LAUI2
|
||||
case IFM_50G_LAUI2:
|
||||
#endif
|
||||
#ifdef IFM_50G_LAUI2_AC
|
||||
case IFM_50G_LAUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_LR
|
||||
case IFM_50G_LR:
|
||||
#endif
|
||||
#ifdef IFM_50G_LR2
|
||||
case IFM_50G_LR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_PCIE
|
||||
case IFM_50G_PCIE:
|
||||
#endif
|
||||
#ifdef IFM_50G_SR
|
||||
case IFM_50G_SR:
|
||||
#endif
|
||||
#ifdef IFM_50G_SR2
|
||||
case IFM_50G_SR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR4
|
||||
case IFM_50G_KR4:
|
||||
#endif
|
||||
iface->speed = 50000; break;
|
||||
#ifdef IFM_56G_R4
|
||||
case IFM_56G_R4:
|
||||
#endif
|
||||
iface->speed = 56000; break;
|
||||
default:
|
||||
iface->speed = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __sun
|
||||
if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->ipv6);
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->speed = -1;
|
||||
ip->mtu = -1;
|
||||
}
|
||||
else
|
||||
@@ -150,7 +151,11 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
}
|
||||
|
||||
if (!newIp)
|
||||
FF_LIST_GET(FFLocalIpResult, *results, results->length - 1)->mtu = (int32_t) adapter->Mtu;
|
||||
{
|
||||
FFLocalIpResult* result = FF_LIST_GET(FFLocalIpResult, *results, results->length - 1);
|
||||
result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000);
|
||||
result->mtu = (int32_t) adapter->Mtu;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 };
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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%");
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef struct FFPackagesResult
|
||||
uint32_t guixHome;
|
||||
uint32_t guixSystem;
|
||||
uint32_t guixUser;
|
||||
uint32_t linglong;
|
||||
uint32_t lpkg;
|
||||
uint32_t lpkgbuild;
|
||||
uint32_t nixDefault;
|
||||
|
||||
@@ -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)
|
||||
@@ -471,6 +471,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
|
||||
{
|
||||
packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile");
|
||||
}
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", DT_DIR);
|
||||
}
|
||||
|
||||
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/linux/elf.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
static const char* getSystemMonospaceFont(void)
|
||||
{
|
||||
@@ -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 = ffElfExtractStrings(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);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "common/processing.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef __FreeBSD__
|
||||
@@ -63,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;
|
||||
}
|
||||
|
||||
@@ -188,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)
|
||||
{
|
||||
@@ -202,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;
|
||||
|
||||
@@ -210,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"))
|
||||
@@ -250,8 +287,24 @@ FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version)
|
||||
return version->length > 0;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
|
||||
static bool extractGeneralVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
if (!ffCharIsDigit(str[0])) return true;
|
||||
int count = 0;
|
||||
sscanf(str, "%*d.%*d.%*d%n", &count);
|
||||
if (count == 0) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str);
|
||||
return false;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
if (exe->chars[0] == '/')
|
||||
{
|
||||
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
|
||||
if (version->length) return true;
|
||||
}
|
||||
|
||||
if(ffProcessAppendStdOut(version, (char* const[]){
|
||||
"gnome-terminal",
|
||||
"--version",
|
||||
@@ -264,6 +317,17 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
|
||||
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[]){
|
||||
@@ -311,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
|
||||
@@ -516,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
|
||||
@@ -590,7 +658,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(processName, "gnome-terminal"))
|
||||
return getTerminalVersionGnome(version);
|
||||
return getTerminalVersionGnome(exe, version);
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(processName, "konsole"))
|
||||
return getTerminalVersionKonsole(exe, version);
|
||||
@@ -599,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");
|
||||
@@ -384,6 +384,14 @@ const FFShellResult* ffDetectShell()
|
||||
result.tty = -1;
|
||||
|
||||
pid_t ppid = getppid();
|
||||
|
||||
const char* ignoreParent = getenv("FFTS_IGNORE_PARENT");
|
||||
if (ignoreParent && ffStrEquals(ignoreParent, "1"))
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY _ = ffStrbufCreate();
|
||||
ffProcessGetBasicInfoLinux(ppid, &_, &ppid, NULL);
|
||||
}
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
getUserShellFromEnv(&result);
|
||||
setShellInfoDetails(&result);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
@@ -37,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)
|
||||
{
|
||||
@@ -345,6 +346,10 @@ const FFShellResult* ffDetectShell(void)
|
||||
if(!ffProcessGetInfoWindows(0, &ppid, NULL, NULL, NULL, NULL, NULL))
|
||||
return &result;
|
||||
|
||||
const char* ignoreParent = getenv("FFTS_IGNORE_PARENT");
|
||||
if (ignoreParent && ffStrEquals(ignoreParent, "1"))
|
||||
ffProcessGetInfoWindows(ppid, &ppid, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
|
||||
if (result.processName.length > 0)
|
||||
@@ -354,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,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;
|
||||
}
|
||||
|
||||
@@ -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,8 +1,8 @@
|
||||
#include "version.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64)
|
||||
#if defined(__x86_64__)
|
||||
#define FF_ARCHITECTURE "x86_64"
|
||||
#elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(__i586__) || defined(__i586) || defined(__i686__) || defined(__i686)
|
||||
#elif defined(__i386__)
|
||||
#define FF_ARCHITECTURE "i386"
|
||||
#elif defined(__aarch64__)
|
||||
#define FF_ARCHITECTURE "aarch64"
|
||||
@@ -16,6 +16,8 @@
|
||||
#define FF_ARCHITECTURE "riscv"
|
||||
#elif defined(__s390x__)
|
||||
#define FF_ARCHITECTURE "s390x"
|
||||
#elif defined(__loongarch__)
|
||||
#define FF_ARCHITECTURE "loongarch"
|
||||
#else
|
||||
#define FF_ARCHITECTURE "unknown"
|
||||
#endif
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 *);
|
||||
@@ -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 */);
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "zpool.h"
|
||||
|
||||
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result /* list of FFZpoolResult */)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -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, "-"))
|
||||
|
||||
@@ -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
@@ -1,19 +1,19 @@
|
||||
${c1} ___________
|
||||
/ \
|
||||
/ ${c2}______${c1} \
|
||||
/ ${c2}/ \${c1} \
|
||||
| ${c2}( )${c1} \
|
||||
/ ${c2}\______/${c1} |
|
||||
| |
|
||||
/ \
|
||||
| |
|
||||
| |
|
||||
/ |
|
||||
| |
|
||||
| _______ |
|
||||
____/ / \ |
|
||||
/ | | |
|
||||
| / ____/ |
|
||||
\_________/ / |
|
||||
\ __/
|
||||
\_______/
|
||||
___________
|
||||
/ \
|
||||
/ ${c2}______${c1} \
|
||||
/ ${c2}/ \${c1} \
|
||||
| ${c2}( )${c1} \
|
||||
/ ${c2}\______/${c1} |
|
||||
| |
|
||||
/ \
|
||||
| |
|
||||
| |
|
||||
/ |
|
||||
| |
|
||||
| _______ |
|
||||
____/ / \ |
|
||||
/ | | |
|
||||
| / ____/ |
|
||||
\_________/ / |
|
||||
\ __/
|
||||
\_______/
|
||||
@@ -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
|
||||
@@ -0,0 +1,20 @@
|
||||
..',;;;;;;,,..
|
||||
..,;;;;;;;;;;;;;;;;,..
|
||||
.';;;;;;;;;;;;;;;;;;;;;;;;,.
|
||||
.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'
|
||||
.;;;;;;;;;$2clodddol:$1;;;;;;;;;;;;;;;;.
|
||||
';;;;;;;$2ckXWWWNNWWWN0d:$1;;;;;;;;;;;;;;'
|
||||
';;;;;;$2cOWWKxl:$1;;;:$2okXWXx$1;;;;;;;;;;;;;;,
|
||||
;;;;;;$2:XWWo$1;;;;;;;;;;;$2ONNx$1;;;;;;;;;;;;;;.
|
||||
,;;;;;;$2xWMk$1;;;;;;;;;;;;;$20NX:$1;;;;;;;;;;;;;;
|
||||
;;;;;;;$2xMMk$1;;;;;;;;;;;;;$2oXNdcloooolc:$1;;;;;
|
||||
,;;;;;;$2:NMWl$1;;;;;;;;;;;;$2ckodKK00000Oc$1;;;;;
|
||||
.;;;;;;;$2cKMWOo:$1;;;;;$2cox0Xccdl:$1;;;;;:;;;;;'
|
||||
;;;;;;;;;$2o0WWNK000KXXKkodKKo$1;;;;;;;;;;;;
|
||||
,;;;;;;;;;$2:loxxxxdlc$1;;;;$2xKKxc$1;;;;;;;;;
|
||||
,;;;;;;;;;;;;;;;;;;;;;;;$2ckK0o;$1;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;$2:l$1;;;;;;.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;.
|
||||
;;;;;;;;;;;;;;;;;;;;;;.
|
||||
';;;;;;;;;;;;,
|
||||
';;'.
|
||||
@@ -0,0 +1,16 @@
|
||||
~. ........
|
||||
::~~ +=: ~:========:~
|
||||
..~:+oo===oo:.~+oooooooooooo+~
|
||||
.:+==ooooooooooo==ooooooooooooooo:
|
||||
.:=oooooooooooooooooooooooooooooooo=
|
||||
.. .=oooooooooooooooooooooooooooooooooo=
|
||||
==. .+ooooooooooooooooooooooooooooooooooo=
|
||||
~+:~:oooooooooooooooooooooooooooooooooooo:
|
||||
~ooooooooooooooooooooooooooooooooooooo=:
|
||||
~oooooooooooooooooooooooooooooooooo==:.
|
||||
.+oooooooooooooooooooooooooo=~::::~..
|
||||
~+oooooooooooooooooooooooo=:
|
||||
.:=ooooooooooooooooooooo=:
|
||||
.:==ooooooooooooooo==:.
|
||||
~~:===oooooo==+:~
|
||||
...~~:~::..
|
||||
@@ -0,0 +1,19 @@
|
||||
${c2}@
|
||||
@@--=====@@
|
||||
@@--==@@ @@====+@
|
||||
@-@@ @==@
|
||||
@=@
|
||||
@=@${c1} @=@ @-==== @=@${c2}
|
||||
@=@${c1} @-===@==++@===+@${c2}
|
||||
@=@${c1} @--====@@=====+@${c2}
|
||||
-=@${c1} @--==========++@${c2}
|
||||
==${c1} @--==========++@${c2} @=@
|
||||
@==${c1} @--=======@==++@${c2} @=+@
|
||||
@==${c1} @-==========++${c2} @=@
|
||||
@==${c1} @-=======@=%${c2} @=@
|
||||
@==${c1} @@@@@@${c2} @=@
|
||||
@====@@@ @@===+%
|
||||
@@=====@@==++++@@
|
||||
=#@=@
|
||||
@==@++@
|
||||
@@@
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user