Compare commits

...

107 Commits

Author SHA1 Message Date
Carter Li 315cb24046 Merge pull request #604 from fastfetch-cli/dev
Fix CI of FreeBSD
2023-11-01 16:06:10 +08:00
李通洲 4cabc5684b CPUUsage: don't count NaN values 2023-11-01 15:55:13 +08:00
李通洲 256c9be19b CPUUsage: skip NaN when summarizing values 2023-11-01 15:49:51 +08:00
李通洲 1b3d713e50 CPUUsage: always print something 2023-11-01 15:36:13 +08:00
李通洲 6e816fca6e CPUUsage: don't hang on weird host
Try fixing CI of FreeBSD
2023-11-01 15:26:24 +08:00
李通洲 5a699af610 OS (macOS): improve performance 2023-11-01 15:24:52 +08:00
Carter Li 390119c592 Merge pull request #603 from fastfetch-cli/dev
Release v2.2.0
2023-11-01 14:04:08 +08:00
李通洲 11d7eec4db Revert "FreeBSD: debug"
This reverts commit 6508ccfc0d.
2023-11-01 12:22:28 +08:00
李通洲 f59be1faf2 Release v2.2.0 2023-11-01 11:29:03 +08:00
李通洲 7bc4c63eb4 Migration: don't overwrite existing files 2023-11-01 11:28:08 +08:00
李通洲 4bf9f524d9 Logo (Builtin): add Interix 2023-11-01 11:16:16 +08:00
李通洲 6508ccfc0d FreeBSD: debug 2023-11-01 09:52:15 +08:00
李通洲 d0a8d3cdc4 TerminalFont (Linux): early return 2023-11-01 09:42:52 +08:00
李通洲 494cc1493e TerminalFont (Linux): support xfce4-terminal 1.1.0+
Fixes #602
2023-11-01 09:40:49 +08:00
李通洲 761c649817 TerminalShell: better support for environment running with su 2023-11-01 08:55:00 +08:00
李通洲 a2f576f3e5 GPU (WSL): support nvml too 2023-11-01 00:10:24 +08:00
李通洲 3b9b03a086 FreeBSD: fix build 2023-10-31 23:45:38 +08:00
李通洲 ab51a209d7 CI: try fixing FreeBSD build 2023-10-31 22:53:06 +08:00
李通洲 38ac339011 WM: support WindowBlinds detection 2023-10-31 22:40:44 +08:00
李通洲 b4777fe73a Windows: silence compiler warnings 2023-10-31 22:40:44 +08:00
李通洲 b6e759f3a2 LocalIP / NetIO: make defaultRouteOnly defaults to true 2023-10-31 19:53:25 +08:00
李通洲 9ddefbc1a2 Doc: update README 2023-10-31 16:32:57 +08:00
李通洲 a16851f5de JsonConfig: update json schema; change most title to description 2023-10-31 15:47:55 +08:00
李通洲 8fe291d161 Doc: remove information of flag based configuration 2023-10-31 15:47:23 +08:00
李通洲 9ac50fc42f GPU: add more vendors 2023-10-31 15:11:22 +08:00
李通洲 c6e5221826 CMake: build with ASAN conditionally 2023-10-31 14:57:32 +08:00
李通洲 5b2006cd06 Global: get rid of locks
Psychological burden NO MORE
2023-10-31 14:42:45 +08:00
李通洲 d3f673dc6f Init: remove separate thread of displayserver and qt/gtk stuff detection
These threads are detached. If the main thread exits before the sub threads end, fastfetch may crash in various ways.

It barely benefits performance. `hyperfine` shows completely no difference between `--thread` enabled and disabled. Let's get rid of it.
2023-10-31 14:32:30 +08:00
李通洲 b99f444234 Global: remove --allow-slow-operations 2023-10-31 14:10:21 +08:00
李通洲 c504096181 Processing (Linux): fix hanging if a child process prints to both stdout and stderr 2023-10-31 14:06:08 +08:00
李通洲 c9ef47271a Brightness: fix flag --brightness-ddcci-sleep 2023-10-31 10:09:31 +08:00
李通洲 fc3891c913 DE: implement --de-slow-version-detection 2023-10-31 10:07:41 +08:00
李通洲 cd07354b6f Doc: update changelog and other docs 2023-10-31 09:50:54 +08:00
kojq fd5aeb2052 Update structure.txt (#600)
add swap information as default
2023-10-30 20:27:10 -05:00
李通洲 b1b583721a Logo (Builtin): add MainsailOS
Ref: https://github.com/dylanaraps/neofetch/pull/2407
2023-10-31 09:15:15 +08:00
李通洲 4c3372a886 Logo (Builtin): fix phyOS 2023-10-31 08:51:56 +08:00
李通洲 cf66679323 DE: move version detection code to separate files 2023-10-30 22:46:38 +08:00
李通洲 55b41144db WM: add flag --wm-detect-plugin 2023-10-30 16:34:35 +08:00
李通洲 ae34208247 Battery (Windows): add flag --battery-use-setup-api 2023-10-30 14:49:00 +08:00
李通洲 b462006280 Chassis (Windows): add flag --chassis-use-wmi 2023-10-30 14:31:19 +08:00
李通洲 485bcbf054 GPU: add flag --gpu-use-nvml 2023-10-30 13:46:51 +08:00
李通洲 2e30a57889 TerminalFont: always use kitten to detect kitty term fonts 2023-10-30 11:05:43 +08:00
李通洲 b439d9c203 Doc: we use Apple80211 instead of IO80211 2023-10-30 09:21:01 +08:00
李通洲 08a717f5f7 JsonConfig: more friendly error message 2023-10-30 09:14:13 +08:00
李通洲 3a84a1a5fa Packages (Windows): add option --packages-winget 2023-10-29 19:37:31 +08:00
李通洲 627d5fc659 JsonConfig: restructure some keys 2023-10-29 00:17:24 +08:00
李通洲 25849dc4bb Migration (Logo): fix --logo-color-num (v2) 2023-10-28 23:39:15 +08:00
李通洲 63032cd840 Doc: update help.txt 2023-10-28 23:02:28 +08:00
李通洲 2414246de9 Migration (Logo): fix --logo-color-num 2023-10-28 21:52:28 +08:00
李通洲 c52353b4b8 Vulkan: remove used GPU memory detection, which is unreliable
Ref: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_memory_budget.html#_description
2023-10-28 20:25:39 +08:00
李通洲 799628c083 GPU: guard nvml related code behind --allow-slow-operations 2023-10-28 17:23:49 +08:00
李通洲 38d5791d57 GPU: support memory, core count detection 2023-10-28 13:56:43 +08:00
李通洲 9d664e2b61 GPU (Linux): support driver version detection 2023-10-28 13:11:04 +08:00
李通洲 2eb21e3521 TerminalFont: fix memleaks 2023-10-28 13:00:45 +08:00
李通洲 bfe1265c44 Logo (Builtin): add azos
Ref: https://github.com/dylanaraps/neofetch/pull/2339
2023-10-27 22:57:16 +08:00
李通洲 dd3109cd89 GPU: better nvidia GPU temp detection 2023-10-27 21:16:03 +08:00
Carter Li 130d5a5202 Sound (macOS): fix no sound devices detected error on old macOS version 2023-10-27 17:35:28 +08:00
Carter Li cda4c62e9e macOS: fix building on old macOS version 2023-10-27 16:59:10 +08:00
李通洲 df245f32ec FFlist: add FF_LIST_GET
this macro can be safer to use than `ffListGet` because it detects wrong type convertion
2023-10-27 12:02:01 +08:00
李通洲 04409f4381 Wifi (macOS): better (or worse) support of security detection 2023-10-27 12:02:01 +08:00
李通洲 155e4a5b80 Doc: update doc for --migrate-config 2023-10-27 00:00:48 +08:00
李通洲 59a9209621 GPU: support Nvidia GPU temp detection 2023-10-27 00:00:19 +08:00
李通洲 cd5e14a834 LM (Linux): tidy 2023-10-26 23:27:40 +08:00
李通洲 e707cf8464 Migration: deprecate --gen-config conf 2023-10-26 16:34:38 +08:00
李通洲 8bdd410e97 Migration: support specifying config file path 2023-10-26 16:22:05 +08:00
李通洲 f45654620f Global: code refactor 2023-10-26 15:39:28 +08:00
李通洲 72d138f8c4 Migration (Modules): only generate objects when necessary 2023-10-26 14:28:47 +08:00
李通洲 6a0df7ae49 Migration: simplify json result 2023-10-26 14:06:47 +08:00
李通洲 23def0a1c7 Options (Library): add definitions only when used on the platform 2023-10-26 13:55:26 +08:00
李通洲 3236ef075d Migration (Library): support library options 2023-10-26 13:55:26 +08:00
李通洲 d00b301904 Migration (General): support general options 2023-10-26 13:55:26 +08:00
李通洲 6c82686283 Migration (Display): support display options 2023-10-26 13:55:21 +08:00
李通洲 399e2235d4 Options (Display): split code 2023-10-26 10:26:15 +08:00
李通洲 bd898e4006 Wifi (macOS): additional fix of Sonoma compatibility 2023-10-26 09:50:51 +08:00
李通洲 2c49dcceaf Options (Library): split code 2023-10-25 16:24:24 +08:00
李通洲 3c5b002414 Options (Modules): split code 2023-10-25 15:38:46 +08:00
李通洲 ca37206a49 Options (Logo): renaming symbols 2023-10-25 15:31:13 +08:00
李通洲 8a939e981c Options (General): symbol renaming to prevent from possible naming conflicts 2023-10-25 14:43:15 +08:00
李通洲 bed1b4cf0f Global: move general options to a new separate folder 2023-10-25 13:39:13 +08:00
李通洲 04c3a4ccf7 Logo: move logo options related code to a new folder 2023-10-25 10:44:34 +08:00
李通洲 f50368a949 Migration: support logo 2023-10-25 10:18:07 +08:00
李通洲 4e018dbf26 JsonConfig: code refactor 2023-10-25 09:13:04 +08:00
李通洲 fa02217ff4 Doc: update changelog 2023-10-25 09:03:44 +08:00
Martin Valba 22080d36b0 Add Evolinx distro banner (#596)
* Add Evolinx banner

* Removed accidental local bad save
2023-10-24 22:23:33 +08:00
westpain 3303f4e1ce Add cycledream logo (#595) 2023-10-24 21:15:56 +08:00
李通洲 11d03ad59e TerminalFont: support st 2023-10-24 16:48:22 +08:00
李通洲 504f1533c2 Terminal: support st version detection 2023-10-24 15:57:40 +08:00
李通洲 bf1d1cbac5 Terminal: support urxvt version detection 2023-10-24 15:56:43 +08:00
李通洲 94119d1674 OpenGL (Linux): fix build 2023-10-24 15:17:27 +08:00
李通洲 f4a263df01 Migration: finish modules support 2023-10-24 14:41:29 +08:00
李通洲 533231825c Terminal (Linux): detect tmux: server as tmux 2023-10-24 10:20:41 +08:00
李通洲 40e2787d94 Revert "Terminal (Linux): better support for tmux"
This reverts commit 281af9c86f.
2023-10-24 10:09:43 +08:00
李通洲 281af9c86f Terminal (Linux): better support for tmux 2023-10-23 23:38:18 +08:00
matoro fc0db8c291 Host (Linux): devicetree path for OBP hosts (#591)
At least SPARC devices have their model name in this devicetree node
and do not have a "model" node.  Possibly also POWER Macs, do not have
one to test though.
2023-10-23 23:37:37 +08:00
李通洲 48d2dbad34 Battery (Linux): fix build 2023-10-23 18:42:40 +08:00
李通洲 be2af8aeaf Migration: support bluetooth and board 2023-10-23 16:34:33 +08:00
李通洲 a7621a7301 Break: remove redundant code 2023-10-23 16:33:25 +08:00
李通洲 ec87790e4f Global: init support for JSON config file migration (WIP) 2023-10-23 16:17:07 +08:00
李通洲 44632e9bf6 Global: don't expose internal functions 2023-10-23 13:32:40 +08:00
李通洲 824ada49b6 Global: :%s/generateJson/generateJsonResult/g 2023-10-23 13:32:39 +08:00
李通洲 e7938216ba Global: :%s/ffGenerate\w+Json/$0Result/g 2023-10-23 13:32:39 +08:00
matoro 40d6d0b7b5 CPU (Linux): quirks for MIPS platforms (#590)
CPU name is in "cpu model" field on MIPS.  Also, /proc/cpuinfo contains
an "isa" field, but rather than being a single string like RISC-V it is
instead a space-separated list of every ISA flavor that the chip is
compatible with.  Since these are mostly incremental, just make the
cpuISA value set to the last one.

Before:
```
$ fastfetch --structure "cpu" --logo none
CPU: mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2 (16)
```

After:
```
$ fastfetch --structure "cpu" --logo none
CPU: Cavium Octeon II V0.10 mips64r2 (16)
```
2023-10-22 22:09:43 -05:00
李通洲 3f4d4c8eea GPU: add more vendors 2023-10-21 17:36:13 +08:00
李通洲 e2fe94d4e4 DisplayServer (Android): tidy 2023-10-21 15:44:38 +08:00
李通洲 debb5d8ad1 Display: don't print display type twice 2023-10-21 15:44:08 +08:00
李通洲 f61794ea70 GPU (Windows): better GPU memory and type detection 2023-10-18 10:52:29 +08:00
李通洲 d15a977431 Logo (Builtin): add Black Mesa
Fix #586
2023-10-17 23:46:38 +08:00
232 changed files with 15949 additions and 3115 deletions
+4 -3
View File
@@ -171,11 +171,12 @@ jobs:
uses: actions/checkout@v4
- name: run VM
uses: vmactions/freebsd-vm@v0
uses: cross-platform-actions/action@v0.21.0
with:
prepare: |
pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
operating_system: freebsd
version: '13.2'
run: |
sudo pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package
./fastfetch --list-features
+46
View File
@@ -1,3 +1,47 @@
# 2.2.0
This release introduces a new option `--migrate-config`, which migrates old flag based config file to new JSONC format
Changes:
* `--pipe` and `--stat` are moved from `general` options to `display` options. This affects cjson configuration.
* Display keys `percent*` and `size*` in JSON config are restructured. e.g. `{ "sizeNdigits": 1 }` is now `{ "size": { "ndigits": 1 } }`
* With the introduction of `--migrate-config`, the old flag based config file is deprecated, and will be removed in 3.0.0 (next major version)
* Support of `--gen-config conf` is deprecated accordingly, and will be removed in 2.3.0 (next minor version)
* The global flag `--allow-slow-operations` is splitted into some explicit flags in differnet modules
* `--packages-winget`: control whether `winget` packages count should be detected. Note it's a very slow operation, please enable it with caution.
* `--chassis-use-wmi`: control whether `WMI` query should be used to detect chassis type, which detects more information, but slower. This flag only affects `--chassis-format` and `--format json`.
* `--battery-use-setup-api`: control whether `SetupAPI` should be used on Windows to detect battery info, which supports multi batteries, but slower.
* `--wm-detect-plugin`: control whether WM plugins should be detected. Note it's implemented with global processes enumeration and can report false results.
* `--de-slow-version-detection`: control DE version should be detected with slow operations. It's usually not necessary and only provided as a backup.
* `--localip-default-route-only` and `--netio-default-route-only` defaults to true to avoid large number of results
Features:
* Quirks for MIPS platforms (CPU, Linux)
* Use devicetree path for OBP hosts (Host, Linux)
* Detect `tmux: server` as tmux (Terminal, Linux)
* Support urxvt version detection (Terminal, Linux)
* Support st version detection (Terminal, Linux)
* Support st terminal font detection (TerminalFont, Linux)
* Support xfce4-terminal 1.1.0+ terminal font detection (TerminalFont, Linux)
* Add option `--migrate-config <?target-file-path>`
* Support Nvidia GPU temp and cuda core count detection via nvml. Use `--gpu-use-nvml` to enable it (GPU)
* Try supporting Wifi authentication type detection in macOS Sonoma. Please file a feature request if you get `to be supported (num)` with result of `/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep auth` (Wifi, macOS)
Bugfixes:
* Better GPU memory and type detection (GPU, Windows)
* Don't print display type twice (Display)
* Detect BSSID instead of Wifi MAC address to align with other platforms (Wifi, macOS)
* Remove support of used GPU memory detection, which is not reliable and only supported with `--gpu-force-vulkan`. (GPU)
* Fix flag `--brightness-ddcci-sleep` (Brightness, Linux)
* Fix hanging if a child process prints to both stdout and stderr (Linux)
Logos:
* Add Black Mesa
* Add cycledream
* Add Evolinx
* Add azos
* Add Interix
# 2.1.2
Bugfixes:
@@ -27,6 +71,8 @@ Logo:
* Add Chimera Linux
* Add EndeavourSmall
* Add Xenia
* Add MainsailOS
* Fix phyOS
# 2.1.0
+29 -7
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.1.2
VERSION 2.2.0
LANGUAGES C
DESCRIPTION "Fast system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -70,8 +70,9 @@ 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_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_PCI_MEMORY "Enable detecting GPU memory size with libpci" OFF "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embeded) yyjson library" OFF "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embeded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
@@ -97,7 +98,7 @@ endif()
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
enable_language(CXX)
@@ -116,7 +117,8 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
endif()
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
if(NOT WIN32 AND NOT APPLE)
if(ENABLE_ASAN)
message(STATUS "Address sanitizer enabled (DEBUG only)")
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address")
endif()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
@@ -297,7 +299,6 @@ set(LIBFASTFETCH_SRC
src/logo/image/im7.c
src/logo/image/image.c
src/logo/logo.c
src/logo/option.c
src/modules/battery/battery.c
src/modules/bios/bios.c
src/modules/bluetooth/bluetooth.c
@@ -355,6 +356,11 @@ set(LIBFASTFETCH_SRC
src/modules/wifi/wifi.c
src/modules/wm/wm.c
src/modules/wmtheme/wmtheme.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/FFlist.c
src/util/FFstrbuf.c
@@ -388,6 +394,7 @@ if(LINUX)
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_linux.c
src/detection/gpu/gpu_nvidia.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/icons/icons_linux.c
@@ -416,6 +423,8 @@ if(LINUX)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_linux.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/util/platform/FFPlatform_unix.c
)
@@ -465,6 +474,8 @@ elseif(ANDROID)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_nosupport.c
src/detection/wifi/wifi_android.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/util/platform/FFPlatform_unix.c
)
@@ -494,6 +505,7 @@ elseif(BSD)
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_linux.c
src/detection/gpu/gpu_nvidia.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_bsd.c
src/detection/lm/lm_linux.c
@@ -522,6 +534,8 @@ elseif(BSD)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_bsd.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/util/platform/FFPlatform_unix.c
)
@@ -572,6 +586,8 @@ elseif(APPLE)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_apple.c
src/detection/wifi/wifi_apple.m
src/detection/wm/wm_apple.c
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
@@ -597,6 +613,7 @@ elseif(WIN32)
src/detection/displayserver/displayserver_windows.c
src/detection/font/font_windows.c
src/detection/gpu/gpu_windows.c
src/detection/gpu/gpu_nvidia.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/libc/libc_windows.cpp
@@ -623,6 +640,8 @@ elseif(WIN32)
src/detection/users/users_windows.c
src/detection/wallpaper/wallpaper_windows.c
src/detection/wifi/wifi_windows.c
src/detection/wm/wm_windows.cpp
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_windows.c
src/util/windows/getline.c
src/util/windows/com.cpp
@@ -868,8 +887,11 @@ elseif(APPLE)
PRIVATE "-framework OpenCL"
PRIVATE "-framework SystemConfiguration"
PRIVATE "-weak_framework CoreDisplay"
PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks"
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
PRIVATE "-F /System/Library/PrivateFrameworks"
PRIVATE "-weak_framework DisplayServices"
PRIVATE "-weak_framework MediaRemote"
PRIVATE "-weak_framework Apple80211"
)
elseif(WIN32)
target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601)
+25 -119
View File
@@ -23,147 +23,53 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
## Customization
## Installation
With customization and speed being two competing goals, this project actually builds two executables:
### Linux
* The main one is `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent by modifying `$XDG_CONFIG_HOME/fastfetch/config.conf`. Use `fastfetch --gen-config conf` to generate one. To view the available options, run `fastfetch --help`.
* The second executable is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c).
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `sudo apt install fastfetch-<version>-Linux.deb`
* Arch Linux: `sudo pacman -S fastfetch`
* Fedora: `sudo dnf install fastfetch`
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
Currently, the performance difference is measurable, but too small to be recognizable by humans. But with more options planned, the leap will get bigger over time and on slow machines this might actually make a difference.
There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config <filename>`. They may also serve as a good example for format arguments.
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
### Customization with new JSONC format
A new, structure based, and user-friendly config file format was introduced in v2.0.0. This format is based on [JSONC](https://jsonc.org/). [See more details in Wiki](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration)
## Dependencies
Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl`, `libm` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most Linux distributions.
The following libraries are used if present at runtime:
### Linux and FreeBSD
* [`libpci`](https://github.com/pciutils/pciutils): GPU output.
* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output.
* [`libxcb-randr`](https://xcb.freedesktop.org/),
[`libXrandr`](https://gitlab.freedesktop.org/xorg/lib/libxrandr),
[`libxcb`](https://xcb.freedesktop.org/),
[`libX11`](https://gitlab.freedesktop.org/xorg/lib/libx11): At least one of them sould be present in X11 sessions for better display detection and faster WM detection. The `*randr` ones provide multi monitor support The `libxcb*` ones usually have better performance.
* [`libwayland-client`](https://wayland.freedesktop.org/): Better display performance and output in wayland sessions. Supports different refresh rates per monitor.
* [`libGIO`](https://developer.gnome.org/gio/unstable/): Needed for values that are only stored GSettings.
* [`libDConf`](https://developer.gnome.org/dconf/unstable/): Needed for values that are only stored in DConf + Fallback for GSettings.
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel or kitty graphics protocol.
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art.
* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol.
* [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Bluetooth, Player & Media detection.
* [`libEGL`](https://www.khronos.org/registry/EGL/),
[`libGLX`](https://dri.freedesktop.org/wiki/GLX/),
[`libOSMesa`](https://docs.mesa3d.org/osmesa.html): At least one of them is needed by the OpenGL module for gl context creation.
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count.
* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE.
* [`libnm`](https://networkmanager.dev/docs/libnm/latest/): Used for Wifi detection.
* [`libpulse`](https://freedesktop.org/software/pulseaudio/doxygen/): Used for Sound detection.
* [`libddcutil`](https://github.com/rockowitz/ddcutil): Used for brightness detection of external displays
* [`DirectX-Headers`](https://github.com/microsoft/DirectX-Headers): Used for GPU detection in WSL
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging)
### macOS
* [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system.
* [`DisplayServices`](https://developer.apple.com/forums/thread/666383#663154022): Need for screen brightness detection. It's a private framework provided by newer macOS system.
* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb)
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb)
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb)
* [`libsqlite3`](https://www.sqlite.org/index.html): Used for fast wallpaper detection ( fallback to AppleScript )
For the image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported.
`brew install fastfetch`
### Windows
* [`wlanapi`](https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/): A system dll which isn't supported by Windows Server by default. Used for Wifi info detection.
* [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. [`vulkan-loader`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-loader) [`vulkan-headers`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-headers)
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module. [`opencl-icd`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-opencl-icd)
`scoop install fastfetch`
Note: In Windows 7, 8 and 8.1, [ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html) is required to run fastfetch due to [the lack of ASCII escape code native support](https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows). In addition, as fastfetch for Windows targets [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library, [it must be installed manually](https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c) as UCRT is only pre-installed in Windows 10 and later.
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
For the image logo, WezTerm with iterm image protocol is known to work, surprisingly.
### FreeBSD
### Android
`pkg install fastfetch`
* [`freetype`](https://www.freetype.org/): Used for Termux font detection. [`freetype`](https://github.com/termux/termux-packages/tree/master/packages/freetype)
* [`libvulkan`](https://www.vulkan.org/): Vulkan module, also used for GPU detection. Usually has been provided by Android system. [`vulkan-loader-android`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-loader-android) [`vulkan-headers`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-headers)
* [`termux-api`](https://github.com/termux/termux-api-package): Used for Wifi / Battery detection. Both the package [termux-api](https://github.com/termux/termux-packages/tree/master/packages/termux-api) and the Android app [Termux API](https://github.com/termux/termux-api) must be installed and the app `Termux API` must be configured to be able to self-running. In order to make Wifi detection actuall work, location privilege must be granted to the app `Termux API`. Read [the official doc](https://wiki.termux.com/wiki/Termux:API) for detail.
* [`libandroid-wordexp-static`](https://github.com/termux/termux-packages/tree/master/packages/libandroid-wordexp): `wordexp.h` support for Android.
### Android (Termux)
For the image logo, [Termux Monet](https://github.com/HardcodedCat/termux-monet) supports iterm image protocol.
`pkg install fastfetch`
## Support status
All categories not listed here should work without needing a specific implementation.
## Build from source
##### Available Modules
```
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, DiskIO, Display, Font, Gamepad, GPU, Host, Icons, Kernel, LM, Locale, LocalIP, Media, Memory, Monitor, NetIO, OpenCL, OpenGL, OS, Packages, Player, Power Adapter, Processes, PublicIP, Separator, Shell, Sound, Swap, Terminal, Terminal Font, Terminal Size, Theme, Time, Title, Uptime, Version, Vulkan, Wallpaper, Weather, Wifi, WM, WMTheme
```
See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
##### Builtin logos
## Usage
<!-- `Content of src/logo/builtin.c`.split('\n').map(x => x.trim()).filter(x => x.startsWith('// ')).map(x => x.slice(3)).filter(x => x != 'LAST').sort((a, b)=>a.toUpperCase().localeCompare(b.toUpperCase())).join(', ') -->
```
AerOS, Afterglow, AIX, AlmaLinux, Alpine, Alpine2Small, AlpineSmall, Alter, Amazon, AmazonLinux, AmogOS, Anarchy, Android, AndroidSmall, Antergos, Antix, AoscOS, AoscOS_old, AoscOsRetro, AoscOsRetro_small, Aperture, Apple, AppleSmall, Apricity, Arch, Arch2, ArchBox, Archcraft, Archcraft2, Archlabs, ArchSmall, ArchStrike, ArcoLinux, ArcoLinuxSmall, ArseLinux, Artix, Artix2Small, ArtixSmall, Arya, Asahi, Aster, AsteroidOS, AstOS, Astra, Ataraxia, Athena, Bedrock, BigLinux, Bitrig, BlackArch, BlackPanther, BLAG, BlankOn, BlueLight, Bodhi, Bonsai, BSD, BunsenLabs, CachyOS, CachyOSSmall, Calculate, CalinixOS, CalinixOSSmall, Carbs, CBL-Mariner, CelOS, Center, CentOS, CentOSSmall, Chakra, ChaletOS, Chapeau, Chimera Linux, ChonkySealOS, Chrom, Cleanjaro, CleanjaroSmall, ClearLinux, ClearOS, Clover, Cobalt, Condres, ContainerLinux, CRUX, CRUXSmall, CrystalLinux, Cucumber, CutefishOS, CuteOS, CyberOS, Dahlia, DarkOS, Debian, DebianSmall, Deepin, DesaOS, Devuan, DevuanSmall, DietPi, DracOS, DragonFly, DragonFlyOld, DragonFlySmall, Drauger, Droidian, Elbrus, Elementary, ElementarySmall, Elive, EncryptOS, Endeavour, EndeavourSmall, Endless, Enso, EuroLinux, EvolutionOS, EvolutionOS_old, EvolutionOSSmall, Exherbo, ExodiaPredator, Fedora, FedoraOld, FedoraSmall, FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeBSDSmall, FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, GarudaDragon, GarudaSmall, Gentoo, GentooSmall, GhostBSD, Glaucus, GNewSense, Gnome, GNU, GoboLinux, GrapheneOS, Grombyang, Guix, GuixSmall, Haiku, HaikuSmall, HamoniKR, HarDClanZ, HardenedBSD, Hash, Huayra, Hybrid, HydroOS, Hyperbola, HyperbolaSmall, Iglunix, InstantOS, IRIX, Itc, Januslinux, Kaisen, Kali, KaliSmall, KaOS, KDENeon, Kibojoe, KISSLinux, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, Laxeros, LEDE, LibreELEC, Linspire, Linux, LinuxLight, LinuxLightSmall, LinuxMint, LinuxMintOld, LinuxMintSmall, LinuxSmall, Live_Raizo, LMDE, Lunar, MacOS, MacOS2, MacOS2Small, MacOSSmall, Mageia, MageiaSmall, MagpieOS, Mandriva, Manjaro, ManjaroSmall, MassOS, MatuusOS, MaUI, Meowix, Mer, Minix, Mint, MintOld, MintSmall, MiracleLinux, MOS, Msys2, MX, MXSmall, Namib, Nekos, Neptune, NetBSD, NetRunner, Nitrux, NixOS, NixOS_small, NixOsOld, NixOsSmall, Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, OpenBSD, OpenBSDSmall, OpenEuler, OpenIndiana, OpenKylin, OpenMamba, OpenMandriva, OpenStage, OpenSuse, OpenSuseLeap, OpenSuseSmall, OpenSuseTumbleweed, OpenWrt, OPNsense, Oracle, Orchid, OrchidSmall, OS_Elbrus, OSMC, OSX, OSXSmall, PacBSD, Panwah, Parabola, ParabolaSmall, Parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS, PearOS, Pengwin, Pentoo, Peppermint, PhyOS, Pisi, PNMLinux, Pop, PopSmall, Porteus, PostMarketOS, PostMarketOSSmall, Proxmox, PuffOS, Puppy, PureOS, PureOSSmall, Q4OS, Qubes, Qubyt, Quibian, Radix, Raspbian, RaspbianSmall, RavynOS, Reborn, RebornSmall, RedCore, RedHatEnterpriseLinux, RedHatEnterpriseLinux_old, RedstarOS, Refracted Devuan, Regata, Regolith, RhaymOS, RockyLinux, RockyLinuxSmall, RosaLinux, Sabayon, Sabotage, Sailfish, SalentOS, SalientOS, Salix, SambaBOX, Sasanqua, Scientific, Semc, Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SlackwareSmall, Slitaz, SmartOS, Soda, Solaris, SolarisSmall, Solus, SourceMage, Sparky, Star, SteamOS, StockLinux, Sulin, Suse, SuseSmall, Swagarch, T2, Tails, TeArch, TorizonCore, Trisquel, TuxedoOS, Twister, Ubuntu, Ubuntu2Old, Ubuntu2Small, UbuntuBudgie, UbuntuCinnamon, UbuntuGnome, UbuntuKde, UbuntuKylin, UbuntuMate, UbuntuOld, UbuntuSmall, UbuntuStudio, UbuntuSway, UbuntuTouch, UbuntuUnity, Ultramarine, Univalent, Univention, UOS, UrukOS, Uwuntu, Vanilla, Venom, VenomSmall, Vnux, Void, VoidSmall, Vzlinux, WiiLinuxNgx, Windows, Windows11, Windows11Small, Windows8, Windows95, Xenia, Xferience, YiffOS, Zorin
```
* 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`
* 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 --mirgrate-config`
Run `fastfetch --print-logos` to print them
## Customization
##### Package managers
```
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, opkg, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps
```
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. They may also serve as a good example for format arguments.
##### WM themes
```
DWM (Windows), KWin, Marco, Muffin, Mutter, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS), XFWM
```
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
##### DE versions
```
Budgie, Cinnamon, Gnome, KDE Plasma, LXQt, Mate, XFCE4
```
##### Terminal fonts
```
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Console, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal, Yakuake
```
## Building
fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are:
```bash
mkdir -p build
cd build
cmake ..
cmake --build . --target fastfetch --target flashfetch
```
If the build process fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available.
### Building on Windows
Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 subsystem (or CLANGARM64 if needed) is suggested (and tested) to build fastfetch. If you need Windows 7 / 8.x support, using MINGW64 is suggested.
1. Install [MSYS2](https://www.msys2.org/#installation)
1. Open `MSYS2 / CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime)
1. Install dependencies
```bash
pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
```
Follow the building instructions of Linux next.
## Packaging
+317 -203
View File
File diff suppressed because it is too large Load Diff
+10359
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
{
"home": "https://github.com/NVIDIA/nvidia-settings/blob/main/src/nvml.h",
"license": "Embed in source",
"version": "545.23.06",
"author": "NVIDIA Corporation"
}
+27 -21
View File
@@ -6,15 +6,17 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
{
assert(green <= 100 && yellow <= 100 && red <= 100);
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * instance.config.barWidth + 0.5);
uint32_t blocksGreen = (uint32_t) (green / 100.0 * instance.config.barWidth + 0.5);
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * instance.config.barWidth + 0.5);
uint32_t blocksRed = (uint32_t) (red / 100.0 * instance.config.barWidth + 0.5);
assert(blocksPercent <= instance.config.barWidth);
const FFOptionsDisplay* options = &instance.config.display;
if(instance.config.barBorder)
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * options->barWidth + 0.5);
uint32_t blocksGreen = (uint32_t) (green / 100.0 * options->barWidth + 0.5);
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * options->barWidth + 0.5);
uint32_t blocksRed = (uint32_t) (red / 100.0 * options->barWidth + 0.5);
assert(blocksPercent <= options->barWidth);
if(options->barBorder)
{
if(!instance.config.pipe)
if(!options->pipe)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m[ ");
else
ffStrbufAppendS(buffer, "[ ");
@@ -22,7 +24,7 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
for (uint32_t i = 0; i < blocksPercent; ++i)
{
if(!instance.config.pipe)
if(!options->pipe)
{
if (i == blocksGreen)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
@@ -31,26 +33,26 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
else if (i == blocksRed)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
}
ffStrbufAppend(buffer, &instance.config.barCharElapsed);
ffStrbufAppend(buffer, &options->barCharElapsed);
}
if (blocksPercent < instance.config.barWidth)
if (blocksPercent < options->barWidth)
{
if(!instance.config.pipe)
if(!options->pipe)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m");
for (uint32_t i = blocksPercent; i < instance.config.barWidth; ++i)
ffStrbufAppend(buffer, &instance.config.barCharTotal);
for (uint32_t i = blocksPercent; i < options->barWidth; ++i)
ffStrbufAppend(buffer, &options->barCharTotal);
}
if(instance.config.barBorder)
if(options->barBorder)
{
if(!instance.config.pipe)
if(!options->pipe)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
else
ffStrbufAppendS(buffer, " ]");
}
if(!instance.config.pipe)
if(!options->pipe)
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
}
@@ -67,14 +69,18 @@ void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
{
assert(green <= 100 && yellow <= 100);
bool colored = !!(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
const FFOptionsDisplay* options = &instance.config.display;
bool colored = !!(options->percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
if (parentheses)
ffStrbufAppendC(buffer, '(');
if (colored && !instance.config.pipe)
if (colored && !options->pipe)
{
if(green < yellow)
if(percent != percent)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_BLACK "m");
else if(green < yellow)
{
if (percent <= green)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
@@ -93,9 +99,9 @@ void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
}
}
ffStrbufAppendF(buffer, "%.*f%%", instance.config.percentNdigits, percent);
ffStrbufAppendF(buffer, "%.*f%%", options->percentNdigits, percent);
if (colored && !instance.config.pipe)
if (colored && !options->pipe)
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
}
+92 -51
View File
@@ -1,6 +1,7 @@
#include "commandoption.h"
#include "common/printing.h"
#include "common/time.h"
#include "common/jsonconfig.h"
#include "fastfetch_datatext.h"
#include "modules/modules.h"
#include "util/stringUtils.h"
@@ -8,37 +9,6 @@
#include <ctype.h>
#include <inttypes.h>
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
{
yyjson_mut_doc* doc = instance.state.resultDoc;
if (__builtin_expect(!doc, true)) return NULL;
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJson)
baseInfo->generateJson(baseInfo, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
return module;
}
bool ffParseModuleCommand(const char* type)
{
if(!isalpha(type[0])) return false;
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
if (ffStrEqualsIgnCase(type, baseInfo->name))
{
if (!genJson(baseInfo))
baseInfo->printModule(baseInfo);
return true;
}
}
return false;
}
bool ffParseModuleOptions(const char* key, const char* value)
{
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
@@ -53,6 +23,7 @@ bool ffParseModuleOptions(const char* key, const char* value)
void ffPrepareCommandOption(FFdata* data)
{
FFOptionsModules* const options = &instance.config.modules;
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
@@ -61,22 +32,57 @@ void ffPrepareCommandOption(FFdata* data)
ffPrepareCPUUsage();
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
ffPrepareDiskIO(&instance.config.diskIo);
ffPrepareDiskIO(&options->diskIo);
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
ffPrepareNetIO(&instance.config.netIo);
ffPrepareNetIO(&options->netIo);
if(instance.config.multithreading)
if(instance.config.general.multithreading)
{
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
ffPreparePublicIp(&instance.config.publicIP);
ffPreparePublicIp(&options->publicIP);
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
ffPrepareWeather(&instance.config.weather);
ffPrepareWeather(&options->weather);
}
}
static void parseStructureCommand(const char* line, FFlist* customValues)
static void genJsonConfig(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
{
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
if (!modules)
modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules");
yyjson_mut_val* module = yyjson_mut_obj(doc);
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name);
ffStrbufLowerCase(&type);
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
if (baseInfo->generateJsonConfig)
baseInfo->generateJsonConfig(baseInfo, doc, module);
if (yyjson_mut_obj_size(module) > 1)
yyjson_mut_arr_add_val(modules, module);
else
yyjson_mut_arr_add_strbuf(doc, modules, &type);
}
static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
{
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJsonResult)
baseInfo->generateJsonResult(baseInfo, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
}
static void parseStructureCommand(
const char* line,
FFlist* customValues,
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
yyjson_mut_doc* jsonDoc
)
{
// handle `--set` and `--set-keyless`
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
@@ -88,19 +94,35 @@ static void parseStructureCommand(const char* line, FFlist* customValues)
if (customValue->printKey)
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
ffPrintCustom(&options);
if (__builtin_expect(jsonDoc != NULL, false))
fn((FFModuleBaseInfo*) &options, jsonDoc);
else
ffPrintCustom(&options);
return;
}
}
if(!ffParseModuleCommand(line))
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
if(isalpha(line[0]))
{
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
if (ffStrEqualsIgnCase(line, baseInfo->name))
{
if (__builtin_expect(jsonDoc != NULL, false))
fn(baseInfo, jsonDoc);
else
baseInfo->printModule(baseInfo);
return;
}
}
}
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
}
void ffPrintCommandOption(FFdata* data)
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
{
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
//Parse the structure and call the modules
uint32_t startIndex = 0;
while (startIndex < data->structure.length)
@@ -109,25 +131,25 @@ void ffPrintCommandOption(FFdata* data)
data->structure.chars[colonIndex] = '\0';
uint64_t ms = 0;
if(instance.config.stat)
if(instance.config.display.stat)
ms = ffTimeGetTick();
parseStructureCommand(data->structure.chars + startIndex, &data->customValues);
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc);
if(instance.config.stat)
if(instance.config.display.stat)
{
ms = ffTimeGetTick() - ms;
if (resultDoc)
if (jsonDoc)
{
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
}
else
{
char str[32];
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
if(instance.config.pipe)
if(instance.config.display.pipe)
puts(str);
else
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
@@ -135,9 +157,28 @@ void ffPrintCommandOption(FFdata* data)
}
#if defined(_WIN32)
if (!instance.config.noBuffer) fflush(stdout);
if (!jsonDoc && !instance.config.display.noBuffer) fflush(stdout);
#endif
startIndex = colonIndex + 1;
}
}
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
{
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
//Parse the structure and call the modules
uint32_t startIndex = 0;
while (startIndex < data->structure.length)
{
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
data->structure.chars[colonIndex] = '\0';
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc);
startIndex = colonIndex + 1;
}
}
+2 -2
View File
@@ -20,9 +20,9 @@ typedef struct FFdata
bool loadUserConfig;
} FFdata;
bool ffParseModuleCommand(const char* type);
bool ffParseModuleOptions(const char* key, const char* value);
void ffPrepareCommandOption(FFdata* data);
void ffPrintCommandOption(FFdata* data);
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc);
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc);
#endif
+1 -5
View File
@@ -7,7 +7,7 @@
static bool loadLibSymbols(FFDBusLibrary* lib)
{
FF_LIBRARY_LOAD(dbus, &instance.config.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD(dbus, &instance.config.library.libDBus, 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_iter_init, false)
@@ -33,9 +33,6 @@ static const FFDBusLibrary* loadLib(void)
static FFDBusLibrary lib;
static bool loaded = false;
static bool loadSuccess = false;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
ffThreadMutexLock(&mutex);
if(!loaded)
{
@@ -43,7 +40,6 @@ static const FFDBusLibrary* loadLib(void)
loadSuccess = loadLibSymbols(&lib);
}
ffThreadMutexUnlock(&mutex);
return loadSuccess ? &lib : NULL;
}
+17 -253
View File
@@ -15,8 +15,6 @@
#include <signal.h>
#endif
#include "modules/modules.h"
FFinstance instance; // Global singleton
static void initState(FFstate* state)
@@ -32,133 +30,11 @@ static void initState(FFstate* state)
static void defaultConfig(void)
{
ffInitLogoOptions(&instance.config.logo);
ffStrbufInit(&instance.config.colorKeys);
ffStrbufInit(&instance.config.colorTitle);
instance.config.brightColor = true;
ffStrbufInitStatic(&instance.config.keyValueSeparator, ": ");
instance.config.processingTimeout = 1000;
#if defined(__linux__) || defined(__FreeBSD__)
ffStrbufInit(&instance.config.playerName);
ffStrbufInit(&instance.config.osFile);
instance.config.dsForceDrm = false;
#elif defined(_WIN32)
instance.config.wmiTimeout = 5000;
#endif
instance.config.showErrors = false;
instance.config.allowSlowOperations = false;
instance.config.pipe = !isatty(STDOUT_FILENO);
#ifdef NDEBUG
instance.config.disableLinewrap = !instance.config.pipe;
instance.config.hideCursor = !instance.config.pipe;
#else
instance.config.disableLinewrap = false;
instance.config.hideCursor = false;
#endif
instance.config.escapeBedrock = true;
instance.config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
instance.config.sizeNdigits = 2;
instance.config.sizeMaxPrefix = UINT8_MAX;
instance.config.temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS;
instance.config.multithreading = true;
instance.config.stat = false;
instance.config.noBuffer = false;
instance.config.keyWidth = 0;
ffStrbufInitStatic(&instance.config.barCharElapsed, "");
ffStrbufInitStatic(&instance.config.barCharTotal, "-");
instance.config.barWidth = 10;
instance.config.barBorder = true;
instance.config.percentType = 1;
instance.config.percentNdigits = 0;
ffInitBatteryOptions(&instance.config.battery);
ffInitBiosOptions(&instance.config.bios);
ffInitBluetoothOptions(&instance.config.bluetooth);
ffInitBoardOptions(&instance.config.board);
ffInitBreakOptions(&instance.config.break_);
ffInitBrightnessOptions(&instance.config.brightness);
ffInitCPUOptions(&instance.config.cpu);
ffInitCPUUsageOptions(&instance.config.cpuUsage);
ffInitChassisOptions(&instance.config.chassis);
ffInitColorsOptions(&instance.config.colors);
ffInitCommandOptions(&instance.config.command);
ffInitCursorOptions(&instance.config.cursor);
ffInitCustomOptions(&instance.config.custom);
ffInitDEOptions(&instance.config.de);
ffInitDateTimeOptions(&instance.config.dateTime);
ffInitDiskOptions(&instance.config.disk);
ffInitDiskIOOptions(&instance.config.diskIo);
ffInitDisplayOptions(&instance.config.display);
ffInitFontOptions(&instance.config.font);
ffInitGPUOptions(&instance.config.gpu);
ffInitGamepadOptions(&instance.config.gamepad);
ffInitHostOptions(&instance.config.host);
ffInitIconsOptions(&instance.config.icons);
ffInitKernelOptions(&instance.config.kernel);
ffInitLMOptions(&instance.config.lm);
ffInitLocalIpOptions(&instance.config.localIP);
ffInitLocaleOptions(&instance.config.locale);
ffInitMediaOptions(&instance.config.media);
ffInitMemoryOptions(&instance.config.memory);
ffInitMonitorOptions(&instance.config.monitor);
ffInitNetIOOptions(&instance.config.netIo);
ffInitOSOptions(&instance.config.os);
ffInitOpenCLOptions(&instance.config.openCL);
ffInitOpenGLOptions(&instance.config.openGL);
ffInitPackagesOptions(&instance.config.packages);
ffInitPlayerOptions(&instance.config.player);
ffInitPowerAdapterOptions(&instance.config.powerAdapter);
ffInitProcessesOptions(&instance.config.processes);
ffInitPublicIpOptions(&instance.config.publicIP);
ffInitSeparatorOptions(&instance.config.separator);
ffInitShellOptions(&instance.config.shell);
ffInitSoundOptions(&instance.config.sound);
ffInitSwapOptions(&instance.config.swap);
ffInitTerminalFontOptions(&instance.config.terminalFont);
ffInitTerminalOptions(&instance.config.terminal);
ffInitTerminalSizeOptions(&instance.config.terminalSize);
ffInitThemeOptions(&instance.config.theme);
ffInitTitleOptions(&instance.config.title);
ffInitUptimeOptions(&instance.config.uptime);
ffInitUsersOptions(&instance.config.users);
ffInitVersionOptions(&instance.config.version);
ffInitVulkanOptions(&instance.config.vulkan);
ffInitWMOptions(&instance.config.wm);
ffInitWMThemeOptions(&instance.config.wmTheme);
ffInitWallpaperOptions(&instance.config.wallpaper);
ffInitWeatherOptions(&instance.config.weather);
ffInitWifiOptions(&instance.config.wifi);
ffStrbufInit(&instance.config.libPCI);
ffStrbufInit(&instance.config.libVulkan);
ffStrbufInit(&instance.config.libWayland);
ffStrbufInit(&instance.config.libXcbRandr);
ffStrbufInit(&instance.config.libXcb);
ffStrbufInit(&instance.config.libXrandr);
ffStrbufInit(&instance.config.libX11);
ffStrbufInit(&instance.config.libGIO);
ffStrbufInit(&instance.config.libDConf);
ffStrbufInit(&instance.config.libDBus);
ffStrbufInit(&instance.config.libXFConf);
ffStrbufInit(&instance.config.libSQLite3);
ffStrbufInit(&instance.config.librpm);
ffStrbufInit(&instance.config.libImageMagick);
ffStrbufInit(&instance.config.libZ);
ffStrbufInit(&instance.config.libChafa);
ffStrbufInit(&instance.config.libEGL);
ffStrbufInit(&instance.config.libGLX);
ffStrbufInit(&instance.config.libOSMesa);
ffStrbufInit(&instance.config.libOpenCL);
ffStrbufInit(&instance.config.libfreetype);
ffStrbufInit(&instance.config.libPulse);
ffStrbufInit(&instance.config.libnm);
ffStrbufInit(&instance.config.libDdcutil);
ffOptionsInitLogo(&instance.config.logo);
ffOptionsInitGeneral(&instance.config.general);
ffOptionsInitModules(&instance.config.modules);
ffOptionsInitDisplay(&instance.config.display);
ffOptionsInitLibrary(&instance.config.library);
}
void ffInitInstance(void)
@@ -175,29 +51,6 @@ void ffInitInstance(void)
defaultConfig();
}
#if defined(FF_HAVE_THREADS) && !(defined(__APPLE__) || defined(_WIN32) || defined(__ANDROID__))
#include "detection/gtk_qt/gtk_qt.h"
#define FF_START_DETECTION_THREADS
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffConnectDisplayServer)
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectQt)
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK2)
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK3)
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK4)
void startDetectionThreads(void)
{
ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, NULL));
ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, NULL));
ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, NULL));
ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, NULL));
ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, NULL));
}
#endif //FF_HAVE_THREADS
static volatile bool ffDisableLinewrap = true;
static volatile bool ffHideCursor = true;
@@ -233,15 +86,15 @@ static void exitSignalHandler(int signal)
void ffStart(void)
{
#ifdef FF_START_DETECTION_THREADS
if(instance.config.multithreading)
if(instance.config.general.multithreading)
startDetectionThreads();
#endif
ffDisableLinewrap = instance.config.disableLinewrap && !instance.config.pipe && !instance.state.resultDoc;
ffHideCursor = instance.config.hideCursor && !instance.config.pipe && !instance.state.resultDoc;
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe && !instance.state.resultDoc;
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
#ifdef _WIN32
setvbuf(stdout, NULL, _IOFBF, instance.config.noBuffer ? 0 : 4096);
setvbuf(stdout, NULL, _IOFBF, instance.config.display.noBuffer ? 0 : 4096);
SetConsoleCtrlHandler(consoleHandler, TRUE);
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode = 0;
@@ -249,7 +102,7 @@ void ffStart(void)
SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
SetConsoleOutputCP(CP_UTF8);
#else
if (instance.config.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
if (instance.config.display.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
struct sigaction action = { .sa_handler = exitSignalHandler };
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
@@ -257,7 +110,7 @@ void ffStart(void)
#endif
//reset everything to default before we start printing
if(!instance.config.pipe && !instance.state.resultDoc)
if(!instance.config.display.pipe && !instance.state.resultDoc)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if(ffHideCursor)
@@ -279,101 +132,11 @@ void ffFinish(void)
static void destroyConfig(void)
{
ffDestroyLogoOptions(&instance.config.logo);
ffStrbufDestroy(&instance.config.colorKeys);
ffStrbufDestroy(&instance.config.colorTitle);
ffStrbufDestroy(&instance.config.keyValueSeparator);
ffStrbufDestroy(&instance.config.barCharElapsed);
ffStrbufDestroy(&instance.config.barCharTotal);
#if defined(__linux__) || defined(__FreeBSD__)
ffStrbufDestroy(&instance.config.playerName);
ffStrbufDestroy(&instance.config.osFile);
#endif
ffDestroyBatteryOptions(&instance.config.battery);
ffDestroyBiosOptions(&instance.config.bios);
ffDestroyBluetoothOptions(&instance.config.bluetooth);
ffDestroyBoardOptions(&instance.config.board);
ffDestroyBreakOptions(&instance.config.break_);
ffDestroyBrightnessOptions(&instance.config.brightness);
ffDestroyCPUOptions(&instance.config.cpu);
ffDestroyCPUUsageOptions(&instance.config.cpuUsage);
ffDestroyChassisOptions(&instance.config.chassis);
ffDestroyColorsOptions(&instance.config.colors);
ffDestroyCommandOptions(&instance.config.command);
ffDestroyCursorOptions(&instance.config.cursor);
ffDestroyCustomOptions(&instance.config.custom);
ffDestroyDEOptions(&instance.config.de);
ffDestroyDateTimeOptions(&instance.config.dateTime);
ffDestroyDiskOptions(&instance.config.disk);
ffDestroyDiskIOOptions(&instance.config.diskIo);
ffDestroyDisplayOptions(&instance.config.display);
ffDestroyFontOptions(&instance.config.font);
ffDestroyGPUOptions(&instance.config.gpu);
ffDestroyGamepadOptions(&instance.config.gamepad);
ffDestroyHostOptions(&instance.config.host);
ffDestroyIconsOptions(&instance.config.icons);
ffDestroyKernelOptions(&instance.config.kernel);
ffDestroyLMOptions(&instance.config.lm);
ffDestroyLocalIpOptions(&instance.config.localIP);
ffDestroyLocaleOptions(&instance.config.locale);
ffDestroyMediaOptions(&instance.config.media);
ffDestroyMemoryOptions(&instance.config.memory);
ffDestroyMonitorOptions(&instance.config.monitor);
ffDestroyNetIOOptions(&instance.config.netIo);
ffDestroyOSOptions(&instance.config.os);
ffDestroyOpenCLOptions(&instance.config.openCL);
ffDestroyOpenGLOptions(&instance.config.openGL);
ffDestroyPackagesOptions(&instance.config.packages);
ffDestroyPlayerOptions(&instance.config.player);
ffDestroyPowerAdapterOptions(&instance.config.powerAdapter);
ffDestroyProcessesOptions(&instance.config.processes);
ffDestroyPublicIpOptions(&instance.config.publicIP);
ffDestroySeparatorOptions(&instance.config.separator);
ffDestroyShellOptions(&instance.config.shell);
ffDestroySoundOptions(&instance.config.sound);
ffDestroySwapOptions(&instance.config.swap);
ffDestroyTerminalFontOptions(&instance.config.terminalFont);
ffDestroyTerminalOptions(&instance.config.terminal);
ffDestroyTerminalSizeOptions(&instance.config.terminalSize);
ffDestroyThemeOptions(&instance.config.theme);
ffDestroyTitleOptions(&instance.config.title);
ffDestroyUptimeOptions(&instance.config.uptime);
ffDestroyUsersOptions(&instance.config.users);
ffDestroyVersionOptions(&instance.config.version);
ffDestroyVulkanOptions(&instance.config.vulkan);
ffDestroyWMOptions(&instance.config.wm);
ffDestroyWMThemeOptions(&instance.config.wmTheme);
ffDestroyWallpaperOptions(&instance.config.wallpaper);
ffDestroyWeatherOptions(&instance.config.weather);
ffDestroyWifiOptions(&instance.config.wifi);
ffStrbufDestroy(&instance.config.libPCI);
ffStrbufDestroy(&instance.config.libVulkan);
ffStrbufDestroy(&instance.config.libWayland);
ffStrbufDestroy(&instance.config.libXcbRandr);
ffStrbufDestroy(&instance.config.libXcb);
ffStrbufDestroy(&instance.config.libXrandr);
ffStrbufDestroy(&instance.config.libX11);
ffStrbufDestroy(&instance.config.libGIO);
ffStrbufDestroy(&instance.config.libDConf);
ffStrbufDestroy(&instance.config.libDBus);
ffStrbufDestroy(&instance.config.libXFConf);
ffStrbufDestroy(&instance.config.libSQLite3);
ffStrbufDestroy(&instance.config.librpm);
ffStrbufDestroy(&instance.config.libImageMagick);
ffStrbufDestroy(&instance.config.libZ);
ffStrbufDestroy(&instance.config.libChafa);
ffStrbufDestroy(&instance.config.libEGL);
ffStrbufDestroy(&instance.config.libGLX);
ffStrbufDestroy(&instance.config.libOSMesa);
ffStrbufDestroy(&instance.config.libOpenCL);
ffStrbufDestroy(&instance.config.libfreetype);
ffStrbufDestroy(&instance.config.libPulse);
ffStrbufDestroy(&instance.config.libnm);
ffStrbufDestroy(&instance.config.libDdcutil);
ffOptionsDestroyLogo(&instance.config.logo);
ffOptionsDestroyGeneral(&instance.config.general);
ffOptionsDestroyModules(&instance.config.modules);
ffOptionsDestroyDisplay(&instance.config.display);
ffOptionsDestroyLibrary(&instance.config.library);
}
static void destroyState(void)
@@ -381,6 +144,7 @@ static void destroyState(void)
ffPlatformDestroy(&instance.state.platform);
yyjson_doc_free(instance.state.configDoc);
yyjson_mut_doc_free(instance.state.resultDoc);
ffStrbufDestroy(&instance.state.migrateConfigPath);
}
void ffDestroyInstance(void)
+48 -295
View File
@@ -35,6 +35,18 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
return false;
}
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs)
{
if (!ffStrbufEqual(&defaultModuleArgs->key, &moduleArgs->key))
yyjson_mut_obj_add_strbuf(doc, module, "key", &moduleArgs->key);
if (!ffStrbufEqual(&defaultModuleArgs->outputFormat, &moduleArgs->outputFormat))
yyjson_mut_obj_add_strbuf(doc, module, "format", &moduleArgs->outputFormat);
if (!ffStrbufEqual(&defaultModuleArgs->keyColor, &moduleArgs->keyColor))
yyjson_mut_obj_add_strbuf(doc, module, "keyColor", &moduleArgs->keyColor);
if (moduleArgs->keyWidth != defaultModuleArgs->keyWidth)
yyjson_mut_obj_add_uint(doc, module, "keyWidth", moduleArgs->keyWidth);
}
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[])
{
if (yyjson_is_int(val))
@@ -70,21 +82,17 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
return "Invalid enum value type; must be a string or integer";
}
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
{
yyjson_mut_doc* doc = instance.state.resultDoc;
if (__builtin_expect(!doc, true)) return NULL;
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJson)
baseInfo->generateJson(baseInfo, doc, module);
if (baseInfo->generateJsonResult)
baseInfo->generateJsonResult(baseInfo, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
return module;
}
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal)
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
{
if(!isalpha(type[0])) return false;
@@ -94,7 +102,9 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal)
if (ffStrEqualsIgnCase(type, baseInfo->name))
{
if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal);
if (!genJson(baseInfo))
if (__builtin_expect(jsonDoc != NULL, false))
genJsonResult(baseInfo, jsonDoc);
else
baseInfo->printModule(baseInfo);
return true;
}
@@ -115,39 +125,39 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
case 'd': case 'D': {
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
{
if (module) ffParseDiskIOJsonObject(&cfg->diskIo, module);
ffPrepareDiskIO(&cfg->diskIo);
if (module) cfg->modules.diskIo.moduleInfo.parseJsonObject(&cfg->modules.diskIo, module);
ffPrepareDiskIO(&cfg->modules.diskIo);
}
break;
}
case 'n': case 'N': {
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
{
if (module) ffParseNetIOJsonObject(&cfg->netIo, module);
ffPrepareNetIO(&cfg->netIo);
if (module) cfg->modules.netIo.moduleInfo.parseJsonObject(&cfg->modules.netIo, module);
ffPrepareNetIO(&cfg->modules.netIo);
}
break;
}
case 'p': case 'P': {
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
{
if (module) ffParsePublicIpJsonObject(&cfg->publicIP, module);
ffPreparePublicIp(&cfg->publicIP);
if (module) cfg->modules.publicIP.moduleInfo.parseJsonObject(&cfg->modules.publicIP, module);
ffPreparePublicIp(&cfg->modules.publicIP);
}
break;
}
case 'w': case 'W': {
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
{
if (module) ffParseWeatherJsonObject(&cfg->weather, module);
ffPrepareWeather(&cfg->weather);
if (module) cfg->modules.weather.moduleInfo.parseJsonObject(&cfg->modules.weather, module);
ffPrepareWeather(&cfg->modules.weather);
}
break;
}
}
}
static const char* printJsonConfig(bool prepare)
static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
{
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
assert(root);
@@ -159,14 +169,12 @@ static const char* printJsonConfig(bool prepare)
if (!modules) return NULL;
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
yyjson_val* item;
size_t idx, max;
yyjson_arr_foreach(modules, idx, max, item)
{
uint64_t ms = 0;
if(!prepare && instance.config.stat)
if(!prepare && instance.config.display.stat)
ms = ffTimeGetTick();
yyjson_val* module = item;
@@ -185,22 +193,22 @@ static const char* printJsonConfig(bool prepare)
if(prepare)
prepareModuleJsonObject(type, module);
else if(!parseModuleJsonObject(type, module))
else if(!parseModuleJsonObject(type, module, jsonDoc))
return "Unknown module type";
if(!prepare && instance.config.stat)
if(!prepare && instance.config.display.stat)
{
ms = ffTimeGetTick() - ms;
if (resultDoc)
if (jsonDoc)
{
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
}
else
{
char str[32];
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
if(instance.config.pipe)
if(instance.config.display.pipe)
puts(str);
else
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
@@ -208,280 +216,25 @@ static const char* printJsonConfig(bool prepare)
}
#if defined(_WIN32)
if (!instance.config.noBuffer && !resultDoc) fflush(stdout);
if (!instance.config.display.noBuffer && !jsonDoc) fflush(stdout);
#endif
}
return NULL;
}
const char* ffParseGeneralJsonConfig(void)
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
{
FFconfig* config = &instance.config;
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
assert(root);
if (!yyjson_is_obj(root))
return "Invalid JSON config format. Root value must be an object";
yyjson_val* object = yyjson_obj_get(root, "general");
if (!object) return NULL;
if (!yyjson_is_obj(object)) return "Property 'general' must be an object";
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(object, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if (ffStrEqualsIgnCase(key, "allowSlowOperations"))
config->allowSlowOperations = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "thread") || ffStrEqualsIgnCase(key, "multithreading"))
config->multithreading = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "stat"))
{
if ((config->stat = yyjson_get_bool(val)))
config->showErrors = true;
}
else if (ffStrEqualsIgnCase(key, "escapeBedrock"))
config->escapeBedrock = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "pipe"))
config->pipe = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "processingTimeout"))
config->processingTimeout = (int32_t) yyjson_get_int(val);
#if defined(__linux__) || defined(__FreeBSD__)
else if (ffStrEqualsIgnCase(key, "playerName"))
ffStrbufSetS(&config->playerName, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "osFile"))
ffStrbufSetS(&config->osFile, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
config->dsForceDrm = yyjson_get_bool(val);
#elif defined(_WIN32)
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
config->wmiTimeout = (int32_t) yyjson_get_int(val);
#endif
else
return "Unknown general property";
}
return NULL;
}
const char* ffParseDisplayJsonConfig(void)
{
FFconfig* config = &instance.config;
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
assert(root);
if (!yyjson_is_obj(root))
return "Invalid JSON config format. Root value must be an object";
yyjson_val* object = yyjson_obj_get(root, "display");
if (!object) return NULL;
if (!yyjson_is_obj(object)) return "Property 'display' must be an object";
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(object, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if (ffStrEqualsIgnCase(key, "showErrors"))
config->showErrors = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "disableLinewrap"))
config->disableLinewrap = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "hideCursor"))
config->hideCursor = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "separator"))
ffStrbufSetS(&config->keyValueSeparator, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "color"))
{
if (yyjson_is_str(val))
{
ffOptionParseColor(yyjson_get_str(val), &config->colorKeys);
ffStrbufSet(&config->colorTitle, &config->colorKeys);
}
else if (yyjson_is_obj(val))
{
const char* colorKeys = yyjson_get_str(yyjson_obj_get(val, "keys"));
if (colorKeys)
ffOptionParseColor(colorKeys, &config->colorKeys);
const char* colorTitle = yyjson_get_str(yyjson_obj_get(val, "title"));
if (colorTitle)
ffOptionParseColor(colorTitle, &config->colorTitle);
}
else
return "display.color must be either a string or an object";
}
else if (ffStrEqualsIgnCase(key, "brightColor"))
config->brightColor = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "binaryPrefix"))
{
int value;
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
{ "iec", FF_BINARY_PREFIX_TYPE_IEC },
{ "si", FF_BINARY_PREFIX_TYPE_SI },
{ "jedec", FF_BINARY_PREFIX_TYPE_JEDEC },
{},
});
if (error) return error;
config->binaryPrefixType = (FFBinaryPrefixType) value;
}
else if (ffStrEqualsIgnCase(key, "sizeNdigits"))
config->sizeNdigits = (uint8_t) yyjson_get_uint(val);
else if (ffStrEqualsIgnCase(key, "sizeMaxPrefix"))
{
int value;
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
{ "B", 0 },
{ "kB", 1 },
{ "MB", 2 },
{ "GB", 3 },
{ "TB", 4 },
{ "PB", 5 },
{ "EB", 6 },
{ "ZB", 7 },
{ "YB", 8 },
{}
});
if (error) return error;
config->sizeMaxPrefix = (uint8_t) value;
}
else if (ffStrEqualsIgnCase(key, "temperatureUnit"))
{
int value;
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
{},
});
if (error) return error;
config->temperatureUnit = (FFTemperatureUnit) value;
}
else if (ffStrEqualsIgnCase(key, "percentType"))
config->percentType = (uint8_t) yyjson_get_uint(val);
else if (ffStrEqualsIgnCase(key, "percentNdigits"))
config->percentNdigits = (uint8_t) yyjson_get_uint(val);
else if (ffStrEqualsIgnCase(key, "bar"))
{
if (yyjson_is_obj(val))
{
const char* charElapsed = yyjson_get_str(yyjson_obj_get(val, "charElapsed"));
if (charElapsed)
ffStrbufSetS(&config->barCharElapsed, charElapsed);
const char* charTotal = yyjson_get_str(yyjson_obj_get(val, "charTotal"));
if (charTotal)
ffStrbufSetS(&config->barCharTotal, charTotal);
yyjson_val* border = yyjson_obj_get(val, "border");
if (border)
config->barBorder = yyjson_get_bool(border);
yyjson_val* width = yyjson_obj_get(val, "width");
if (width)
config->barWidth = (uint8_t) yyjson_get_uint(width);
}
else
return "display.bar must be an object";
}
else if (ffStrEqualsIgnCase(key, "noBuffer"))
config->noBuffer = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "keyWidth"))
config->keyWidth = (uint32_t) yyjson_get_uint(val);
else
return "Unknown display property";
}
return NULL;
}
const char* ffParseLibraryJsonConfig(void)
{
FFconfig* config = &instance.config;
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
assert(root);
if (!yyjson_is_obj(root))
return "Invalid JSON config format. Root value must be an object";
yyjson_val* object = yyjson_obj_get(root, "library");
if (!object) return NULL;
if (!yyjson_is_obj(object)) return "Property 'library' must be an object";
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(object, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if (ffStrEqualsIgnCase(key, "pci"))
ffStrbufSetS(&config->libPCI, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "vulkan"))
ffStrbufSetS(&config->libVulkan, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "freetype"))
ffStrbufSetS(&config->libfreetype, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "wayland"))
ffStrbufSetS(&config->libWayland, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "xcbRandr"))
ffStrbufSetS(&config->libXcbRandr, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "xcb"))
ffStrbufSetS(&config->libXcb, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "Xrandr"))
ffStrbufSetS(&config->libXrandr, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "X11"))
ffStrbufSetS(&config->libX11, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "gio"))
ffStrbufSetS(&config->libGIO, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "DConf"))
ffStrbufSetS(&config->libDConf, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "dbus"))
ffStrbufSetS(&config->libDBus, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "XFConf"))
ffStrbufSetS(&config->libXFConf, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "sqlite") || ffStrEqualsIgnCase(key, "sqlite3"))
ffStrbufSetS(&config->libSQLite3, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "rpm"))
ffStrbufSetS(&config->librpm, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "imagemagick"))
ffStrbufSetS(&config->libImageMagick, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "z"))
ffStrbufSetS(&config->libZ, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "chafa"))
ffStrbufSetS(&config->libChafa, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "egl"))
ffStrbufSetS(&config->libEGL, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "glx"))
ffStrbufSetS(&config->libGLX, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "osmesa"))
ffStrbufSetS(&config->libOSMesa, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "opencl"))
ffStrbufSetS(&config->libOpenCL, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "pulse"))
ffStrbufSetS(&config->libPulse, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "nm"))
ffStrbufSetS(&config->libnm, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "ddcutil"))
ffStrbufSetS(&config->libDdcutil, yyjson_get_str(val));
else
return "Unknown library property";
}
return NULL;
}
void ffPrintJsonConfig(bool prepare)
{
const char* error = printJsonConfig(prepare);
const char* error = printJsonConfig(prepare, jsonDoc);
if (error)
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
{
if (jsonDoc)
{
yyjson_mut_val* obj = yyjson_mut_obj(jsonDoc);
yyjson_mut_obj_add_str(jsonDoc, obj, "error", error);
yyjson_mut_doc_set_root(jsonDoc, obj);
}
else
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
}
}
+6 -4
View File
@@ -4,10 +4,12 @@
bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs);
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]);
void ffPrintJsonConfig(bool prepare);
const char* ffParseGeneralJsonConfig(void);
const char* ffParseDisplayJsonConfig(void);
const char* ffParseLibraryJsonConfig(void);
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc);
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs);
yyjson_api_inline yyjson_mut_val* yyjson_mut_strbuf(yyjson_mut_doc *doc, const FFstrbuf* buf) {
return yyjson_mut_strncpy(doc, buf->chars, buf->length);
}
yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
+57 -57
View File
@@ -5,32 +5,32 @@ static FFModuleBaseInfo* A[] = {
};
static FFModuleBaseInfo* B[] = {
(void*) &instance.config.battery,
(void*) &instance.config.bios,
(void*) &instance.config.bluetooth,
(void*) &instance.config.board,
(void*) &instance.config.break_,
(void*) &instance.config.brightness,
(void*) &instance.config.modules.battery,
(void*) &instance.config.modules.bios,
(void*) &instance.config.modules.bluetooth,
(void*) &instance.config.modules.board,
(void*) &instance.config.modules.break_,
(void*) &instance.config.modules.brightness,
NULL,
};
static FFModuleBaseInfo* C[] = {
(void*) &instance.config.chassis,
(void*) &instance.config.command,
(void*) &instance.config.colors,
(void*) &instance.config.cpu,
(void*) &instance.config.cpuUsage,
(void*) &instance.config.cursor,
(void*) &instance.config.custom,
(void*) &instance.config.modules.chassis,
(void*) &instance.config.modules.command,
(void*) &instance.config.modules.colors,
(void*) &instance.config.modules.cpu,
(void*) &instance.config.modules.cpuUsage,
(void*) &instance.config.modules.cursor,
(void*) &instance.config.modules.custom,
NULL,
};
static FFModuleBaseInfo* D[] = {
(void*) &instance.config.dateTime,
(void*) &instance.config.de,
(void*) &instance.config.display,
(void*) &instance.config.disk,
(void*) &instance.config.diskIo,
(void*) &instance.config.modules.dateTime,
(void*) &instance.config.modules.de,
(void*) &instance.config.modules.display,
(void*) &instance.config.modules.disk,
(void*) &instance.config.modules.diskIo,
NULL,
};
@@ -39,23 +39,23 @@ static FFModuleBaseInfo* E[] = {
};
static FFModuleBaseInfo* F[] = {
(void*) &instance.config.font,
(void*) &instance.config.modules.font,
NULL,
};
static FFModuleBaseInfo* G[] = {
(void*) &instance.config.gamepad,
(void*) &instance.config.gpu,
(void*) &instance.config.modules.gamepad,
(void*) &instance.config.modules.gpu,
NULL,
};
static FFModuleBaseInfo* H[] = {
(void*) &instance.config.host,
(void*) &instance.config.modules.host,
NULL,
};
static FFModuleBaseInfo* I[] = {
(void*) &instance.config.icons,
(void*) &instance.config.modules.icons,
NULL,
};
@@ -64,42 +64,42 @@ static FFModuleBaseInfo* J[] = {
};
static FFModuleBaseInfo* K[] = {
(void*) &instance.config.kernel,
(void*) &instance.config.modules.kernel,
NULL,
};
static FFModuleBaseInfo* L[] = {
(void*) &instance.config.lm,
(void*) &instance.config.locale,
(void*) &instance.config.localIP,
(void*) &instance.config.modules.lm,
(void*) &instance.config.modules.locale,
(void*) &instance.config.modules.localIP,
NULL,
};
static FFModuleBaseInfo* M[] = {
(void*) &instance.config.media,
(void*) &instance.config.memory,
(void*) &instance.config.monitor,
(void*) &instance.config.modules.media,
(void*) &instance.config.modules.memory,
(void*) &instance.config.modules.monitor,
NULL,
};
static FFModuleBaseInfo* N[] = {
(void*) &instance.config.netIo,
(void*) &instance.config.modules.netIo,
NULL,
};
static FFModuleBaseInfo* O[] = {
(void*) &instance.config.openCL,
(void*) &instance.config.openGL,
(void*) &instance.config.os,
(void*) &instance.config.modules.openCL,
(void*) &instance.config.modules.openGL,
(void*) &instance.config.modules.os,
NULL,
};
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.packages,
(void*) &instance.config.player,
(void*) &instance.config.powerAdapter,
(void*) &instance.config.processes,
(void*) &instance.config.publicIP,
(void*) &instance.config.modules.packages,
(void*) &instance.config.modules.player,
(void*) &instance.config.modules.powerAdapter,
(void*) &instance.config.modules.processes,
(void*) &instance.config.modules.publicIP,
NULL,
};
@@ -112,40 +112,40 @@ static FFModuleBaseInfo* R[] = {
};
static FFModuleBaseInfo* S[] = {
(void*) &instance.config.separator,
(void*) &instance.config.shell,
(void*) &instance.config.sound,
(void*) &instance.config.swap,
(void*) &instance.config.modules.separator,
(void*) &instance.config.modules.shell,
(void*) &instance.config.modules.sound,
(void*) &instance.config.modules.swap,
NULL,
};
static FFModuleBaseInfo* T[] = {
(void*) &instance.config.terminal,
(void*) &instance.config.terminalFont,
(void*) &instance.config.terminalSize,
(void*) &instance.config.title,
(void*) &instance.config.theme,
(void*) &instance.config.modules.terminal,
(void*) &instance.config.modules.terminalFont,
(void*) &instance.config.modules.terminalSize,
(void*) &instance.config.modules.title,
(void*) &instance.config.modules.theme,
NULL,
};
static FFModuleBaseInfo* U[] = {
(void*) &instance.config.uptime,
(void*) &instance.config.users,
(void*) &instance.config.modules.uptime,
(void*) &instance.config.modules.users,
NULL,
};
static FFModuleBaseInfo* V[] = {
(void*) &instance.config.version,
(void*) &instance.config.vulkan,
(void*) &instance.config.modules.version,
(void*) &instance.config.modules.vulkan,
NULL,
};
static FFModuleBaseInfo* W[] = {
(void*) &instance.config.wallpaper,
(void*) &instance.config.weather,
(void*) &instance.config.wm,
(void*) &instance.config.wifi,
(void*) &instance.config.wmTheme,
(void*) &instance.config.modules.wallpaper,
(void*) &instance.config.modules.weather,
(void*) &instance.config.modules.wm,
(void*) &instance.config.modules.wifi,
(void*) &instance.config.modules.wmTheme,
NULL,
};
+7 -4
View File
@@ -17,8 +17,9 @@ typedef struct FFModuleBaseInfo
bool (*parseCommandOptions)(void* options, const char* key, const char* value);
void (*parseJsonObject)(void* options, struct yyjson_val *module);
void (*printModule)(void* options);
void (*generateJson)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
void (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
void (*printHelpFormat)(void);
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
} FFModuleBaseInfo;
static inline void ffOptionInitModuleBaseInfo(
@@ -27,16 +28,18 @@ static inline void ffOptionInitModuleBaseInfo(
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
void* printModule, // void (*const printModule)(void* options)
void* generateJson, // void (*const generateJson)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
void (*printHelpFormat)(void)
void* generateJsonResult, // void (*const generateJsonResult)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
void (*printHelpFormat)(void),
void* generateJsonConfig // void (*const generateJsonConfig)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
)
{
baseInfo->name = name;
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
baseInfo->generateJson = (__typeof__(baseInfo->generateJson)) generateJson;
baseInfo->generateJsonResult = (__typeof__(baseInfo->generateJsonResult)) generateJsonResult;
baseInfo->printHelpFormat = printHelpFormat;
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
}
typedef struct FFModuleArgs
+4 -4
View File
@@ -65,7 +65,7 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
double size = (double) bytes;
uint8_t counter = 0;
while(size >= base && counter < instance.config.sizeMaxPrefix && prefixes[counter + 1])
while(size >= base && counter < instance.config.display.sizeMaxPrefix && prefixes[counter + 1])
{
size /= base;
counter++;
@@ -74,12 +74,12 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
if(counter == 0)
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
else
ffStrbufAppendF(result, "%.*f %s", instance.config.sizeNdigits, size, prefixes[counter]);
ffStrbufAppendF(result, "%.*f %s", instance.config.display.sizeNdigits, size, prefixes[counter]);
}
void ffParseSize(uint64_t bytes, FFstrbuf* result)
{
switch (instance.config.binaryPrefixType)
switch (instance.config.display.binaryPrefixType)
{
case FF_BINARY_PREFIX_TYPE_IEC:
parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
@@ -98,7 +98,7 @@ void ffParseSize(uint64_t bytes, FFstrbuf* result)
void ffParseTemperature(double celsius, FFstrbuf* buffer)
{
switch (instance.config.temperatureUnit)
switch (instance.config.display.temperatureUnit)
{
case FF_TEMPERATURE_UNIT_CELSIUS:
ffStrbufAppendF(buffer, "%.1f°C", celsius);
+11 -11
View File
@@ -14,16 +14,16 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
if(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " "))
return;
if(!instance.config.pipe)
if(!instance.config.display.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (instance.config.brightColor)
if (instance.config.display.brightColor)
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
ffPrintColor(&moduleArgs->keyColor);
else
ffPrintColor(&instance.config.colorKeys);
ffPrintColor(&instance.config.display.colorKeys);
}
//NULL check is required for modules with custom keys, e.g. disk with the folder path
@@ -43,18 +43,18 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
ffStrbufWriteTo(&key, stdout);
}
if(!instance.config.pipe)
if(!instance.config.display.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
ffStrbufWriteTo(&instance.config.keyValueSeparator, stdout);
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
if(!instance.config.pipe)
if(!instance.config.display.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (!instance.config.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
if (!instance.config.display.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
{
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.keyWidth;
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
if (keyWidth > 0)
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
}
@@ -77,17 +77,17 @@ void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFMo
static void printError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, va_list arguments)
{
if(!instance.config.showErrors)
if(!instance.config.display.showErrors)
return;
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
if(!instance.config.pipe)
if(!instance.config.display.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
vprintf(message, arguments);
if(!instance.config.pipe)
if(!instance.config.display.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
putchar('\n');
+3 -2
View File
@@ -34,10 +34,11 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
//Child
if(childPid == 0)
{
int nullFile = open("/dev/null", O_WRONLY);
dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
dup2(nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
close(pipes[0]);
close(pipes[1]);
close(useStdErr ? STDOUT_FILENO : STDERR_FILENO);
setenv("LANG", "C", 1);
execvp(argv[0], argv);
exit(901);
@@ -48,7 +49,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
int FF_AUTO_CLOSE_FD childPipeFd = pipes[0];
int timeout = instance.config.processingTimeout;
int timeout = instance.config.general.processingTimeout;
if (timeout >= 0)
fcntl(childPipeFd, F_SETFL, fcntl(childPipeFd, F_GETFL) | O_NONBLOCK);
+1 -1
View File
@@ -8,7 +8,7 @@ enum { FF_PIPE_BUFSIZ = 4096 };
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
{
int timeout = instance.config.processingTimeout;
int timeout = instance.config.general.processingTimeout;
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW(
L"\\\\.\\pipe\\LOCAL\\",
+4 -11
View File
@@ -15,18 +15,14 @@ typedef enum FFInitState
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
static dataObject data; \
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
ffThreadMutexLock(&mutex); \
if(initState != FF_INITSTATE_UNINITIALIZED) {\
ffThreadMutexUnlock(&mutex); \
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
} \
initState = FF_INITSTATE_SUCCESSFUL; \
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
if(libraryHandle == NULL) { \
initState = FF_INITSTATE_FAILED; \
ffThreadMutexUnlock(&mutex); \
return NULL; \
} \
@@ -35,20 +31,17 @@ typedef enum FFInitState
if(data.ff ## symbolName == NULL) { \
dlclose(libraryHandle); \
initState = FF_INITSTATE_FAILED; \
ffThreadMutexUnlock(&mutex); \
return NULL; \
}
#define FF_LIBRARY_DATA_LOAD_RETURN \
initState = FF_INITSTATE_SUCCESSFUL; \
ffThreadMutexUnlock(&mutex); \
return &data;
#define FF_LIBRARY_DATA_LOAD_ERROR \
{ \
dlclose(libraryHandle); \
initState = FF_INITSTATE_FAILED; \
ffThreadMutexUnlock(&mutex); \
return NULL; \
}
@@ -99,7 +92,7 @@ typedef struct GSettingsData
static const GSettingsData* getGSettingsData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.library.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key)
@@ -172,7 +165,7 @@ typedef struct DConfData
static const DConfData* getDConfData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.library.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full)
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
@@ -243,7 +236,7 @@ typedef struct XFConfData
static const XFConfData* getXFConfData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.library.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get)
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property)
@@ -305,7 +298,7 @@ typedef struct SQLiteData
static const SQLiteData* getSQLiteData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.library.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
+26 -17
View File
@@ -14,20 +14,20 @@ Informative options:
--print-config-system: Print the default system config
--print-config-user: Print the default user config
--print-structure: Print the default structure
--gen-config <?type>: Generate a sample config file in the default path. Param `type` can be `jsonc` or `conf`
--gen-config-force <?type>: Generate a sample config file in the default path. Overwrite the existing one
Config options:
--load-config,--config,-c <file>: Load a config file or preset (+)
--gen-config <type>: Generate a sample config file in the default path. Param `type` can be `jsonc` or deprecated `conf`
--gen-config-force <type>: Generate a sample config file in the default path. Overwrite the existing one
--migrate-config <?path>: Migrate old flag based config file to new JSONC format. Optional param `path` is the file path that new file should be write to
General options:
--load-config <file>: Load a config file or preset (+)
--config <file>: Alias of --load-config (+)
--multithreading <?value>: Use multiple threads to detect values
--stat <?value>: Show time usage (in ms) for individual modules
--allow-slow-operations <?value>: Allow operations that are usually very slow for more detailed output
--escape-bedrock <?value>: On Bedrock Linux, whether to escape the bedrock jail
--pipe <?value>: Disable logo and all escape sequences
--wmi-timeout <num>: Set the timeout (ms) for WMI queries. Windows only. Default is 5000
--processing-timeout <num>: Set the timeout (ms) when waiting for child processes. Default is 1000
--ds-force-drm <?value>: Set if only DRM should be used to detect displays. Default is false
--multithreading,--thread <?value>: Use multiple threads to detect values
--allow-slow-operations <?value>: Allow operations that are usually very slow for more detailed output
--escape-bedrock <?value>: On Bedrock Linux, whether to escape the bedrock jail
--wmi-timeout <num>: Set the timeout (ms) for WMI queries. Windows only. Default is 5000
--processing-timeout <num>: Set the timeout (ms) when waiting for child processes. Default is 1000
--ds-force-drm <?value>: Set if only DRM should be used to detect displays. Default is false. Linux only
Logo options:
-l,--logo <logo>: Set the logo; if default, the name of a builtin logo or a path to a file
@@ -41,6 +41,7 @@ Logo options:
--logo-padding-right <padding>: Set the padding on the right of the logo
--logo-padding-top <padding>: Set the padding on the top of the logo
--logo-print-remaining <?value>: Whether to print the remaining logo, if it has more lines than modules to display
--logo-separate <?value>: If true, print modules at bottom of the logo
--logo-recache <?value>: If true, regenerate image logo cache
--file <file>: Short for --logo-type file --logo <file>
--file-raw <file>: Short for --logo-type file-raw --logo <file>
@@ -58,6 +59,8 @@ Logo options:
Display options:
-s,--structure <structure>: Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available.
--stat <?value>: Show time usage (in ms) for individual modules
--pipe <?value>: Disable logo and all escape sequences
--color-keys <color>: Set the color of the keys
--color-title <color>: Set the color of the title
--color <color>: Set the color of both the keys and title
@@ -122,8 +125,9 @@ Module specific options:
--title-color-user <color>: Set color of the user name (left part). Default is empty (use color of `--color-title`).
--title-color-at <color>: Set color of the @ symbol (middle part). Default is empty (use color of `--color-title`)
--title-color-host <color>: Set color of the host name (right part). Default is empty (use color of `--color-title`)
--chassis-use-wmi <?value>: Set if WMI query should be used on Windows, which detects more information but slower. Default is false
--separator-string <str>: Set the string printed by the separator module
--os-file <path>: Set the path to the file containing OS information
--os-file <path>: Set the path to the file containing OS information. Linux only
--disk-folders <folders>: A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows)
--disk-show-regular <?value>: Set if regular volume should be printed. Default is true
--disk-show-external <?value>: Set if external volume should be printed. Default is true
@@ -134,16 +138,20 @@ Module specific options:
--disk-use-available <?value>: Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes. Default is false
--diskio-name-prefix <str>: Show disks with given name prefix only. Default is empty
--bluetooth-show-disconnected: <?value>: Set if disconnected bluetooth devices should be printed. Default is false
--packages-winget: <?value>: Set if winget package count should be detected. Default is false
--display-compact-type: <?string>: Set if all displays should be printed in one line. Default is none
--display-detect-name: <?value>: Set if display name should be detected and printed (if supported). Default is false
--display-precise-refresh-rate: <?value>:Set if decimal refresh rates should not be rounded into integers when printing. Default is true
--brightness-ddcci-sleep: <num> Set the sleep times (in ms) when sending DDC/CI requests. See <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for detail. Default is 10
--sound-type: <value>: Set what type of sound devices should be printed. Should be either main, active or all. Default is main
--battery-dir <folder>: The directory where the battery folders are. Standard: /sys/class/power_supply/
--battery-dir <folder>: The directory where the battery folders are. Standard: `/sys/class/power_supply/`. Linux only
--battery-use-setup-api <?value>: Set if `SetupAPI` should be used on Windows to detect battery info, which supports multi batteries, but slower. Windows only
--cpu-temp <?value>: Detect and display CPU temperature if supported. Default is false
--cpu-freq-ndigits <num>: Set the number of digits to keep after the decimal point when printing CPU frequency. Default is 2
--cpuusage-separate <?value>: Display CPU usage per CPU logical core, instead of an average result. Default is false
--de-slow-version-detection <?value>: Set if DE version should be detected with slow operations. Default is false
--gpu-temp <?value>: Detect and display GPU temperature if supported. Default is false
--gpu-use-nvml <?value>: Use nvml (NVIDIA Management Library) to detect more detailed GPU information (memory usage, CUDA core count, etc). Default is false
--gpu-force-vulkan <?value>: Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`. Default is false
--gpu-hide-type <?value>: Specify the type of GPUs should not be printed. Must be `integrated`, `discrete` or `none`. Default is none
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
@@ -152,16 +160,17 @@ Module specific options:
--localip-show-mac <?value>: Show mac addresses in local ip module. Default is false
--localip-show-loop <?value>: Show loop back addresses (127.0.0.1) in local ip module. Default is false
--localip-name-prefix <str>: Show interfaces with given interface name prefix only. Default is empty
--localip-default-route-only <?value>: Show the interface that is used for default routing only. Default is false
--localip-default-route-only <?value>: Show the interface that is used for default routing only. Default is true
--localip-compact <?value>: Show all IPs in one line. Default is false
--netio-name-prefix <str>: Show interfaces with given name prefix only. Default is empty
--netio-default-route-only <?value>: Show the interfac that is used for default routing only. Default is false
--netio-default-route-only <?value>: Show the interfac that is used for default routing only. Default is true
--publicip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
--publicip-url: The URL of public IP detection server to be used.
--weather-location: Set the location to be used. It must be URI encoded (eg a whitespace must be encoded as `+`).
--weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0)
--weather-output-format: The output weather format to be used. It must be URI encoded.
--player-name: The name of the player to use
--wm-detect-plugin: Set if window manager plugin should be detected on supported platforms. Default is false
--player-name: The name of the player to use for module Media and Player. Linux only
--opengl-library <value>: Set the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto
--command-shell <str>: Set the shell program to execute the command text. Default is cmd for Windows, /bin/sh for *nix
--command-key <str>: Set the module key to display
+1 -1
View File
@@ -1 +1 @@
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:PowerAdapter:Locale:Break:Colors
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Locale:Break:Colors
+1 -1
View File
@@ -32,7 +32,7 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
{
if(instance.config.allowSlowOperations)
if(options->useSetupApi)
{
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) =
+1 -1
View File
@@ -100,7 +100,7 @@ double ddca_set_default_sleep_multiplier(double multiplier); // ddcutil 1.4
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
{
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
FF_LIBRARY_LOAD(libddcutil, &instance.config.library.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)
+1 -1
View File
@@ -12,7 +12,7 @@ typedef struct FFChassisResult
FFstrbuf version;
} FFChassisResult;
const char* ffDetectChassis(FFChassisResult* result);
const char* ffDetectChassis(FFChassisResult* result, FFChassisOptions* options);
const char* ffChassisTypeToString(uint32_t type);
#endif
+1 -1
View File
@@ -2,7 +2,7 @@
#include "common/settings.h"
#include "util/smbiosHelper.h"
const char* ffDetectChassis(FFChassisResult* result)
const char* ffDetectChassis(FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
{
// Unlike other platforms, `smbios.chassis.type` return display string directly on my machine
ffSettingsGetFreeBSDKenv("smbios.chassis.type", &result->type);
+1 -1
View File
@@ -17,7 +17,7 @@ static void getSmbiosValue(const char* devicesPath, const char* classPath, FFstr
ffStrbufClear(buffer);
}
const char* ffDetectChassis(FFChassisResult* result)
const char* ffDetectChassis(FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
{
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->type);
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->vendor);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "chassis.h"
const char* ffDetectChassis(FF_MAYBE_UNUSED FFChassisResult* result)
const char* ffDetectChassis(FF_MAYBE_UNUSED FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
{
return "Not supported on this platform";
}
+3 -3
View File
@@ -36,7 +36,7 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result)
{
auto [arr, len] = vtProp.get<std::pair<const int32_t*, uint32_t>>();
if(len == 0)
return "ChassisTypes contain no data failed";
return "ChassisTypes contain no data";
for (uint32_t i = 0; i < len; ++i)
{
if (i > 0)
@@ -65,9 +65,9 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result)
}
extern "C"
const char* ffDetectChassis(FFChassisResult* result)
const char* ffDetectChassis(FFChassisResult* result, FFChassisOptions* options)
{
if (instance.config.allowSlowOperations)
if (options->useWmi)
return detectWithWmi(result);
return detectWithRegistry(result);
}
+6 -1
View File
@@ -47,7 +47,8 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
ffParsePropLine(line, "isa :", cpuIsa) ||
ffParsePropLine(line, "uarch :", cpuUarch) ||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) //For POWER
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) //For MIPS
);
}
@@ -115,6 +116,10 @@ static void parseIsa(FFstrbuf* cpuIsa)
}
// The final ISA output of the above example is "rv64gch".
}
if(ffStrbufStartsWithS(cpuIsa, "mips"))
{
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
}
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
+7 -3
View File
@@ -27,6 +27,7 @@ const char* ffGetCpuUsageResult(FFlist* result)
if(cpuTimes1.length == 0) return "No CPU cores found";
FF_LIST_AUTO_DESTROY cpuTimes2 = ffListCreate(sizeof(FFCpuUsageInfo));
uint32_t retryCount = 0;
retry:
error = ffGetCpuUsageInfo(&cpuTimes2);
@@ -39,9 +40,12 @@ retry:
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
if (cpuTime2->totalAll <= cpuTime1->totalAll)
{
ffListClear(&cpuTimes2);
ffTimeSleep(200);
goto retry;
if (++retryCount <= 3)
{
ffListClear(&cpuTimes2);
ffTimeSleep(200);
goto retry;
}
}
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "fastfetch.h"
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options);
+173
View File
@@ -0,0 +1,173 @@
#include "de.h"
#include "common/io/io.h"
#include "common/parsing.h"
#include "common/properties.h"
#include "common/processing.h"
#include "detection/displayserver/displayserver.h"
#include "util/stringUtils.h"
#include <ctype.h>
static void getKDE(FFstrbuf* result, FFDEOptions* options)
{
ffParsePropFileValues("/usr/share/xsessions/plasmax11.desktop", 1, (FFpropquery[]) {
{"X-KDE-PluginInfo-Version =", result}
});
if(result->length == 0)
ffParsePropFileData("xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", result);
if(result->length == 0)
ffParsePropFileData("xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", result);
if(result->length == 0)
{
ffParsePropFileValues("/usr/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) {
{"X-KDE-PluginInfo-Version =", result}
});
}
if(result->length == 0)
ffParsePropFileData("wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", result);
if(result->length == 0)
ffParsePropFileData("wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", result);
if(result->length == 0 && options->slowVersionDetection)
{
if (ffProcessAppendStdOut(result, (char* const[]){
"plasmashell",
"--version",
NULL
}) == NULL) // plasmashell 5.27.5
ffStrbufSubstrAfterLastC(result, ' ');
}
}
static void getGnome(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
ffParsePropFileData("gnome-shell/org.gnome.Extensions", "version :", result);
if (result->length == 0)
{
if (ffProcessAppendStdOut(result, (char* const[]){
"gnome-shell",
"--version",
NULL
}) == NULL) // GNOME Shell 44.1
ffStrbufSubstrAfterLastC(result, ' ');
}
}
static void getCinnamon(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
}
static void getMate(FFstrbuf* result, FFDEOptions* options)
{
FF_STRBUF_AUTO_DESTROY major = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY micro = ffStrbufCreate();
ffParsePropFileDataValues("mate-about/mate-version.xml", 3, (FFpropquery[]) {
{"<platform>", &major},
{"<minor>", &minor},
{"<micro>", &micro}
});
ffParseSemver(result, &major, &minor, &micro);
if(result->length == 0 && options->slowVersionDetection)
{
ffProcessAppendStdOut(result, (char* const[]){
"mate-session",
"--version",
NULL
});
ffStrbufSubstrAfterFirstC(result, ' ');
ffStrbufTrim(result, ' ');
}
}
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
{
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", result);
#ifdef __FreeBSD__
if(result->length == 0)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
if (dirp)
{
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
continue;
ffStrbufAppendS(result, &entry->d_name[5]);
}
}
}
#endif
if(result->length == 0 && options->slowVersionDetection)
{
//This is somewhat slow
ffProcessAppendStdOut(result, (char* const[]){
"xfce4-session",
"--version",
NULL
});
ffStrbufSubstrBeforeFirstC(result, '(');
ffStrbufSubstrAfterFirstC(result, ' ');
ffStrbufTrim(result, ' ');
}
}
static void getLXQt(FFstrbuf* result, FFDEOptions* options)
{
ffParsePropFileData("gconfig/lxqt.pc", "Version:", result);
if(result->length == 0)
ffParsePropFileData("cmake/lxqt/lxqt-config.cmake", "set ( LXQT_VERSION", result);
if(result->length == 0)
ffParsePropFileData("cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", result);
if(result->length == 0 && options->slowVersionDetection)
{
//This is really, really, really slow. Thank you, LXQt developers
ffProcessAppendStdOut(result, (char* const[]){
"lxqt-session",
"-v",
NULL
});
result->length = 0; //don't set '\0' byte
ffParsePropLines(result->chars , "liblxqt", result);
}
}
static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
}
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
{
if (ffStrbufEqualS(deName, FF_DE_PRETTY_PLASMA))
getKDE(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME) || ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME))
getGnome(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_CINNAMON))
getCinnamon(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_XFCE4))
getXFCE4(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_MATE))
getMate(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_LXQT))
getLXQt(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
getBudgie(result, options);
else
return "Unsupported DE";
return NULL;
}
+6
View File
@@ -0,0 +1,6 @@
#include "de.h"
const char* ffDetectDEVersion(FF_MAYBE_UNUSED const FFstrbuf* deName, FF_MAYBE_UNUSED FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
return "Not supported on this platform";
}
@@ -68,7 +68,6 @@ typedef struct FFDisplayServerResult
FFstrbuf wmProtocolName;
FFstrbuf deProcessName;
FFstrbuf dePrettyName;
FFstrbuf deVersion;
FFlist displays; //List of FFDisplayResult
} FFDisplayServerResult;
@@ -75,7 +75,7 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
{
// Only for MiUI
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
;
if (ffSettingsGetAndroidProperty("persist.sys.miui_resolution", &buffer) &&
ffStrbufContainC(&buffer, ','))
{
@@ -107,7 +107,6 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
ffStrbufInit(&ds->wmProtocolName);
ffStrbufInit(&ds->deProcessName);
ffStrbufInit(&ds->dePrettyName);
ffStrbufInit(&ds->deVersion);
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 0);
if (!detectWithGetprop(ds))
@@ -1,10 +1,7 @@
#include "displayserver.h"
#include "common/sysctl.h"
#include "util/apple/cf_helpers.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <CoreGraphics/CGDirectDisplay.h>
@@ -70,35 +67,6 @@ static void detectDisplays(FFDisplayServerResult* ds)
}
}
static void detectWMPlugin(FFstrbuf* name)
{
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
u_int requestLength = sizeof(request) / sizeof(*request);
size_t length = 0;
FF_AUTO_FREE struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length);
if(processes == NULL)
return;
for(size_t i = 0; i < length / sizeof(struct kinfo_proc); i++)
{
const char* comm = processes[i].kp_proc.p_comm;
if(
strcasecmp(comm, "spectacle") != 0 &&
strcasecmp(comm, "amethyst") != 0 &&
strcasecmp(comm, "kwm") != 0 &&
strcasecmp(comm, "chunkwm") != 0 &&
strcasecmp(comm, "yabai") != 0 &&
strcasecmp(comm, "rectangle") != 0
) continue;
ffStrbufAppendS(name, comm);
name->chars[0] = (char) toupper(name->chars[0]);
break;
}
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
{
{
@@ -116,18 +84,8 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
}
ffStrbufInit(&ds->wmProtocolName);
if(instance.config.allowSlowOperations)
{
FF_STRBUF_AUTO_DESTROY name;
ffStrbufInit(&name);
detectWMPlugin(&name);
if(name.length)
ffStrbufAppendF(&ds->wmPrettyName, " (with %s)", name.chars);
}
ffStrbufInit(&ds->deProcessName);
ffStrbufInitStatic(&ds->dePrettyName, "Aqua");
ffStrbufInit(&ds->deVersion);
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
detectDisplays(ds);
@@ -143,20 +143,21 @@ static void detectDisplays(FFDisplayServerResult* ds)
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
{
BOOL enabled;
if(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled == TRUE)
if(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
{
ffStrbufInitStatic(&ds->wmProcessName, "dwm.exe");
ffStrbufInitStatic(&ds->wmPrettyName, "Desktop Window Manager");
}
else
{
// `explorer.exe` only provides a subset of WM functions, as well as the taskbar and desktop icons.
// While a window itself is drawn by kernel (GDI). Killing `explorer.exe` won't affect how windows are displayed generally.
ffStrbufInitStatic(&ds->wmProcessName, "explorer.exe");
ffStrbufInitStatic(&ds->wmPrettyName, "Windows Explorer");
ffStrbufInitStatic(&ds->wmPrettyName, "Internal");
}
ffStrbufInit(&ds->wmProtocolName);
ffStrbufInit(&ds->deProcessName);
ffStrbufInit(&ds->dePrettyName);
ffStrbufInit(&ds->deVersion);
ffListInit(&ds->displays, sizeof(FFDisplayResult));
detectDisplays(ds);
@@ -85,10 +85,9 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
ffStrbufInit(&ds->wmProtocolName);
ffStrbufInit(&ds->deProcessName);
ffStrbufInit(&ds->dePrettyName);
ffStrbufInit(&ds->deVersion);
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
if (!instance.config.dsForceDrm)
if (!instance.config.general.dsForceDrm)
{
//We try wayland as our prefered display server, as it supports the most features.
//This method can't detect the name of our WM / DE
+1 -6
View File
@@ -202,9 +202,6 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist
if(display.width <= 0 || display.height <= 0)
return;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
ffThreadMutexLock(&mutex);
switch(display.transform)
{
case WL_OUTPUT_TRANSFORM_90:
@@ -262,8 +259,6 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist
ffStrbufDestroy(&display.vendorAndModelId);
ffStrbufDestroy(&display.name);
ffStrbufDestroy(&display.edidName);
ffThreadMutexUnlock(&mutex);
}
static void waylandGlobalAddListener(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
@@ -276,7 +271,7 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
bool detectWayland(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(wayland, &instance.config.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD(wayland, &instance.config.library.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false)
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false)
+36 -179
View File
@@ -1,7 +1,6 @@
#include "displayserver_linux.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "common/parsing.h"
#include "common/processing.h"
#include "util/stringUtils.h"
@@ -131,177 +130,6 @@ static void applyBetterWM(FFDisplayServerResult* result, const char* processName
ffStrbufAppend(&result->wmPrettyName, &result->wmProcessName);
}
static void getKDE(FFDisplayServerResult* result)
{
ffStrbufSetS(&result->deProcessName, "plasmashell");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
ffParsePropFileValues("/usr/share/xsessions/plasmax11.desktop", 1, (FFpropquery[]) {
{"X-KDE-PluginInfo-Version =", &result->deVersion}
});
if(result->deVersion.length == 0)
ffParsePropFileData("xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0)
ffParsePropFileData("xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0)
{
ffParsePropFileValues("/usr/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) {
{"X-KDE-PluginInfo-Version =", &result->deVersion}
});
}
if(result->deVersion.length == 0)
ffParsePropFileData("wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0)
ffParsePropFileData("wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
{
if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){
"plasmashell",
"--version",
NULL
}) == NULL) // plasmashell 5.27.5
ffStrbufSubstrAfterLastC(&result->deVersion, ' ');
}
applyBetterWM(result, getenv("KDEWM"));
}
static void getGnome(FFDisplayServerResult* result)
{
ffStrbufSetS(&result->deProcessName, "gnome-shell");
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
if (sessionMode && ffStrEquals(sessionMode, "classic"))
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC);
else
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME);
ffParsePropFileData("gnome-shell/org.gnome.Extensions", "version :", &result->deVersion);
if (result->deVersion.length == 0)
{
if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){
"gnome-shell",
"--version",
NULL
}) == NULL) // GNOME Shell 44.1
ffStrbufSubstrAfterLastC(&result->deVersion, ' ');
}
}
static void getCinnamon(FFDisplayServerResult* result)
{
ffStrbufSetS(&result->deProcessName, "cinnamon");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", &result->deVersion);
}
static void getMate(FFDisplayServerResult* result)
{
ffStrbufSetS(&result->deProcessName, "mate-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
FF_STRBUF_AUTO_DESTROY major = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY micro = ffStrbufCreate();
ffParsePropFileDataValues("mate-about/mate-version.xml", 3, (FFpropquery[]) {
{"<platform>", &major},
{"<minor>", &minor},
{"<micro>", &micro}
});
ffParseSemver(&result->deVersion, &major, &minor, &micro);
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
{
ffProcessAppendStdOut(&result->deVersion, (char* const[]){
"mate-session",
"--version",
NULL
});
ffStrbufSubstrAfterFirstC(&result->deVersion, ' ');
ffStrbufTrim(&result->deVersion, ' ');
}
}
static void getXFCE4(FFDisplayServerResult* result)
{
ffStrbufSetS(&result->deProcessName, "xfce4-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", &result->deVersion);
#ifdef __FreeBSD__
if(result->deVersion.length == 0)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
if (dirp)
{
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
continue;
ffStrbufAppendS(&result->deVersion, &entry->d_name[5]);
}
}
}
#endif
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
{
//This is somewhat slow
ffProcessAppendStdOut(&result->deVersion, (char* const[]){
"xfce4-session",
"--version",
NULL
});
ffStrbufSubstrBeforeFirstC(&result->deVersion, '(');
ffStrbufSubstrAfterFirstC(&result->deVersion, ' ');
ffStrbufTrim(&result->deVersion, ' ');
}
}
static void getLXQt(FFDisplayServerResult* result)
{
ffStrbufSetS(&result->deProcessName, "lxqt-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
ffParsePropFileData("gconfig/lxqt.pc", "Version:", &result->deVersion);
if(result->deVersion.length == 0)
ffParsePropFileData("cmake/lxqt/lxqt-config.cmake", "set ( LXQT_VERSION", &result->deVersion);
if(result->deVersion.length == 0)
ffParsePropFileData("cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", &result->deVersion);
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
{
//This is really, really, really slow. Thank you, LXQt developers
ffProcessAppendStdOut(&result->deVersion, (char* const[]){
"lxqt-session",
"-v",
NULL
});
result->deVersion.length = 0; //don't set '\0' byte
ffParsePropLines(result->deVersion.chars , "liblxqt", &result->deVersion);
}
FF_STRBUF_AUTO_DESTROY wmProcessNameBuffer = ffStrbufCreate();
ffParsePropFileConfig("lxqt/session.conf", "window_manager =", &wmProcessNameBuffer);
applyBetterWM(result, wmProcessNameBuffer.chars);
}
static void getBudgie(FFDisplayServerResult* result)
{
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
ffParsePropFileData("budgie/budgie-version.xml", "<str>", &result->deVersion);
}
static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
{
if(!ffStrSet(name))
@@ -312,19 +140,33 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
strcasecmp(name, "plasma") == 0 ||
strcasecmp(name, "plasmashell") == 0 ||
strcasecmp(name, "plasmawayland") == 0
) getKDE(result);
) {
ffStrbufSetStatic(&result->deProcessName, "plasmashell");
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
applyBetterWM(result, getenv("KDEWM"));
}
else if(
strcasecmp(name, "Gnome") == 0 ||
strcasecmp(name, "ubuntu:GNOME") == 0 ||
strcasecmp(name, "ubuntu") == 0 ||
strcasecmp(name, "gnome-shell") == 0
) getGnome(result);
) {
ffStrbufSetStatic(&result->deProcessName, "gnome-shell");
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
if (sessionMode && ffStrEquals(sessionMode, "classic"))
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC);
else
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_GNOME);
}
else if(
strcasecmp(name, "X-Cinnamon") == 0 ||
strcasecmp(name, "Cinnamon") == 0
) getCinnamon(result);
) {
ffStrbufSetS(&result->deProcessName, "cinnamon");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
}
else if(
strcasecmp(name, "XFCE") == 0 ||
@@ -332,26 +174,41 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
strcasecmp(name, "XFCE4") == 0 ||
strcasecmp(name, "X-XFCE4") == 0 ||
strcasecmp(name, "xfce4-session") == 0
) getXFCE4(result);
) {
ffStrbufSetS(&result->deProcessName, "xfce4-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
}
else if(
strcasecmp(name, "MATE") == 0 ||
strcasecmp(name, "X-MATE") == 0 ||
strcasecmp(name, "mate-session") == 0
) getMate(result);
) {
ffStrbufSetS(&result->deProcessName, "mate-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
}
else if(
strcasecmp(name, "LXQt") == 0 ||
strcasecmp(name, "X-LXQT") == 0 ||
strcasecmp(name, "lxqt-session") == 0
) getLXQt(result);
) {
ffStrbufSetS(&result->deProcessName, "lxqt-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
FF_STRBUF_AUTO_DESTROY wmProcessNameBuffer = ffStrbufCreate();
ffParsePropFileConfig("lxqt/session.conf", "window_manager =", &wmProcessNameBuffer);
applyBetterWM(result, wmProcessNameBuffer.chars);
}
else if(
strcasecmp(name, "Budgie") == 0 ||
strcasecmp(name, "X-Budgie") == 0 ||
strcasecmp(name, "budgie-desktop") == 0 ||
strcasecmp(name, "Budgie:GNOME") == 0
) getBudgie(result);
) {
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
}
}
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
+2 -2
View File
@@ -100,7 +100,7 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
void ffdsConnectXcb(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(xcb, &instance.config.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2)
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,)
@@ -429,7 +429,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
void ffdsConnectXcbRandr(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(xcbRandr, &instance.config.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
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,)
+2 -2
View File
@@ -60,7 +60,7 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl
void ffdsConnectXlib(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(x11, &instance.config.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
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,)
@@ -338,7 +338,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
void ffdsConnectXrandr(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(xrandr, &instance.config.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3)
FF_LIBRARY_LOAD(xrandr, &instance.config.library.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3)
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,)
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,)
+16
View File
@@ -6,6 +6,11 @@ const char* FF_GPU_VENDOR_NAME_APPLE = "Apple";
const char* FF_GPU_VENDOR_NAME_AMD = "AMD";
const char* FF_GPU_VENDOR_NAME_INTEL = "Intel";
const char* FF_GPU_VENDOR_NAME_NVIDIA = "NVIDIA";
const char* FF_GPU_VENDOR_NAME_VMWARE = "VMware";
const char* FF_GPU_VENDOR_NAME_PARALLEL = "Parallel";
const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat";
const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle";
static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsigned length)
{
@@ -19,6 +24,7 @@ static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsign
const char* ffGetGPUVendorString(unsigned vendorId)
{
// https://devicehunt.com/all-pci-vendors
if(vendorId == 0x106b)
return FF_GPU_VENDOR_NAME_APPLE;
if(arrayContains((const unsigned[]) {0x1002, 0x1022}, vendorId, 2))
@@ -27,6 +33,16 @@ const char* ffGetGPUVendorString(unsigned vendorId)
return FF_GPU_VENDOR_NAME_INTEL;
else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3))
return FF_GPU_VENDOR_NAME_NVIDIA;
else if(arrayContains((const unsigned[]) {0x15ad}, vendorId, 1))
return FF_GPU_VENDOR_NAME_VMWARE;
else if(arrayContains((const unsigned[]) {0x1af4}, vendorId, 1))
return FF_GPU_VENDOR_NAME_REDHAT;
else if(arrayContains((const unsigned[]) {0x1ab8}, vendorId, 1))
return FF_GPU_VENDOR_NAME_PARALLEL;
else if(arrayContains((const unsigned[]) {0x1414}, vendorId, 1))
return FF_GPU_VENDOR_NAME_MICROSOFT;
else if(arrayContains((const unsigned[]) {0x108e}, vendorId, 1))
return FF_GPU_VENDOR_NAME_ORACLE;
return NULL;
}
+5
View File
@@ -13,6 +13,11 @@ extern const char* FF_GPU_VENDOR_NAME_APPLE;
extern const char* FF_GPU_VENDOR_NAME_AMD;
extern const char* FF_GPU_VENDOR_NAME_INTEL;
extern const char* FF_GPU_VENDOR_NAME_NVIDIA;
extern const char* FF_GPU_VENDOR_NAME_VMWARE;
extern const char* FF_GPU_VENDOR_NAME_PARALLEL;
extern const char* FF_GPU_VENDOR_NAME_MICROSOFT;
extern const char* FF_GPU_VENDOR_NAME_REDHAT;
extern const char* FF_GPU_VENDOR_NAME_ORACLE;
typedef struct FFGPUMemory
{
+37 -16
View File
@@ -1,7 +1,9 @@
#include "detection/gpu/gpu.h"
#include "detection/gpu/gpu_nvidia.h"
#include "detection/vulkan/vulkan.h"
#ifdef FF_HAVE_LIBPCI
#include "common/io/io.h"
#include "common/library.h"
#include "common/properties.h"
#include "common/parsing.h"
@@ -35,7 +37,7 @@ typedef struct PCIData
static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
ffStrbufAppendS(&gpu->vendor, ffGetGPUVendorString(device->vendor_id));
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(device->vendor_id));
if(gpu->vendor.length > 0)
return;
@@ -45,11 +47,11 @@ static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
ffStrbufRecalculateLength(&gpu->vendor);
if(ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if(ffStrbufContainS(&gpu->vendor, "Intel"))
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if(ffStrbufContainS(&gpu->vendor, "NVIDIA"))
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
}
static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
@@ -110,24 +112,28 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
#if PCI_LIB_VERSION >= 0x030800
pci->ffpci_fill_info(device, PCI_FILL_DRIVER);
ffStrbufAppendS(&gpu->driver, pci->ffpci_get_string_property(device, PCI_FILL_DRIVER));
if(gpu->driver.length > 0)
return;
#endif
const char* base = pci->ffpci_get_param(pci->access, "sysfs.path");
if(!ffStrSet(base))
return;
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateF("%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func);
ffStrbufEnsureFree(&gpu->driver, 1023);
ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator
if(resultLength > 0)
if (gpu->driver.length == 0)
{
gpu->driver.length = (uint32_t) resultLength;
gpu->driver.chars[resultLength] = '\0';
ffStrbufSubstrAfterLastC(&gpu->driver, '/');
ffStrbufEnsureFree(&gpu->driver, 1023);
ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator
if(resultLength > 0)
{
gpu->driver.length = (uint32_t) resultLength;
gpu->driver.chars[resultLength] = '\0';
ffStrbufSubstrAfterLastC(&gpu->driver, '/');
}
}
ffStrbufAppendC(&gpu->driver, ' ');
ffStrbufAppendS(&path, "/module/version");
ffAppendFileBuffer(path.chars, &gpu->driver);
ffStrbufTrimRight(&gpu->driver, ' ');
}
FF_MAYBE_UNUSED static void pciDetectTemp(FFGPUResult* gpu, struct pci_dev* device)
@@ -236,8 +242,23 @@ static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->useNvml))
{
char pciDeviceId[32];
snprintf(pciDeviceId, sizeof(pciDeviceId) - 1, "%04x:%02x:%02x.%d", device->domain, device->bus, device->dev, device->func);
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) { .pciBusId = pciDeviceId }, (FFGpuNvidiaResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->useNvml ? &gpu->dedicated : NULL,
.coreCount = options->useNvml ? (uint32_t*) &gpu->coreCount : NULL,
}, "libnvidia-ml.so");
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
#ifdef __linux__
if(options->temp)
if(options->temp && gpu->temperature != gpu->temperature)
pciDetectTemp(gpu, device);
#endif
}
@@ -270,7 +291,7 @@ static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
{
PCIData pci;
FF_LIBRARY_LOAD(libpci, &instance.config.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD(libpci, &instance.config.library.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus);
+97
View File
@@ -0,0 +1,97 @@
#include "gpu_nvidia.h"
#include "3rdparty/nvml/nvml.h"
#include "common/library.h"
struct FFNvmlData {
FF_LIBRARY_SYMBOL(nvmlDeviceGetCount_v2)
FF_LIBRARY_SYMBOL(nvmlDeviceGetHandleByIndex_v2)
FF_LIBRARY_SYMBOL(nvmlDeviceGetHandleByPciBusId_v2)
FF_LIBRARY_SYMBOL(nvmlDeviceGetPciInfo_v3)
FF_LIBRARY_SYMBOL(nvmlDeviceGetTemperature)
FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo_v2)
FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores)
bool inited;
} nvmlData;
const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result, const char* soName)
{
if (!nvmlData.inited)
{
nvmlData.inited = true;
FF_LIBRARY_LOAD(libnvml, NULL, "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)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetHandleByIndex_v2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetHandleByPciBusId_v2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetPciInfo_v3)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetTemperature)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo_v2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores)
if (ffnvmlInit_v2() != NVML_SUCCESS)
{
nvmlData.ffnvmlDeviceGetNumGpuCores = NULL;
return "nvmlInit_v2() failed";
}
atexit((void*) ffnvmlShutdown);
libnvml = NULL; // don't close nvml
}
if (nvmlData.ffnvmlDeviceGetNumGpuCores == NULL)
return "loading nvml library failed";
nvmlDevice_t device = NULL;
if (cond.pciBusId)
{
nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(cond.pciBusId, &device);
if (ret != NVML_SUCCESS)
return "nvmlDeviceGetHandleByPciBusId_v2() failed";
}
else
{
uint32_t count;
if (nvmlData.ffnvmlDeviceGetCount_v2(&count) != NVML_SUCCESS)
return "nvmlDeviceGetCount_v2() failed";
for (uint32_t i = 0; i < count; i++, device = NULL)
{
if (nvmlData.ffnvmlDeviceGetHandleByIndex_v2(i, &device) != NVML_SUCCESS)
continue;
nvmlPciInfo_t pciInfo;
if (nvmlData.ffnvmlDeviceGetPciInfo_v3(device, &pciInfo) != NVML_SUCCESS)
continue;
if (pciInfo.pciDeviceId != cond.pciDeviceId || pciInfo.pciSubSystemId != cond.pciSubSystemId)
continue;
break;
}
if (!device) return "Device not found";
}
if (result.temp)
{
uint32_t value;
if (nvmlData.ffnvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) == NVML_SUCCESS)
*result.temp = value;
}
if (result.memory)
{
nvmlMemory_v2_t memory = { .version = nvmlMemory_v2 };
if (nvmlData.ffnvmlDeviceGetMemoryInfo_v2(device, &memory) == NVML_SUCCESS)
{
result.memory->total = memory.used + memory.free;
result.memory->used = memory.used;
}
}
if (result.coreCount)
nvmlData.ffnvmlDeviceGetNumGpuCores(device, result.coreCount);
return NULL;
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "gpu.h"
// Use pciBusId if not NULL; use pciDeviceId and pciSubSystemId otherwise
typedef struct FFGpuNvidiaCondition
{
// "domain:bus:device.function"
const char* pciBusId;
// (deviceId << 16) | vendorId
uint32_t pciDeviceId;
uint32_t pciSubSystemId;
} FFGpuNvidiaCondition;
// detect x if not NULL
typedef struct FFGpuNvidiaResult
{
double* temp;
FFGPUMemory* memory;
uint32_t* coreCount;
} FFGpuNvidiaResult;
const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result, const char* soName);
+47 -10
View File
@@ -1,4 +1,5 @@
#include "gpu.h"
#include "detection/gpu/gpu_nvidia.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
@@ -12,9 +13,11 @@ static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
{
DISPLAY_DEVICEW displayDevice = { .cb = sizeof(displayDevice) };
wchar_t regKey[MAX_PATH] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\{";
const uint32_t regKeyPrefixLength = (uint32_t) wcslen(regKey);
const uint32_t deviceKeyPrefixLength = strlen("\\Registry\\Machine\\") + regKeyPrefixLength;
wchar_t regDirectxKey[MAX_PATH] = L"SOFTWARE\\Microsoft\\DirectX\\{";
const uint32_t regDirectxKeyPrefixLength = (uint32_t) wcslen(regDirectxKey);
wchar_t regControlVideoKey[MAX_PATH] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\{";
const uint32_t regControlVideoKeyPrefixLength = (uint32_t) wcslen(regControlVideoKey);
const uint32_t deviceKeyPrefixLength = strlen("\\Registry\\Machine\\") + regControlVideoKeyPrefixLength;
for (DWORD i = 0; EnumDisplayDevicesW(NULL, i, &displayDevice, 0); ++i)
{
@@ -43,27 +46,61 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
if (deviceKeyLength == 100 && displayDevice.DeviceKey[deviceKeyPrefixLength - 1] == '{')
{
wmemcpy(regKey + regKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, 100 - regKeyPrefixLength + 1);
wmemcpy(regControlVideoKey + regControlVideoKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, strlen("00000000-0000-0000-0000-000000000000}\\0000"));
FF_HKEY_AUTO_DESTROY hKey = NULL;
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regKey, &hKey, NULL)) continue;
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regControlVideoKey, &hKey, NULL)) continue;
ffRegReadStrbuf(hKey, L"DriverVersion", &gpu->driver, NULL);
ffRegReadStrbuf(hKey, L"ProviderName", &gpu->vendor, NULL);
if(ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if(ffStrbufContainS(&gpu->vendor, "Intel"))
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if(ffStrbufContainS(&gpu->vendor, "NVIDIA"))
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
if (!ffRegReadUint64(hKey, L"HardwareInformation.qwMemorySize", &gpu->dedicated.total, NULL))
wmemcpy(regDirectxKey + regDirectxKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, strlen("00000000-0000-0000-0000-000000000000}"));
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
{
uint64_t dedicatedVideoMemory = 0;
if(ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, NULL))
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
uint64_t dedicatedSystemMemory, sharedSystemMemory;
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
ffRegReadUint64(hDirectxKey, L"SharedSystemMemory", &sharedSystemMemory, NULL))
{
gpu->dedicated.total = dedicatedVideoMemory + dedicatedSystemMemory;
gpu->shared.total = sharedSystemMemory;
}
}
else if (!ffRegReadUint64(hKey, L"HardwareInformation.qwMemorySize", &gpu->dedicated.total, NULL))
{
uint32_t vmem = 0;
if (ffRegReadUint(hKey, L"HardwareInformation.MemorySize", &vmem, NULL))
gpu->dedicated.total = vmem;
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
}
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->useNvml))
{
uint32_t vendorId, deviceId, subSystemId;
// See: https://download.nvidia.com/XFree86/Linux-x86_64/545.23.06/README/supportedchips.html
// displayDevice.DeviceID = MatchingDeviceId "PCI\\VEN_10DE&DEV_2782&SUBSYS_513417AA&REV_A1"
if (swscanf(displayDevice.DeviceID, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x", &vendorId, &deviceId, &subSystemId) == 3)
{
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) {
.pciDeviceId = (deviceId << 16) | vendorId,
.pciSubSystemId = subSystemId,
}, (FFGpuNvidiaResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->useNvml ? &gpu->dedicated : NULL,
.coreCount = options->useNvml ? (uint32_t*) &gpu->coreCount : NULL,
}, "nvml.dll");
}
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
}
+15 -1
View File
@@ -4,6 +4,7 @@
extern "C" {
#include "common/library.h"
#include "detection/gpu/gpu.h"
#include "detection/gpu/gpu_nvidia.h"
}
#include <wsl/winadapter.h>
@@ -92,7 +93,20 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::HardwareID, sizeof(hardwareId), &hardwareId)))
{
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
ffStrbufAppendS(&gpu->vendor, vendorStr);
ffStrbufSetStatic(&gpu->vendor, vendorStr);
if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA && options->useNvml)
{
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) {
.pciBusId = nullptr,
.pciDeviceId = (hardwareId.deviceID << 16) | hardwareId.vendorID,
.pciSubSystemId = hardwareId.subSysID
}, (FFGpuNvidiaResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->useNvml ? &gpu->dedicated : NULL,
.coreCount = options->useNvml ? (uint32_t*) &gpu->coreCount : NULL,
}, "/usr/lib/wsl/lib/libnvidia-ml.so");
}
}
}
+1 -12
View File
@@ -36,8 +36,6 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
static void detectGTKFromSettings(FFGTKResult* result)
{
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static const char* themeName = NULL;
static const char* iconsName = NULL;
static const char* fontName = NULL;
@@ -47,11 +45,8 @@ static void detectGTKFromSettings(FFGTKResult* result)
static bool init = false;
ffThreadMutexLock(&mutex);
if(init)
{
ffThreadMutexUnlock(&mutex);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
return;
}
@@ -103,7 +98,6 @@ static void detectGTKFromSettings(FFGTKResult* result)
wallpaper = ffSettingsGet("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
}
ffThreadMutexUnlock(&mutex);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
}
@@ -178,14 +172,10 @@ static void detectGTK(const char* version, FFGTKResult* result)
}
#define FF_DETECT_GTK_IMPL(version) \
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
static FFGTKResult result; \
static bool init = false; \
ffThreadMutexLock(&mutex); \
if(init){ \
ffThreadMutexUnlock(&mutex);\
if(init) \
return &result; \
} \
init = true; \
ffStrbufInit(&result.theme); \
ffStrbufInit(&result.icons); \
@@ -194,7 +184,6 @@ static void detectGTK(const char* version, FFGTKResult* result)
ffStrbufInit(&result.cursorSize); \
ffStrbufInit(&result.wallpaper); \
detectGTK(#version, &result); \
ffThreadMutexUnlock(&mutex); \
return &result;
const FFGTKResult* ffDetectGTK2(void)
-6
View File
@@ -138,14 +138,9 @@ const FFQtResult* ffDetectQt(void)
{
static FFQtResult result;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
ffThreadMutexLock(&mutex);
if(init)
{
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
ffStrbufInit(&result.widgetStyle);
@@ -161,6 +156,5 @@ const FFQtResult* ffDetectQt(void)
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT) == 0)
detectLXQt(&result);
ffThreadMutexUnlock(&mutex);
return &result;
}
+4
View File
@@ -28,6 +28,10 @@ static void getHostProductName(FFstrbuf* name)
if(ffIsSmbiosValueSet(name))
return;
ffReadFileBuffer("/sys/firmware/devicetree/base/banner-name", name);
if(ffIsSmbiosValueSet(name))
return;
//does a clear before the read
ffReadFileBuffer("/tmp/sysinfo/model", name);
if(ffIsSmbiosValueSet(name))
-6
View File
@@ -6,18 +6,12 @@
#include "common/thread.h"
#define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
static ResultType result; \
static bool init = false; \
ffThreadMutexLock(&mutex); \
if(init) \
{ \
ffThreadMutexUnlock(&mutex); \
return &result; \
} \
init = true; \
__VA_ARGS__; \
ffThreadMutexUnlock(&mutex); \
return &result; \
#endif
+7 -7
View File
@@ -55,13 +55,13 @@ static const char* getSshdVersion(FFstrbuf* version)
static const char* getSddmVersion(FFstrbuf* version)
{
FF_LIBRARY_LOAD(zlib, &instance.config.libZ, "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);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gztell);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzrewind);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzclose);
FF_LIBRARY_LOAD(zlib, &instance.config.library.libZ, "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)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gztell)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzrewind)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzclose)
gzFile file = ffgzopen("/usr/share/man/man1/sddm.1.gz", "rb");
if (file == Z_NULL)
+2 -2
View File
@@ -161,8 +161,8 @@ static const char* getMedia(FFMediaResult* result)
// FIXME: This is shared for both player and media module.
// However it uses an option in one specific module
if(instance.config.playerName.length > 0)
getCustomBus(&data, &instance.config.playerName, result);
if(instance.config.general.playerName.length > 0)
getCustomBus(&data, &instance.config.general.playerName, result);
else
getBestBus(&data, result);
+1 -1
View File
@@ -72,7 +72,7 @@ const char* ffDetectOpenCL(FFOpenCLResult* result)
OpenCLData data;
FF_LIBRARY_LOAD(opencl, &instance.config.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed",
FF_LIBRARY_LOAD(opencl, &instance.config.library.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed",
#ifdef _WIN32
"OpenCL"FF_LIBRARY_EXTENSION, -1,
#endif
+3 -3
View File
@@ -122,7 +122,7 @@ static const char* eglPrint(FFOpenGLResult* result)
{
EGLData eglData;
FF_LIBRARY_LOAD(egl, &instance.config.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(egl, &instance.config.library.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize);
@@ -239,7 +239,7 @@ static const char* glxPrint(FFOpenGLResult* result)
{
GLXData data;
FF_LIBRARY_LOAD(glx, &instance.config.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(glx, &instance.config.library.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual);
@@ -303,7 +303,7 @@ static const char* osMesaPrint(FFOpenGLResult* result)
{
OSMesaData data;
FF_LIBRARY_LOAD(osmesa, &instance.config.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8);
FF_LIBRARY_LOAD(osmesa, &instance.config.library.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent);
+22 -22
View File
@@ -35,10 +35,10 @@ static bool detectOSCodeName(FFOSResult* os)
switch (num)
{
case 14: ffStrbufAppendS(&os->codename, "Sonoma"); return true;
case 13: ffStrbufAppendS(&os->codename, "Ventura"); return true;
case 12: ffStrbufAppendS(&os->codename, "Monterey"); return true;
case 11: ffStrbufAppendS(&os->codename, "Big Sur"); return true;
case 14: ffStrbufSetStatic(&os->codename, "Sonoma"); return true;
case 13: ffStrbufSetStatic(&os->codename, "Ventura"); return true;
case 12: ffStrbufSetStatic(&os->codename, "Monterey"); return true;
case 11: ffStrbufSetStatic(&os->codename, "Big Sur"); return true;
case 10: {
version = str_end + 1;
num = strtoul(version, &str_end, 10);
@@ -46,23 +46,23 @@ static bool detectOSCodeName(FFOSResult* os)
switch (num)
{
case 16: ffStrbufAppendS(&os->codename, "Big Sur"); return true;
case 15: ffStrbufAppendS(&os->codename, "Catalina"); return true;
case 14: ffStrbufAppendS(&os->codename, "Mojave"); return true;
case 13: ffStrbufAppendS(&os->codename, "High Sierra"); return true;
case 12: ffStrbufAppendS(&os->codename, "Sierra"); return true;
case 11: ffStrbufAppendS(&os->codename, "El Capitan"); return true;
case 10: ffStrbufAppendS(&os->codename, "Yosemite"); return true;
case 9: ffStrbufAppendS(&os->codename, "Mavericks"); return true;
case 8: ffStrbufAppendS(&os->codename, "Mountain Lion"); return true;
case 7: ffStrbufAppendS(&os->codename, "Lion"); return true;
case 6: ffStrbufAppendS(&os->codename, "Snow Leopard"); return true;
case 5: ffStrbufAppendS(&os->codename, "Leopard"); return true;
case 4: ffStrbufAppendS(&os->codename, "Tiger"); return true;
case 3: ffStrbufAppendS(&os->codename, "Panther"); return true;
case 2: ffStrbufAppendS(&os->codename, "Jaguar"); return true;
case 1: ffStrbufAppendS(&os->codename, "Puma"); return true;
case 0: ffStrbufAppendS(&os->codename, "Cheetah"); return true;
case 16: ffStrbufSetStatic(&os->codename, "Big Sur"); return true;
case 15: ffStrbufSetStatic(&os->codename, "Catalina"); return true;
case 14: ffStrbufSetStatic(&os->codename, "Mojave"); return true;
case 13: ffStrbufSetStatic(&os->codename, "High Sierra"); return true;
case 12: ffStrbufSetStatic(&os->codename, "Sierra"); return true;
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); return true;
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); return true;
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); return true;
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); return true;
case 7: ffStrbufSetStatic(&os->codename, "Lion"); return true;
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); return true;
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); return true;
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); return true;
case 3: ffStrbufSetStatic(&os->codename, "Panther"); return true;
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); return true;
case 1: ffStrbufSetStatic(&os->codename, "Puma"); return true;
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); return true;
}
}
}
@@ -113,7 +113,7 @@ void ffDetectOSImpl(FFOSResult* os)
parseSystemVersion(os);
if(ffStrbufStartsWithIgnCaseS(&os->name, "MacOS"))
ffStrbufAppendS(&os->id, "macos");
ffStrbufSetStatic(&os->id, "macos");
if(os->version.length == 0)
ffSysctlGetString("kern.osproductversion", &os->version);
+3 -3
View File
@@ -133,13 +133,13 @@ static void getDebianVersion(FFOSResult* result)
static void detectOS(FFOSResult* os)
{
if(instance.config.osFile.length > 0)
if(instance.config.general.osFile.length > 0)
{
parseFile(instance.config.osFile.chars, os);
parseFile(instance.config.general.osFile.chars, os);
return;
}
if(instance.config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os))
if(instance.config.general.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os))
{
if(os->id.length == 0)
ffStrbufAppendS(&os->id, "bedrock");
+3 -3
View File
@@ -3,11 +3,11 @@
#include <stddef.h>
void ffDetectPackagesImpl(FFPackagesResult* result);
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options);
const char* ffDetectPackages(FFPackagesResult* result)
const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options)
{
ffDetectPackagesImpl(result);
ffDetectPackagesImpl(result, options);
for(uint32_t i = 0; i < offsetof(FFPackagesResult, all) / sizeof(uint32_t); ++i)
result->all += ((uint32_t *)result)[i];
+1 -1
View File
@@ -36,6 +36,6 @@ typedef struct FFPackagesResult
FFstrbuf pacmanBranch;
} FFPackagesResult;
const char* ffDetectPackages(FFPackagesResult* result);
const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options);
#endif
+1 -1
View File
@@ -68,7 +68,7 @@ static uint32_t getMacPortsPackages()
return countMacPortsPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/local");
}
void ffDetectPackagesImpl(FFPackagesResult* result)
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
{
getBrewPackages(result);
result->port = getMacPortsPackages();
+2 -2
View File
@@ -226,7 +226,7 @@ static uint32_t getFlatpak(FFstrbuf* baseDir, const char* dirname)
static uint32_t getRpmFromLibrpm(void)
{
FF_LIBRARY_LOAD(rpm, &instance.config.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12)
FF_LIBRARY_LOAD(rpm, &instance.config.library.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0)
@@ -327,7 +327,7 @@ static void getPackageCountsBedrock(FFstrbuf* baseDir, FFPackagesResult* package
ffStrbufSubstrBefore(baseDir, baseDirLength);
}
void ffDetectPackagesImpl(FFPackagesResult* result)
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(512);
ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT);
+2 -2
View File
@@ -105,11 +105,11 @@ static void detectWinget(FFPackagesResult* result)
result->winget = count;
}
void ffDetectPackagesImpl(FFPackagesResult* result)
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
{
detectScoop(result);
detectChoco(result);
detectPacman(result);
if (instance.config.allowSlowOperations)
if (options->winget)
detectWinget(result);
}
+14 -5
View File
@@ -49,14 +49,23 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
}, 0, NULL, &dataSize) == kAudioHardwareNoError && dataSize > 0)
continue;
uint32_t connected;
dataSize = sizeof(connected);
uint32_t dataSource;
dataSize = sizeof(dataSource);
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyJackIsConnected,
kAudioDevicePropertyDataSource,
kAudioObjectPropertyScopeOutput,
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize, &connected) == kAudioHardwareNoError)
if (!connected) continue;
}, 0, NULL, &dataSize, &dataSource) == kAudioHardwareNoError && dataSource == 'hdpn')
{
uint32_t connected;
dataSize = sizeof(connected);
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyJackIsConnected,
kAudioObjectPropertyScopeOutput,
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize, &connected) == kAudioHardwareNoError)
if (!connected) continue;
}
FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices);
device->main = deviceId == mainDeviceId;
+1 -1
View File
@@ -38,7 +38,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.libPulse, "Failed to load libpulse" FF_LIBRARY_EXTENSION, "libpulse" FF_LIBRARY_EXTENSION, 0)
FF_LIBRARY_LOAD(pulse, &instance.config.library.libPulse, "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)
-9
View File
@@ -44,15 +44,10 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
const FFTempsResult* ffDetectTemps(void)
{
static FFTempsResult result;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
ffThreadMutexLock(&mutex);
if(init)
{
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
ffListInitA(&result.values, sizeof(FFTempValue), 16);
@@ -64,10 +59,7 @@ const FFTempsResult* ffDetectTemps(void)
DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
{
ffThreadMutexUnlock(&mutex);
return &result;
}
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
@@ -92,6 +84,5 @@ const FFTempsResult* ffDetectTemps(void)
closedir(dirp);
ffThreadMutexUnlock(&mutex);
return &result;
}
+23 -26
View File
@@ -242,35 +242,32 @@ FF_MAYBE_UNUSED static bool detectKitty(const FFstrbuf* exe, FFTerminalFontResul
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate();
FFpropquery fontQuery[] = {
{"font_family ", &fontName},
{"font_size ", &fontSize},
};
if(instance.config.allowSlowOperations)
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
if(!ffProcessAppendStdOut(&buf, (char* const[]){
exe->chars,
"+kitten",
"query-terminal",
NULL,
}))
{
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
if(!ffProcessAppendStdOut(&buf, (char* const[]){
exe->chars,
"+kitten",
"query-terminal",
NULL,
}))
{
ffParsePropLines(buf.chars, "font_family: ", &fontName);
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
return true;
}
ffParsePropLines(buf.chars, "font_family: ", &fontName);
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
}
else
{
FFpropquery fontQuery[] = {
{"font_family ", &fontName},
{"font_size ", &fontSize},
};
ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery);
if(fontName.length == 0)
ffStrbufSetS(&fontName, "monospace");
if(fontSize.length == 0)
ffStrbufSetS(&fontSize, "11.0");
}
if(!ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery))
return false;
if(fontName.length == 0)
ffStrbufSetS(&fontName, "monospace");
if(fontSize.length == 0)
ffStrbufSetS(&fontSize, "11.0");
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
@@ -15,7 +15,7 @@ const char* detectTermux(FFTerminalFontResult* terminalFont)
{
#ifdef FF_HAVE_FREETYPE
FF_LIBRARY_LOAD(freetype, &instance.config.libfreetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD(freetype, &instance.config.library.libfreetype, "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);
@@ -2,6 +2,7 @@
#include "common/settings.h"
#include "common/properties.h"
#include "common/parsing.h"
#include "common/io/io.h"
#include "detection/terminalshell/terminalshell.h"
#include "detection/displayserver/displayserver.h"
#include "util/mallocHelper.h"
@@ -124,15 +125,36 @@ static void detectXFCETerminal(FFTerminalFontResult* terminalFont)
FF_STRBUF_AUTO_DESTROY useSysFont = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
ffParsePropFileConfigValues("xfce4/terminal/terminalrc", 2, (FFpropquery[]) {
{"FontUseSystem = ", &useSysFont},
{"FontName = ", &fontName}
const char* path = "xfce4/xfconf/xfce-perchannel-xml/xfce4-terminal.xml";
bool configFound = ffParsePropFileConfigValues(path, 2, (FFpropquery[]) {
{"<property name=\"font-use-system\" type=\"bool\" value=\"", &useSysFont},
{"<property name=\"font-name\" type=\"string\" value=\"", &fontName}
});
if (configFound)
{
ffStrbufSubstrBeforeLastC(&useSysFont, '"');
ffStrbufSubstrBeforeLastC(&fontName, '"');
}
else
{
path = "xfce4/terminal/terminalrc";
configFound = ffParsePropFileConfigValues(path, 2, (FFpropquery[]) {
{"FontUseSystem = ", &useSysFont},
{"FontName = ", &fontName}
});
}
if (!configFound)
{
ffStrbufSetStatic(&terminalFont->error, "Couldn't find xfce4/xfconf/xfce-perchannel-xml/xfce4-terminal.xml or xfce4/terminal/terminalrc");
return;
}
if(useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0)
{
if(fontName.length == 0)
ffStrbufAppendS(&terminalFont->error, "Couldn't find FontName in .config/xfce4/terminal/terminalrc");
ffStrbufAppendF(&terminalFont->error, "Couldn't find FontName in %s", path);
else
ffFontInitPango(&terminalFont->font, fontName.chars);
}
@@ -250,6 +272,38 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
}
static void detectSt(FFTerminalFontResult* terminalFont, uint32_t pid)
{
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreateF("/proc/%u/cmdline", pid);
FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate();
if (!ffAppendFileBuffer(size.chars, &font))
{
ffStrbufAppendF(&terminalFont->error, "Failed to open %s", size.chars);
return;
}
const char* p = memmem(font.chars, font.length, "\0-f", sizeof("\0-f")); // find parameter of `-f`
if (!p)
{
ffStrbufAppendF(&terminalFont->error, "st was not executed with `-f` parameter");
return;
}
ffStrbufSubstrAfter(&font, (uint32_t) (p + (sizeof("\0-f") - 1) - font.chars));
ffStrbufRecalculateLength(&font);
// `monospace:size=15` || `monospace` || `:size=15`
uint32_t index = ffStrbufFirstIndexS(&font, ":size=");
if (index != font.length)
{
ffStrbufSetS(&size, font.chars + index + strlen(":size="));
ffStrbufSubstrBefore(&font, index);
}
else
ffStrbufClear(&size);
ffFontInitValues(&terminalFont->font, font.chars, size.chars);
}
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
{
if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "konsole"))
@@ -276,4 +330,6 @@ void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FF
detectQTerminal(terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xterm"))
detectXterm(terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "st"))
detectSt(terminalFont, terminalShell->terminalPid);
}
@@ -284,6 +284,36 @@ FF_MAYBE_UNUSED static bool getTerminalVersionXterm(FFstrbuf* exe, FFstrbuf* ver
return version->length > 0;
}
FF_MAYBE_UNUSED static bool getTerminalVersionUrxvt(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version)
{
if(ffProcessAppendStdErr(version, (char* const[]){
"urxvt", // Don't use exe because of urxvtd
"-invalid",
NULL
})) return false;
//urxvt: "invalid": unknown or malformed option.
//rxvt-unicode (urxvt) v9.31 - released: 2023-01-02
ffStrbufSubstrAfterFirstS(version, "(urxvt) v");
ffStrbufSubstrBeforeFirstC(version, ' ');
return version->length > 0;
}
FF_MAYBE_UNUSED static bool getTerminalVersionSt(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version)
{
if(ffProcessAppendStdErr(version, (char* const[]){
exe->chars,
"-v",
NULL
})) return false;
//st 0.9
ffStrbufSubstrAfterFirstC(version, ' ');
return version->length > 0;
}
static bool getTerminalVersionContour(FFstrbuf* exe, FFstrbuf* version)
{
const char* env = getenv("TERMINAL_VERSION_STRING");
@@ -371,6 +401,16 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
if(ffStrbufIgnCaseEqualS(processName, "xterm"))
return getTerminalVersionXterm(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "st"))
return getTerminalVersionSt(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "urxvt") ||
ffStrbufIgnCaseEqualS(processName, "urxvtd") ||
ffStrbufIgnCaseEqualS(processName, "rxvt") ||
ffStrbufIgnCaseEqualS(processName, "rxvt-unicode")
)
return getTerminalVersionUrxvt(exe, version);
#endif
#ifdef _WIN32
@@ -415,6 +455,22 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
}
}
termProgramVersion = getenv("LC_TERMINAL_VERSION");
if(termProgramVersion)
{
const char* termProgram = getenv("LC_TERMINAL");
if(termProgram)
{
if(ffStrbufStartsWithIgnCaseS(processName, termProgram) || // processName ends with `.exe` on Windows
(ffStrEquals(termProgram, "vscode") && ffStrbufStartsWithIgnCaseS(processName, "code")) ||
(ffStrStartsWith(termProgram, "iTerm") && ffStrbufStartsWithIgnCaseS(processName, "iTermServer-"))
) {
ffStrbufSetS(version, termProgramVersion);
return true;
}
}
}
#ifdef _WIN32
return getFileVersion(exe->chars, version);
@@ -139,6 +139,7 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
strcasecmp(name, "sshd") == 0 ||
strcasecmp(name, "gdb") == 0 ||
strcasecmp(name, "lldb") == 0 ||
strcasecmp(name, "login") == 0 ||
strcasecmp(name, "guake-wrapped") == 0 ||
strcasestr(name, "debug") != NULL ||
strcasestr(name, "command-not-found") != NULL ||
@@ -236,8 +237,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
//Termux
if(!ffStrSet(term) && (
getenv("TERMUX_VERSION") != NULL ||
getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL ||
getenv("TMUX_TMPDIR") != NULL
getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL
)) term = "com.termux";
#endif
@@ -252,6 +252,9 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
if(!ffStrSet(term))
term = getenv("TERM_PROGRAM");
if(!ffStrSet(term))
term = getenv("LC_TERMINAL");
//Normal Terminal
if(!ffStrSet(term))
term = getenv("TERM");
@@ -311,15 +314,10 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* vers
const FFTerminalShellResult* ffDetectTerminalShell()
{
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static FFTerminalShellResult result;
static bool init = false;
ffThreadMutexLock(&mutex);
if(init)
{
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
#ifdef __APPLE__
@@ -373,9 +371,10 @@ const FFTerminalShellResult* ffDetectTerminalShell()
result.terminalExeName + 1);
}
if(ffStrbufEqualS(&result.terminalProcessName, "wezterm-gui"))
ffStrbufInitStatic(&result.terminalPrettyName, "WezTerm");
if(ffStrbufStartsWithS(&result.terminalProcessName, "tmux:"))
ffStrbufInitStatic(&result.terminalPrettyName, "tmux");
#if defined(__ANDROID__)
@@ -388,6 +387,11 @@ const FFTerminalShellResult* ffDetectTerminalShell()
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Terminal");
else if(ffStrbufStartsWithS(&result.terminalProcessName, "kgx"))
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Console");
else if(ffStrbufEqualS(&result.terminalProcessName, "urxvt") ||
ffStrbufEqualS(&result.terminalProcessName, "urxvtd") ||
ffStrbufEqualS(&result.terminalProcessName, "rxvt")
)
ffStrbufInitStatic(&result.terminalPrettyName, "rxvt-unicode");
#elif defined(__APPLE__)
@@ -408,6 +412,5 @@ const FFTerminalShellResult* ffDetectTerminalShell()
ffStrbufInit(&result.terminalVersion);
fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion);
ffThreadMutexUnlock(&mutex);
return &result;
}
@@ -130,7 +130,7 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
{
ffStrbufClear(&result->shellPrettyName);
HANDLE snapshot;
FF_AUTO_CLOSE_FD HANDLE snapshot = NULL;
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
if(snapshot)
@@ -147,7 +147,6 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
break;
}
}
CloseHandle(snapshot);
}
if(result->shellPrettyName.length == 0)
ffStrbufAppendS(&result->shellPrettyName, "Command Prompt");
@@ -355,15 +354,10 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* vers
const FFTerminalShellResult* ffDetectTerminalShell(void)
{
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static FFTerminalShellResult result;
static bool init = false;
ffThreadMutexLock(&mutex);
if(init)
{
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
ffStrbufInit(&result.shellProcessName);
@@ -381,7 +375,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(void)
uint32_t ppid;
if(!getProcessInfo(0, &ppid, NULL, NULL, NULL))
goto exit;
return &result;
ppid = getShellInfo(&result, ppid);
if(ppid)
@@ -393,7 +387,5 @@ const FFTerminalShellResult* ffDetectTerminalShell(void)
ffStrbufInit(&result.terminalVersion);
fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion);
exit:
ffThreadMutexUnlock(&mutex);
return &result;
}
+9 -35
View File
@@ -40,7 +40,7 @@ static void applyDriverName(VkPhysicalDeviceDriverProperties* properties, FFstrb
static const char* detectVulkan(FFVulkanResult* result)
{
FF_LIBRARY_LOAD(vulkan, &instance.config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed",
FF_LIBRARY_LOAD(vulkan, &instance.config.library.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed",
#ifdef __APPLE__
"libMoltenVK"FF_LIBRARY_EXTENSION, -1
#elif defined(_WIN32)
@@ -117,11 +117,7 @@ static const char* detectVulkan(FFVulkanResult* result)
if(!ffvkGetPhysicalDeviceProperties2)
ffvkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceProperties");
PFN_vkGetPhysicalDeviceMemoryProperties ffvkGetPhysicalDeviceMemoryProperties = NULL;
PFN_vkGetPhysicalDeviceMemoryProperties2 ffvkGetPhysicalDeviceMemoryProperties2 =
instance.config.allowSlowOperations ? (PFN_vkGetPhysicalDeviceMemoryProperties2) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties2") : NULL; // 1.1
if(!ffvkGetPhysicalDeviceMemoryProperties2)
ffvkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties");
PFN_vkGetPhysicalDeviceMemoryProperties ffvkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties");
FFVersion maxDeviceApiVersion = FF_VERSION_INIT;
FFVersion maxDeviceConformanceVersion = FF_VERSION_INIT;
@@ -187,38 +183,22 @@ static const char* detectVulkan(FFVulkanResult* result)
gpu->vulkanDeviceId = physicalDeviceProperties.properties.deviceID;
ffStrbufInit(&gpu->name);
ffStrbufAppendS(&gpu->name, physicalDeviceProperties.properties.deviceName);
ffStrbufInitS(&gpu->name, physicalDeviceProperties.properties.deviceName);
if(physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
gpu->type = FF_GPU_TYPE_DISCRETE;
else
gpu->type = FF_GPU_TYPE_INTEGRATED;
gpu->type = physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
ffStrbufInitS(&gpu->vendor, ffGetGPUVendorString(physicalDeviceProperties.properties.vendorID));
ffStrbufInitS(&gpu->driver, driverProperties.driverInfo);
VkPhysicalDeviceMemoryBudgetPropertiesEXT budgetProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT,
};
VkPhysicalDeviceMemoryProperties2 memoryProperties2 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
.pNext = &budgetProperties,
};
if(ffvkGetPhysicalDeviceMemoryProperties2)
ffvkGetPhysicalDeviceMemoryProperties2(physicalDevices[i], &memoryProperties2);
else
ffvkGetPhysicalDeviceMemoryProperties(physicalDevices[i], &memoryProperties2.memoryProperties);
VkPhysicalDeviceMemoryProperties memoryProperties = {};
ffvkGetPhysicalDeviceMemoryProperties(physicalDevices[i], &memoryProperties);
gpu->dedicated.total = gpu->shared.total = 0;
gpu->dedicated.used = gpu->shared.used = ffvkGetPhysicalDeviceMemoryProperties2 ? 0 : FF_GPU_VMEM_SIZE_UNSET;
for(uint32_t index = 0; index < memoryProperties2.memoryProperties.memoryHeapCount; ++index)
gpu->dedicated.used = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
for(uint32_t index = 0; index < memoryProperties.memoryHeapCount; ++index)
{
const VkMemoryHeap* heap = &memoryProperties2.memoryProperties.memoryHeaps[index];
const VkMemoryHeap* heap = &memoryProperties.memoryHeaps[index];
FFGPUMemory* vmem = gpu->type == FF_GPU_TYPE_DISCRETE && (heap->flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? &gpu->dedicated : &gpu->shared;
vmem->total += heap->size;
if(ffvkGetPhysicalDeviceMemoryProperties2)
vmem->used += heap->size - budgetProperties.heapBudget[index];
}
//No way to detect those using vulkan
@@ -248,15 +228,10 @@ static const char* detectVulkan(FFVulkanResult* result)
FFVulkanResult* ffDetectVulkan(void)
{
static FFVulkanResult result;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
ffThreadMutexLock(&mutex);
if(init)
{
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
ffStrbufInit(&result.driver);
@@ -270,6 +245,5 @@ FFVulkanResult* ffDetectVulkan(void)
result.error = "fastfetch was compiled without vulkan support";
#endif
ffThreadMutexUnlock(&mutex);
return &result;
}
+1 -1
View File
@@ -24,7 +24,7 @@ const char* ffDetectWallpaper(FFstrbuf* result)
#endif
if (!ffOsascript("tell application \"Finder\" to get POSIX path of (get desktop picture as alias)", result))
return "ffOsascript() failed";
return "ffOsascript(get desktop picture) failed";
return NULL;
}
+89 -40
View File
@@ -3,6 +3,27 @@
#import <CoreWLAN/CoreWLAN.h>
struct Apple80211; // https://code.google.com/archive/p/iphone-wireless/wikis/Apple80211.wiki
// 0 is sucessful; < 0 is failure
int Apple80211Open(struct Apple80211 **handle) __attribute__((weak_import));
int Apple80211BindToInterface(struct Apple80211 *handle, CFStringRef interface) __attribute__((weak_import));
int Apple80211GetInfoCopy(struct Apple80211 *handle, CFDictionaryRef *info) __attribute__((weak_import));
int Apple80211Close(struct Apple80211 *handle) __attribute__((weak_import));
static NSDictionary* getWifiInfoByApple80211(NSString* ifName)
{
if (!Apple80211Open || !Apple80211BindToInterface || !Apple80211GetInfoCopy || !Apple80211Close) return NULL;
struct Apple80211* handle = NULL;
if (Apple80211Open(&handle) < 0) return NULL;
if (Apple80211BindToInterface(handle, (CFStringRef)ifName) < 0) return NULL;
CFDictionaryRef result;
if (Apple80211GetInfoCopy(handle, &result) < 0) return NULL;
Apple80211Close(handle);
return CFBridgingRelease(result);
}
const char* ffDetectWifi(FFlist* result)
{
NSArray<CWInterface*>* interfaces = CWWiFiClient.sharedWiFiClient.interfaces;
@@ -24,56 +45,53 @@ const char* ffDetectWifi(FFlist* result)
item->conn.txRate = 0.0/0.0;
ffStrbufAppendS(&item->inf.description, inf.interfaceName.UTF8String);
ffStrbufAppendS(&item->inf.status, inf.powerOn ? "Power On" : "Power Off");
ffStrbufSetStatic(&item->inf.status, inf.powerOn ? "Power On" : "Power Off");
if(!inf.powerOn)
continue;
ffStrbufAppendS(&item->conn.status, inf.serviceActive ? "Active" : "Inactive");
ffStrbufSetStatic(&item->conn.status, inf.interfaceMode != kCWInterfaceModeNone ? "Active" : "Inactive");
if(!inf.serviceActive)
continue;
if (inf.ssid)
NSDictionary* apple = NULL;
if (inf.ssid) // https://developer.apple.com/forums/thread/732431
ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String);
else if (!ffProcessAppendStdOut(&item->conn.ssid, (char* []) {
"/usr/sbin/networksetup",
"-getairportnetwork",
item->inf.description.chars,
NULL
}) && item->conn.ssid.length > 0)
{
uint32_t index = ffStrbufFirstIndexC(&item->conn.ssid, ':');
if (index < item->conn.ssid.length)
ffStrbufSubstrAfter(&item->conn.ssid, index + 1);
}
else if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName)))
ffStrbufAppendS(&item->conn.ssid, [[apple valueForKey:@"SSID_STR"] UTF8String]);
else
ffStrbufSetStatic(&item->conn.ssid, "<unknown ssid>"); // https://developer.apple.com/forums/thread/732431
ffStrbufAppendS(&item->conn.macAddress, inf.hardwareAddress.UTF8String);
if (inf.bssid)
ffStrbufAppendS(&item->conn.macAddress, inf.bssid.UTF8String);
else if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName)))
ffStrbufAppendS(&item->conn.macAddress, [[apple valueForKey:@"BSSID"] UTF8String]);
switch(inf.activePHYMode)
{
case kCWPHYModeNone:
ffStrbufAppendS(&item->conn.protocol, "none");
ffStrbufSetStatic(&item->conn.protocol, "none");
break;
case kCWPHYMode11a:
ffStrbufAppendS(&item->conn.protocol, "802.11a");
ffStrbufSetStatic(&item->conn.protocol, "802.11a");
break;
case kCWPHYMode11b:
ffStrbufAppendS(&item->conn.protocol, "802.11b");
ffStrbufSetStatic(&item->conn.protocol, "802.11b");
break;
case kCWPHYMode11g:
ffStrbufAppendS(&item->conn.protocol, "802.11g");
ffStrbufSetStatic(&item->conn.protocol, "802.11g");
break;
case kCWPHYMode11n:
ffStrbufAppendS(&item->conn.protocol, "802.11n (Wi-Fi 4)");
ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)");
break;
case kCWPHYMode11ac:
ffStrbufAppendS(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
break;
case 6 /*kCWPHYMode11ax*/:
ffStrbufAppendS(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
ffStrbufSetStatic(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
break;
case 7 /*kCWPHYMode11be?*/:
ffStrbufAppendS(&item->conn.protocol, "802.11be (Wi-Fi 7)");
ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)");
break;
default:
ffStrbufAppendF(&item->conn.protocol, "Unknown (%ld)", inf.activePHYMode);
@@ -85,55 +103,86 @@ const char* ffDetectWifi(FFlist* result)
switch(inf.security)
{
case kCWSecurityNone:
ffStrbufAppendS(&item->conn.security, "Insecure");
ffStrbufSetStatic(&item->conn.security, "Insecure");
break;
case kCWSecurityWEP:
ffStrbufAppendS(&item->conn.security, "WEP");
ffStrbufSetStatic(&item->conn.security, "WEP");
break;
case kCWSecurityWPAPersonal:
ffStrbufAppendS(&item->conn.security, "WPA Personal");
ffStrbufSetStatic(&item->conn.security, "WPA Personal");
break;
case kCWSecurityWPAPersonalMixed:
ffStrbufAppendS(&item->conn.security, "WPA Persional Mixed");
ffStrbufSetStatic(&item->conn.security, "WPA Persional Mixed");
break;
case kCWSecurityWPA2Personal:
ffStrbufAppendS(&item->conn.security, "WPA2 Personal");
ffStrbufSetStatic(&item->conn.security, "WPA2 Personal");
break;
case kCWSecurityPersonal:
ffStrbufAppendS(&item->conn.security, "Personal");
ffStrbufSetStatic(&item->conn.security, "Personal");
break;
case kCWSecurityDynamicWEP:
ffStrbufAppendS(&item->conn.security, "Dynamic WEP");
ffStrbufSetStatic(&item->conn.security, "Dynamic WEP");
break;
case kCWSecurityWPAEnterprise:
ffStrbufAppendS(&item->conn.security, "WPA Enterprise");
ffStrbufSetStatic(&item->conn.security, "WPA Enterprise");
break;
case kCWSecurityWPAEnterpriseMixed:
ffStrbufAppendS(&item->conn.security, "WPA Enterprise Mixed");
ffStrbufSetStatic(&item->conn.security, "WPA Enterprise Mixed");
break;
case kCWSecurityWPA2Enterprise:
ffStrbufAppendS(&item->conn.security, "WPA2 Enterprise");
ffStrbufSetStatic(&item->conn.security, "WPA2 Enterprise");
break;
case kCWSecurityEnterprise:
ffStrbufAppendS(&item->conn.security, "Enterprise");
ffStrbufSetStatic(&item->conn.security, "Enterprise");
break;
case kCWSecurityWPA3Personal:
ffStrbufAppendS(&item->conn.security, "WPA3 Personal");
ffStrbufSetStatic(&item->conn.security, "WPA3 Personal");
break;
case kCWSecurityWPA3Enterprise:
ffStrbufAppendS(&item->conn.security, "WPA3 Enterprise");
ffStrbufSetStatic(&item->conn.security, "WPA3 Enterprise");
break;
case kCWSecurityWPA3Transition:
ffStrbufAppendS(&item->conn.security, "WPA3 Transition");
ffStrbufSetStatic(&item->conn.security, "WPA3 Transition");
break;
case 14 /*kCWSecurityOWE*/:
ffStrbufAppendS(&item->conn.security, "OWE");
ffStrbufSetStatic(&item->conn.security, "OWE");
break;
case 15 /*kCWSecurityOWETransition*/:
ffStrbufAppendS(&item->conn.security, "OWE Transition");
ffStrbufSetStatic(&item->conn.security, "OWE Transition");
break;
case kCWSecurityUnknown:
// Ignore
// Sonoma...
if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName)))
{
NSDictionary* authType = [apple valueForKey:@"AUTH_TYPE"];
if (authType)
{
if ([[authType valueForKey:@"AUTH_LOWER"] intValue] != 1) break; // APPLE80211_AUTH_TYPE_UNICAST?
NSNumber* authUpper = [authType valueForKey:@"AUTH_UPPER"];
if (!authUpper)
ffStrbufSetStatic(&item->conn.security, "Insecure");
else
{
int authUpperValue = [authUpper intValue];
switch (authUpperValue)
{
case 4096:
ffStrbufSetStatic(&item->conn.security, "WPA3-SAE");
break;
case 8:
ffStrbufSetStatic(&item->conn.security, "WPA2-PSK");
break;
case 4:
ffStrbufSetStatic(&item->conn.security, "WPA2");
break;
default: // TODO: support more auth types
ffStrbufAppendF(&item->conn.security, "To be supported (%d)", authUpperValue);
break;
}
}
}
}
break;
default:
ffStrbufAppendF(&item->conn.security, "Unknown (%ld)", inf.security);
+1 -1
View File
@@ -22,7 +22,7 @@
static const char* detectWifiWithLibnm(FFlist* result)
{
FF_LIBRARY_LOAD(nm, &instance.config.libnm, "dlopen libnm failed", "libnm" FF_LIBRARY_EXTENSION, 0);
FF_LIBRARY_LOAD(nm, &instance.config.library.libnm, "dlopen libnm failed", "libnm" FF_LIBRARY_EXTENSION, 0);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_new);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_get_devices);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_device_get_iface);
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "fastfetch.h"
const char* ffDetectWMPlugin(FFstrbuf* pluginName);
+37
View File
@@ -0,0 +1,37 @@
#include "wm.h"
#include "common/sysctl.h"
#include "util/mallocHelper.h"
#include <ctype.h>
const char* ffDetectWMPlugin(FFstrbuf* pluginName)
{
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
u_int requestLength = sizeof(request) / sizeof(*request);
size_t length = 0;
FF_AUTO_FREE struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length);
if(processes == NULL)
return "sysctl(CTL_KERN, KERN_PROC, KERN_PROC_ALL) failed";
for(size_t i = 0; i < length / sizeof(struct kinfo_proc); i++)
{
const char* comm = processes[i].kp_proc.p_comm;
if(
strcasecmp(comm, "spectacle") != 0 &&
strcasecmp(comm, "amethyst") != 0 &&
strcasecmp(comm, "kwm") != 0 &&
strcasecmp(comm, "chunkwm") != 0 &&
strcasecmp(comm, "yabai") != 0 &&
strcasecmp(comm, "rectangle") != 0
) continue;
ffStrbufAppendS(pluginName, comm);
pluginName->chars[0] = (char) toupper(pluginName->chars[0]);
break;
}
return NULL;
}
+6
View File
@@ -0,0 +1,6 @@
#include "wm.h"
const char* ffDetectWMPlugin(FF_MAYBE_UNUSED FFstrbuf* pluginName)
{
return "Not supported on this platform";
}
+66
View File
@@ -0,0 +1,66 @@
extern "C"
{
#include "wm.h"
#include "common/io/io.h"
#include "detection/terminalshell/terminalshell.h"
}
#include "util/windows/com.hpp"
#include <utility>
#include <windows.h>
#include <tlhelp32.h>
#include <shlobj.h>
#include <Propkey.h>
template <typename Fn>
struct on_scope_exit {
on_scope_exit(Fn &&fn): _fn(std::move(fn)) {}
~on_scope_exit() { this->_fn(); }
private:
Fn _fn;
};
extern "C"
const char* ffDetectWMPlugin(FFstrbuf* pluginName)
{
DWORD pid = ffDetectTerminalShell()->terminalPid; // Whatever GUI program
if (pid == 0) return "Unable to find a GUI program";
FF_AUTO_CLOSE_FD HANDLE snapshot = NULL;
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
if(!snapshot)
return "CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid) failed";
if (ffInitCom())
return "ffInitCom() failed";
MODULEENTRY32W module;
module.dwSize = sizeof(module);
for(BOOL success = Module32FirstW(snapshot, &module); success; success = Module32NextW(snapshot, &module))
{
if(wcscmp(module.szModule, L"wbhelp64.dll") == 0 || wcscmp(module.szModule, L"wbhelp.dll") == 0)
{
IShellItem2* shellItem = NULL;
if (FAILED(SHCreateItemFromParsingName(module.szExePath, NULL, IID_IShellItem2, (void**) &shellItem)))
continue;
on_scope_exit destroyShellItem([=] { shellItem->Release(); });
wchar_t* desc = NULL;
if (FAILED(shellItem->GetString(PKEY_FileDescription, &desc)))
continue;
on_scope_exit destroyDesc([=] { CoTaskMemFree(desc); });
if (wcscmp(desc, L"WindowBlinds Helper DLL") == 0)
{
ffStrbufSetStatic(pluginName, "WindowBlinds");
break;
}
}
}
return NULL;
}
+141 -263
View File
@@ -236,18 +236,24 @@ static bool parseConfigFile(FFdata* data, const char* path)
static void generateConfigFile(bool force, const char* type)
{
if (!type)
{
fputs("Error: the config type (`jsonc` or `conf`) must be specified\n", stderr);
exit(1);
}
FFstrbuf* filename = (FFstrbuf*) ffListGet(&instance.state.platform.configDirs, 0);
// Paths generated in `init.c/initConfigDirs` end with `/`
bool isJsonc = false;
if (type)
bool isJsonc = ffStrEqualsIgnCase(type, "jsonc");
if (!isJsonc)
{
if (ffStrEqualsIgnCase(type, "jsonc"))
isJsonc = true;
else if (!ffStrEqualsIgnCase(type, "conf"))
if (!ffStrEqualsIgnCase(type, "conf"))
{
fputs("config type can only be `jsonc` or `conf`\n", stderr);
fputs("Error: config type can only be `jsonc` or `conf`\n", stderr);
exit(1);
}
else
fputs("Warning: support of flag based config type `conf` is deprecated, and may be removed in the future\n", stderr);
}
ffStrbufAppendS(filename, isJsonc ? "fastfetch/config.jsonc" : "fastfetch/config.conf");
@@ -332,16 +338,6 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
exit(414);
}
static inline void optionCheckString(const char* key, const char* value, FFstrbuf* buffer)
{
if(value == NULL)
{
fprintf(stderr, "Error: usage: %s <str>\n", key);
exit(477);
}
ffStrbufEnsureFree(buffer, 63); //This is not needed, as ffStrbufSetS will resize capacity if needed, but giving a higher start should improve performance
}
static void printVersion()
{
FFVersionResult result = {};
@@ -471,9 +467,9 @@ static void parseOption(FFdata* data, const char* key, const char* value)
customValue->printKey = key[5] == '\0';
}
///////////////////
//General options//
///////////////////
////////////
//Switches//
////////////
else if(ffStrEqualsIgnCase(key, "-c") || ffStrEqualsIgnCase(key, "--load-config") || ffStrEqualsIgnCase(key, "--config"))
optionParseConfigFile(data, key, value);
@@ -481,23 +477,30 @@ static void parseOption(FFdata* data, const char* key, const char* value)
generateConfigFile(false, value);
else if(ffStrEqualsIgnCase(key, "--gen-config-force"))
generateConfigFile(true, value);
else if(ffStrEqualsIgnCase(key, "--thread") || ffStrEqualsIgnCase(key, "--multithreading"))
instance.config.multithreading = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--stat"))
else if (ffStrEqualsIgnCase(key, "--migrate-config"))
{
if((instance.config.stat = ffOptionParseBoolean(value)))
instance.config.showErrors = true;
if (instance.state.configDoc)
{
fputs("Error: existing jsonc config detected. Aborting\n", stderr);
exit(477);
}
if (!value)
{
ffStrbufSet(&instance.state.migrateConfigPath, (FFstrbuf*) ffListGet(&instance.state.platform.configDirs, 0));
ffStrbufAppendS(&instance.state.migrateConfigPath, "fastfetch/config.jsonc");
}
else
ffStrbufSetS(&instance.state.migrateConfigPath, value);
if (ffPathExists(instance.state.migrateConfigPath.chars, FF_PATHTYPE_ANY))
{
fprintf(stderr, "Error: file `%s` exists. Aborting\n", instance.state.migrateConfigPath.chars);
exit(477);
}
}
else if(ffStrEqualsIgnCase(key, "--allow-slow-operations"))
instance.config.allowSlowOperations = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--escape-bedrock"))
instance.config.escapeBedrock = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--pipe"))
instance.config.pipe = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--load-user-config"))
data->loadUserConfig = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--processing-timeout"))
instance.config.processingTimeout = ffOptionParseInt32(key, value);
else if(ffStrEqualsIgnCase(key, "--format"))
{
switch (ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
@@ -522,188 +525,20 @@ static void parseOption(FFdata* data, const char* key, const char* value)
break;
}
}
#if defined(__linux__) || defined(__FreeBSD__)
else if(ffStrEqualsIgnCase(key, "--player-name"))
ffOptionParseString(key, value, &instance.config.playerName);
else if (ffStrEqualsIgnCase(key, "--os-file"))
ffOptionParseString(key, value, &instance.config.osFile);
else if(ffStrEqualsIgnCase(key, "--ds-force-drm"))
instance.config.dsForceDrm = ffOptionParseBoolean(value);
#elif defined(_WIN32)
else if (ffStrEqualsIgnCase(key, "--wmi-timeout"))
instance.config.wmiTimeout = ffOptionParseInt32(key, value);
#endif
////////////////
//Logo options//
////////////////
else if(ffParseLogoCommandOptions(&instance.config.logo, key, value)) {}
///////////////////
//Display options//
///////////////////
else if(ffStrEqualsIgnCase(key, "--show-errors"))
instance.config.showErrors = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--disable-linewrap"))
instance.config.disableLinewrap = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--hide-cursor"))
instance.config.hideCursor = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "-s") || ffStrEqualsIgnCase(key, "--structure"))
ffOptionParseString(key, value, &data->structure);
else if(ffStrEqualsIgnCase(key, "--separator"))
ffOptionParseString(key, value, &instance.config.keyValueSeparator);
else if(ffStrEqualsIgnCase(key, "--color"))
{
optionCheckString(key, value, &instance.config.colorKeys);
ffOptionParseColor(value, &instance.config.colorKeys);
ffStrbufSet(&instance.config.colorTitle, &instance.config.colorKeys);
}
else if(ffStrStartsWithIgnCase(key, "--color-"))
{
const char* subkey = key + strlen("--color-");
if(ffStrEqualsIgnCase(subkey, "keys"))
{
optionCheckString(key, value, &instance.config.colorKeys);
ffOptionParseColor(value, &instance.config.colorKeys);
}
else if(ffStrEqualsIgnCase(subkey, "title"))
{
optionCheckString(key, value, &instance.config.colorTitle);
ffOptionParseColor(value, &instance.config.colorTitle);
}
else
goto error;
}
else if(ffStrEqualsIgnCase(key, "--key-width"))
instance.config.keyWidth = ffOptionParseUInt32(key, value);
else if(ffStrEqualsIgnCase(key, "--bright-color"))
instance.config.brightColor = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(key, "--binary-prefix"))
{
instance.config.binaryPrefixType = (FFBinaryPrefixType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "iec", FF_BINARY_PREFIX_TYPE_IEC },
{ "si", FF_BINARY_PREFIX_TYPE_SI },
{ "jedec", FF_BINARY_PREFIX_TYPE_JEDEC },
{}
});
}
else if(ffStrEqualsIgnCase(key, "--size-ndigits"))
instance.config.sizeNdigits = (uint8_t) ffOptionParseUInt32(key, value);
else if(ffStrEqualsIgnCase(key, "--size-max-prefix"))
{
instance.config.sizeMaxPrefix = (uint8_t) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "B", 0 },
{ "kB", 1 },
{ "MB", 2 },
{ "GB", 3 },
{ "TB", 4 },
{ "PB", 5 },
{ "EB", 6 },
{ "ZB", 7 },
{ "YB", 8 },
{}
});
}
else if(ffStrEqualsIgnCase(key, "--temperature-unit"))
{
instance.config.temperatureUnit = (FFTemperatureUnit) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
{},
});
}
else if(ffStrEqualsIgnCase(key, "--percent-type"))
instance.config.percentType = (uint8_t) ffOptionParseUInt32(key, value);
else if(ffStrEqualsIgnCase(key, "--percent-ndigits"))
instance.config.percentNdigits = (uint8_t) ffOptionParseUInt32(key, value);
else if(ffStrEqualsIgnCase(key, "--no-buffer"))
instance.config.noBuffer = ffOptionParseBoolean(value);
else if(ffStrStartsWithIgnCase(key, "--bar-"))
{
const char* subkey = key + strlen("--bar-");
if(ffStrEqualsIgnCase(subkey, "char-elapsed"))
ffOptionParseString(key, value, &instance.config.barCharElapsed);
else if(ffStrEqualsIgnCase(subkey, "char-total"))
ffOptionParseString(key, value, &instance.config.barCharTotal);
else if(ffStrEqualsIgnCase(subkey, "width"))
instance.config.barWidth = (uint8_t) ffOptionParseUInt32(key, value);
else if(ffStrEqualsIgnCase(subkey, "border"))
instance.config.barBorder = ffOptionParseBoolean(value);
else
goto error;
}
///////////////////
//Library options//
///////////////////
///////////
//Options//
///////////
else if(ffStrStartsWithIgnCase(key, "--lib-"))
{
const char* subkey = key + strlen("--lib-");
if(ffStrEqualsIgnCase(subkey, "PCI"))
ffOptionParseString(key, value, &instance.config.libPCI);
else if(ffStrEqualsIgnCase(subkey, "vulkan"))
ffOptionParseString(key, value, &instance.config.libVulkan);
else if(ffStrEqualsIgnCase(subkey, "freetype"))
ffOptionParseString(key, value, &instance.config.libfreetype);
else if(ffStrEqualsIgnCase(subkey, "wayland"))
ffOptionParseString(key, value, &instance.config.libWayland);
else if(ffStrEqualsIgnCase(subkey, "xcb-randr"))
ffOptionParseString(key, value, &instance.config.libXcbRandr);
else if(ffStrEqualsIgnCase(subkey, "xcb"))
ffOptionParseString(key, value, &instance.config.libXcb);
else if(ffStrEqualsIgnCase(subkey, "Xrandr"))
ffOptionParseString(key, value, &instance.config.libXrandr);
else if(ffStrEqualsIgnCase(subkey, "X11"))
ffOptionParseString(key, value, &instance.config.libX11);
else if(ffStrEqualsIgnCase(subkey, "gio"))
ffOptionParseString(key, value, &instance.config.libGIO);
else if(ffStrEqualsIgnCase(subkey, "DConf"))
ffOptionParseString(key, value, &instance.config.libDConf);
else if(ffStrEqualsIgnCase(subkey, "dbus"))
ffOptionParseString(key, value, &instance.config.libDBus);
else if(ffStrEqualsIgnCase(subkey, "XFConf"))
ffOptionParseString(key, value, &instance.config.libXFConf);
else if(ffStrEqualsIgnCase(subkey, "sqlite") || ffStrEqualsIgnCase(subkey, "sqlite3"))
ffOptionParseString(key, value, &instance.config.libSQLite3);
else if(ffStrEqualsIgnCase(subkey, "rpm"))
ffOptionParseString(key, value, &instance.config.librpm);
else if(ffStrEqualsIgnCase(subkey, "imagemagick"))
ffOptionParseString(key, value, &instance.config.libImageMagick);
else if(ffStrEqualsIgnCase(subkey, "z"))
ffOptionParseString(key, value, &instance.config.libZ);
else if(ffStrEqualsIgnCase(subkey, "chafa"))
ffOptionParseString(key, value, &instance.config.libChafa);
else if(ffStrEqualsIgnCase(subkey, "egl"))
ffOptionParseString(key, value, &instance.config.libEGL);
else if(ffStrEqualsIgnCase(subkey, "glx"))
ffOptionParseString(key, value, &instance.config.libGLX);
else if(ffStrEqualsIgnCase(subkey, "osmesa"))
ffOptionParseString(key, value, &instance.config.libOSMesa);
else if(ffStrEqualsIgnCase(subkey, "opencl"))
ffOptionParseString(key, value, &instance.config.libOpenCL);
else if(ffStrEqualsIgnCase(subkey, "pulse"))
ffOptionParseString(key, value, &instance.config.libPulse);
else if(ffStrEqualsIgnCase(subkey, "nm"))
ffOptionParseString(key, value, &instance.config.libnm);
else if(ffStrEqualsIgnCase(subkey, "ddcutil"))
ffOptionParseString(key, value, &instance.config.libDdcutil);
else
goto error;
}
///////////////////////
//Module args options//
///////////////////////
else if(ffParseModuleOptions(key, value)) {}
else if(
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)
) {}
//////////////////
//Unknown option//
@@ -719,20 +554,22 @@ error:
static void parseConfigFiles(FFdata* data)
{
for(uint32_t i = instance.state.platform.configDirs.length; i > 0; --i)
if (__builtin_expect(instance.state.migrateConfigPath.length == 0, true))
{
FFstrbuf* dir = ffListGet(&instance.state.platform.configDirs, i - 1);
uint32_t dirLength = dir->length;
for (uint32_t i = instance.state.platform.configDirs.length; i > 0; --i)
{
FFstrbuf* dir = ffListGet(&instance.state.platform.configDirs, i - 1);
uint32_t dirLength = dir->length;
ffStrbufAppendS(dir, "fastfetch/config.jsonc");
bool success = parseJsoncFile(dir->chars);
ffStrbufSubstrBefore(dir, dirLength);
if (success) return;
ffStrbufAppendS(dir, "fastfetch/config.jsonc");
bool success = parseJsoncFile(dir->chars);
ffStrbufSubstrBefore(dir, dirLength);
if (success) return;
}
}
for(uint32_t i = instance.state.platform.configDirs.length; i > 0; --i)
for (uint32_t i = instance.state.platform.configDirs.length; i > 0; --i)
{
if(!data->loadUserConfig)
if (!data->loadUserConfig)
return;
FFstrbuf* dir = ffListGet(&instance.state.platform.configDirs, i - 1);
@@ -773,60 +610,101 @@ static void parseArguments(FFdata* data, int argc, const char** argv)
}
}
static void run(FFdata* data)
{
if (instance.state.configDoc)
{
const char* error = NULL;
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
if (!yyjson_is_obj(root))
error = "Invalid JSON config format. Root value must be an object";
if (
error ||
(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);
exit(477);
}
}
const bool useJsonConfig = data->structure.length == 0 && instance.state.configDoc;
if (useJsonConfig)
ffPrintJsonConfig(true /* prepare */, instance.state.resultDoc);
else
ffPrepareCommandOption(data);
ffStart();
#if defined(_WIN32)
if (!instance.config.display.noBuffer) fflush(stdout);
#endif
if (useJsonConfig)
ffPrintJsonConfig(false, instance.state.resultDoc);
else
ffPrintCommandOption(data, instance.state.resultDoc);
if (instance.state.resultDoc)
yyjson_mut_write_fp(stdout, instance.state.resultDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL);
else
ffFinish();
}
static void migrateConfig(FFdata* data, const FFstrbuf* filename)
{
yyjson_mut_doc* doc = yyjson_mut_doc_new(NULL);
yyjson_mut_val* root = yyjson_mut_obj(doc);
yyjson_mut_doc_set_root(doc, root);
yyjson_mut_obj_add_str(doc, root, "$schema", "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json");
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, "-"))
yyjson_mut_write_fp(stdout, doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL);
else
{
if (yyjson_mut_write_file(filename->chars, doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL))
printf("The migrated config file has been written in `%s`\nYou may remove the old config file if everything works fine\n", filename->chars);
else
{
printf("Error: failed to write file in `%s`\n", filename->chars);
exit(1);
}
}
yyjson_mut_doc_free(doc);
}
int main(int argc, const char** argv)
{
ffInitInstance();
//Data stores things only needed for the configuration of fastfetch
FFdata data;
ffStrbufInit(&data.structure);
ffListInit(&data.customValues, sizeof(FFCustomValue));
data.loadUserConfig = true;
FFdata data = {
.structure = ffStrbufCreate(),
.customValues = ffListCreate(sizeof(FFCustomValue)),
.loadUserConfig = true,
};
if(!getenv("NO_CONFIG"))
parseConfigFiles(&data);
parseArguments(&data, argc, argv);
if (instance.state.configDoc)
{
const char* error = NULL;
if (
(error = ffParseLogoJsonConfig()) ||
(error = ffParseGeneralJsonConfig()) ||
(error = ffParseDisplayJsonConfig()) ||
(error = ffParseLibraryJsonConfig()) ||
false
) {
fputs(error, stderr);
exit(477);
}
}
const bool useJsonConfig = data.structure.length == 0 && instance.state.configDoc;
if(useJsonConfig)
ffPrintJsonConfig(true /* prepare */);
if (__builtin_expect(instance.state.migrateConfigPath.length == 0, true))
run(&data);
else
ffPrepareCommandOption(&data);
ffStart();
#if defined(_WIN32)
if (!instance.config.noBuffer) fflush(stdout);
#endif
if (useJsonConfig)
ffPrintJsonConfig(false);
else
ffPrintCommandOption(&data);
if (instance.state.resultDoc)
{
yyjson_mut_write_fp(stdout, instance.state.resultDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL);
}
ffFinish();
migrateConfig(&data, &instance.state.migrateConfigPath);
ffStrbufDestroy(&data.structure);
FF_LIST_FOR_EACH(FFCustomValue, customValue, data.customValues)
+11 -139
View File
@@ -23,148 +23,19 @@
#include "util/platform/FFPlatform.h"
#include "util/unused.h"
#include "modules/options.h"
#include "logo/option.h"
typedef enum FFBinaryPrefixType
{
FF_BINARY_PREFIX_TYPE_IEC, // 1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard)
FF_BINARY_PREFIX_TYPE_SI, // 1000 Bytes = 1 KB, 1000 KB = 1 MB, ...
FF_BINARY_PREFIX_TYPE_JEDEC, // 1024 Bytes = 1 kB, 1024 K = 1 MB, ...
} FFBinaryPrefixType;
typedef enum FFTemperatureUnit
{
FF_TEMPERATURE_UNIT_CELSIUS,
FF_TEMPERATURE_UNIT_FAHRENHEIT,
FF_TEMPERATURE_UNIT_KELVIN,
} FFTemperatureUnit;
#include "options/modules.h"
#include "options/logo.h"
#include "options/display.h"
#include "options/general.h"
#include "options/library.h"
typedef struct FFconfig
{
FFLogoOptions logo;
//If one of those is empty, ffLogoPrint will set them
FFstrbuf colorKeys;
FFstrbuf colorTitle;
bool brightColor;
FFstrbuf keyValueSeparator;
bool showErrors;
bool allowSlowOperations;
bool disableLinewrap;
bool hideCursor;
bool escapeBedrock;
FFBinaryPrefixType binaryPrefixType;
uint8_t sizeNdigits;
uint8_t sizeMaxPrefix;
FFTemperatureUnit temperatureUnit;
FFstrbuf barCharElapsed;
FFstrbuf barCharTotal;
uint8_t barWidth;
bool barBorder;
uint8_t percentType;
uint8_t percentNdigits;
bool pipe; //disables logo and all escape sequences
bool multithreading;
bool stat;
bool noBuffer;
int32_t processingTimeout;
uint32_t keyWidth;
// Module options that cannot be put in module option structure
#if defined(__linux__) || defined(__FreeBSD__)
FFstrbuf playerName;
FFstrbuf osFile;
bool dsForceDrm;
#elif defined(_WIN32)
int32_t wmiTimeout;
#endif
FFBatteryOptions battery;
FFBiosOptions bios;
FFBluetoothOptions bluetooth;
FFBoardOptions board;
FFBreakOptions break_;
FFBrightnessOptions brightness;
FFCPUOptions cpu;
FFCPUUsageOptions cpuUsage;
FFChassisOptions chassis;
FFColorsOptions colors;
FFCommandOptions command;
FFCursorOptions cursor;
FFCustomOptions custom;
FFDEOptions de;
FFDateTimeOptions dateTime;
FFDiskOptions disk;
FFDiskIOOptions diskIo;
FFDisplayOptions display;
FFFontOptions font;
FFGPUOptions gpu;
FFGamepadOptions gamepad;
FFHostOptions host;
FFIconsOptions icons;
FFKernelOptions kernel;
FFLMOptions lm;
FFLocalIpOptions localIP;
FFLocaleOptions locale;
FFMediaOptions media;
FFMemoryOptions memory;
FFMonitorOptions monitor;
FFNetIOOptions netIo;
FFOSOptions os;
FFOpenCLOptions openCL;
FFOpenGLOptions openGL;
FFPackagesOptions packages;
FFPlayerOptions player;
FFPowerAdapterOptions powerAdapter;
FFProcessesOptions processes;
FFPublicIpOptions publicIP;
FFSeparatorOptions separator;
FFShellOptions shell;
FFSoundOptions sound;
FFSwapOptions swap;
FFTerminalFontOptions terminalFont;
FFTerminalOptions terminal;
FFTerminalSizeOptions terminalSize;
FFThemeOptions theme;
FFTitleOptions title;
FFUptimeOptions uptime;
FFUsersOptions users;
FFVersionOptions version;
FFVulkanOptions vulkan;
FFWMOptions wm;
FFWMThemeOptions wmTheme;
FFWallpaperOptions wallpaper;
FFWeatherOptions weather;
FFWifiOptions wifi;
FFstrbuf libPCI;
FFstrbuf libVulkan;
FFstrbuf libWayland;
FFstrbuf libXcbRandr;
FFstrbuf libXcb;
FFstrbuf libXrandr;
FFstrbuf libX11;
FFstrbuf libGIO;
FFstrbuf libDConf;
FFstrbuf libDBus;
FFstrbuf libXFConf;
FFstrbuf libSQLite3;
FFstrbuf librpm;
FFstrbuf libImageMagick;
FFstrbuf libZ;
FFstrbuf libChafa;
FFstrbuf libEGL;
FFstrbuf libGLX;
FFstrbuf libOSMesa;
FFstrbuf libOpenCL;
FFstrbuf libfreetype;
FFstrbuf libPulse;
FFstrbuf libnm;
FFstrbuf libDdcutil;
FFOptionsLogo logo;
FFOptionsDisplay display;
FFOptionsGeneral general;
FFOptionsModules modules;
FFOptionsLibrary library;
} FFconfig;
typedef struct FFstate
@@ -176,6 +47,7 @@ typedef struct FFstate
FFPlatform platform;
yyjson_doc* configDoc;
yyjson_mut_doc* resultDoc;
FFstrbuf migrateConfigPath;
} FFstate;
typedef struct FFinstance
+51 -50
View File
@@ -7,63 +7,64 @@ int main(void)
ffInitInstance(); //This also applys default configuration to instance.config
//Modify instance.config here
FFOptionsModules* const options = &instance.config.modules;
// ffPrepareCPUUsage();
// ffPreparePublicIp(&instance.config.publicIP);
// ffPrepareWeather(&instance.config.weather);
// ffPreparePublicIp(&options->publicIP);
// ffPrepareWeather(&options->weather);
//Does things like starting detection threads, disabling line wrap, etc
ffStart();
//Printing
ffPrintTitle(&instance.config.title);
ffPrintSeparator(&instance.config.separator);
ffPrintOS(&instance.config.os);
ffPrintHost(&instance.config.host);
//ffPrintBios(&instance.config.bios);
//ffPrintBoard(&instance.config.board);
//ffPrintChassis(&instance.config.chassis);
ffPrintKernel(&instance.config.kernel);
//ffPrintProcesses(&instance.config.processes);
ffPrintUptime(&instance.config.uptime);
ffPrintPackages(&instance.config.packages);
ffPrintShell(&instance.config.shell);
ffPrintDisplay(&instance.config.display);
// ffPrintBrightness(&instance.config.brightness);
ffPrintDE(&instance.config.de);
ffPrintWM(&instance.config.wm);
ffPrintWMTheme(&instance.config.wmTheme);
ffPrintTheme(&instance.config.theme);
ffPrintIcons(&instance.config.icons);
ffPrintFont(&instance.config.font);
ffPrintCursor(&instance.config.cursor);
ffPrintTerminal(&instance.config.terminal);
ffPrintTerminalFont(&instance.config.terminalFont);
ffPrintCPU(&instance.config.cpu);
ffPrintGPU(&instance.config.gpu);
ffPrintMemory(&instance.config.memory);
ffPrintSwap(&instance.config.swap);
ffPrintDisk(&instance.config.disk);
ffPrintBattery(&instance.config.battery);
ffPrintPowerAdapter(&instance.config.powerAdapter);
//ffPrintPlayer(&instance.config.player);
//ffPrintMedia(&instance.config.media);
//ffPrintLocalIp(&instance.config.localIp);
//ffPrintPublicIp(&instance.config.publicIp);
//ffPrintWifi(&instance.config.wifi);
//ffPrintCPUUsage(&instance.config.cpuUsage);
ffPrintLocale(&instance.config.locale);
//ffPrintDateTime(&instance.config.dateTime);
//ffPrintVulkan(&instance.config.vulkan);
//ffPrintOpenGL(&instance.config.openGL);
//ffPrintOpenCL(&instance.config.openCL);
//ffPrintUsers(&instance.config.users);
//ffPrintWeather(&instance.config.weather);
//ffPrintBluetooth(&instance.config.bluetooth);
//ffPrintSound(&instance.config.sound);
//ffPrintGamepad(&instance.config.gamepad);
ffPrintBreak(&instance.config.break_);
ffPrintColors(&instance.config.colors);
ffPrintTitle(&options->title);
ffPrintSeparator(&options->separator);
ffPrintOS(&options->os);
ffPrintHost(&options->host);
//ffPrintBios(&options->bios);
//ffPrintBoard(&options->board);
//ffPrintChassis(&options->chassis);
ffPrintKernel(&options->kernel);
//ffPrintProcesses(&options->processes);
ffPrintUptime(&options->uptime);
ffPrintPackages(&options->packages);
ffPrintShell(&options->shell);
ffPrintDisplay(&options->display);
// ffPrintBrightness(&options->brightness);
ffPrintDE(&options->de);
ffPrintWM(&options->wm);
ffPrintWMTheme(&options->wmTheme);
ffPrintTheme(&options->theme);
ffPrintIcons(&options->icons);
ffPrintFont(&options->font);
ffPrintCursor(&options->cursor);
ffPrintTerminal(&options->terminal);
ffPrintTerminalFont(&options->terminalFont);
ffPrintCPU(&options->cpu);
ffPrintGPU(&options->gpu);
ffPrintMemory(&options->memory);
ffPrintSwap(&options->swap);
ffPrintDisk(&options->disk);
ffPrintBattery(&options->battery);
ffPrintPowerAdapter(&options->powerAdapter);
//ffPrintPlayer(&options->player);
//ffPrintMedia(&options->media);
//ffPrintLocalIp(&options->localIp);
//ffPrintPublicIp(&options->publicIp);
//ffPrintWifi(&options->wifi);
//ffPrintCPUUsage(&options->cpuUsage);
ffPrintLocale(&options->locale);
//ffPrintDateTime(&options->dateTime);
//ffPrintVulkan(&options->vulkan);
//ffPrintOpenGL(&options->openGL);
//ffPrintOpenCL(&options->openCL);
//ffPrintUsers(&options->users);
//ffPrintWeather(&options->weather);
//ffPrintBluetooth(&options->bluetooth);
//ffPrintSound(&options->sound);
//ffPrintGamepad(&options->gamepad);
ffPrintBreak(&options->break_);
ffPrintColors(&options->colors);
ffFinish();
ffDestroyInstance();
+17
View File
@@ -0,0 +1,17 @@
${c1} ////. ${c2} (((((
${c1}//////// ${c2} @((((((((
${c1}//////// ${c2} @((((((((
${c1}//////// /////// ${c2} ((((((( @((((((((
${c1}//////// ///////// ${c2} ((((((((( @((((((((
${c1}//////// ///////// ${c2} ((((((((( @((((((((
${c1}//////// ///////// ////// ${c2} (((((( ((((((((( @((((((((
${c1}//////// ///////// //////// ${c2} (((((((( ((((((((( @((((((((
${c1}//////// ///////// //////// ${c2} (((((((( ((((((((( @((((((((
${c1}//////// ///////// //////// ${c2} ((((((( ((((((((( @((((((((
${c1}//////// ///////// /// ${c2} ( ((((((((( @((((((((
${c1}//////// ///////// ${c2} ((((((((( @((((((((
${c1}//////// ///////// ${c2} &(((((((( @((((((((
${c1}//////// ////// ${c2} @(((( @((((((((
${c1}//////// ${c2} @((((((((
${c1}//////// ${c2} @((((((((
${c1} ///// ${c2} (((((
+20
View File
@@ -0,0 +1,20 @@
.-;+$$XHHHHHHX$$+;-
,:X@@X%/;=----=:\%X@@X:,
=$$@@%=. .=+H@X:
-XMX: =XMX=
/@@: =H@+
%@X. .$$@$$
+@X, $$@%
/@@, .@@\
%@% +@$$
H@: :@H
H@: :HHHHHHHHHHHHHHHHHHX, =@H
%@% ;@M@@@@@@@@@@@@@@@@@H- +@$$
=@@, :@@@@@@@@@@@@@@@@@@@@@= .@@:
=@X :@@@@@@@@@@@@@@@@@@@@@@:%@%
$$@$$, ;@@@@@@@@@@@@@@@@@M@@@@@@$$
+@@HHHHHHH@@@@@@@@@@@@@@@@@@@@@@@
=X@@@@@@@@@@@@@@@@@@@@@@@@@@@X=
:$$@@@@@@@@@@@@@@@@@@M@@@@$$:
\$$@@@@@@@@@@@@@@@@@@X/-
.-;+$$XXHHHHHX$$+;-.
+21
View File
@@ -0,0 +1,21 @@
.:ox00000kdc,
;; 'cdO. dxl,.
00 'oO' 0x;
00ko ,Oc
x00Okxx lO'
.x, .0c
;c .O00' :: '0:
. O0000. o0.
.0c ,,;;:clO00000Olc:;;,, .0l
x0 ;00000000000000000c 00
00 0000000000000. 0O
x0. ... 00000000000. ... '0:
.0c ,00000000000o .o
o0. O000; '0000
0k .0 O O'
lO. ''.....
.0o d000
Oo' ,dO O0
;Oo;. .;oO, 00
xkdocc:ccodko
;k0k,
+10
View File
@@ -0,0 +1,10 @@
#-----------------------------------------------------------------------#
|#SSSSSSSS\*SS\****SS\**SSSSSS\**SS\*******SSSSSS\*SS\***SS\*SS\***SS\*#|
|#SS**_____|SS*|***SS*|SS**__SS\*SS*|******\_SS**_|SSS\**SS*|SS*|**SS*|#|
|#SS*|******SS*|***SS*|SS*/**SS*|SS*|********SS*|**SSSS\*SS*|\SS\*SS**|#|
|#SSSSS\****\SS\**SS**|SS*|**SS*|SS*|********SS*|**SS*SS\SS*|*\SSSS**/*#|
|#SS**__|****\SS\SS**/*SS*|**SS*|SS*|********SS*|**SS*\SSSS*|*SS**SS<**#|
|#SS*|********\SSS**/**SS*|**SS*|SS*|********SS*|**SS*|\SSS*|SS**/\SS\*#|
|#SSSSSSSS\****\S**/****SSSSSS**|SSSSSSSS\*SSSSSS\*SS*|*\SS*|SS*/**SS*|#|
|#\________|****\_/*****\______/*\________|\______|\__|**\__|\__|**\__|#|
#-----------------------------------------------------------------------#
+17
View File
@@ -0,0 +1,17 @@
.${c3}.
${c1} 75${c3}G!
${c1} ^?PG${c3}&&J.
${c1} :!5GPP${c3}&&&B!
${c1} :YPPPPP${c3}&&&&&Y:
${c1} !5PPPPPP${c3}&&&&&&B!
${c1} :?PPPPPPPP${c3}&&&&&&&&Y~
${c1} !5PPPPPPPPP${c3}###&&&&&&B7
${c1} :?PPPP5555555${c3}B####&&&&&&5:
${c1} ~5PPPP555YJ${c5}7!~7?${c3}5B###&&&&&B?.
${c1} .:JPPPP5555Y${c5}?^....:^?${c3}G####&&&&&5:
${c1} 75PPP555555Y${c5}7:....:^!${c3}5#####&&&&&B7.
${c1} :JPPPP${c2}555555YY?${c5}~::::^~${c2}7YPGBB###${c3}&&&&&5^
${c1}75${c2}GGPPPPPP555555YJ?77??YYYYYY55PPGGB#${c3}&B?
${c2}~!!7JY5PGGBBBBBBBBGGGGGGGBGGGGGP5YJ?7~~~
.::^~7?JYPGBB#BGPYJ?7!7^:.
..:^...
+18
View File
@@ -0,0 +1,18 @@
-
*%:
:%%%#
=%%%%%-
*%%%%%%#
:#%%%%%%%#.
-%%%%%%%%+
*%%%%%%%%- :
.#%%%%%%%#. *%=
-%%%%%%%%+ :#%%%*
+%%%%%%%%- =%%%%%%#.
.#%%%%%%%#. *%%%%%%%%:
-%%%%%%%%* :#%%%%%%%#.
+%%%%%%%%- =%%%%%%%%+ :%*.
.#%%%%%%%#: *%%%%%%%%- +%%%%*:
:%%%%%%%%* :#%%%%%%%#. .*%%%%%%%*
+%%%%%%%%= -%%%%%%%%+ :%%%%%%%%*
.#%%%%%%%%: *%%%%%%%%- =%%%%%%%%=
+7
View File
@@ -0,0 +1,7 @@
-:
+%*
.#%%+
-%%%: +=
+%%#..#%%-
.#%%+ -%%%- +=
-%%%- +%%#..#%%+
-1
View File
@@ -1,4 +1,3 @@
'
.^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.^^^^^.
:777777777777777777777777777777^~7777:
.~~~~~~~~~~~~~~~~~~~~~^~7777!:!777!.
+68
View File
@@ -524,6 +524,15 @@ static const FFlogo A[] = {
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_WHITE,
},
// Azos
{
.names = {"Azos"},
.lines = FASTFETCH_DATATEXT_LOGO_AZOS,
.colors = {
FF_COLOR_FG_CYAN,
FF_COLOR_FG_RED,
}
},
// LAST
{},
};
@@ -574,6 +583,16 @@ static const FFlogo B[] = {
.colorKeys = FF_COLOR_FG_LIGHT_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// BlackMesa
{
.names = {"BlackMesa", "black-mesa"},
.lines = FASTFETCH_DATATEXT_LOGO_BLACKMESA,
.colors = {
FF_COLOR_FG_BLACK,
},
.colorKeys = FF_COLOR_FG_BLACK,
.colorTitle = FF_COLOR_FG_WHITE,
},
// BlackPanther
{
.names = {"BlackPanther"},
@@ -1034,6 +1053,16 @@ static const FFlogo C[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_CYAN,
},
// cycledream
{
.names = {"cycledream"},
.lines = FASTFETCH_DATATEXT_LOGO_CYCLEDREAM,
.colors = {
FF_COLOR_FG_MAGENTA,
},
.colorKeys = FF_COLOR_FG_MAGENTA,
.colorTitle = FF_COLOR_FG_MAGENTA,
},
// LAST
{},
};
@@ -1320,6 +1349,16 @@ static const FFlogo E[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_WHITE,
},
// evolinx
{
.names = {"Evolinx"},
.lines = FASTFETCH_DATATEXT_LOGO_EVOLINX,
.colors = {
FF_COLOR_FG_BLUE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// EvolutionOS
{
.names = {"EvolutionOS"},
@@ -1828,6 +1867,18 @@ static const FFlogo I[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_CYAN,
},
// Interix
{
.names = {"Interix"},
.lines = FASTFETCH_DATATEXT_LOGO_INTERIX,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_BLUE,
FF_COLOR_FG_BLACK,
FF_COLOR_FG_YELLOW,
},
},
// IRIX
{
.names = {"IRIX"},
@@ -2256,6 +2307,23 @@ static const FFlogo M[] = {
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_GREEN,
},
// MainsailOS
{
.names = {"MainsailOS"},
.lines = FASTFETCH_DATATEXT_LOGO_MAINSAILOS,
.colors = {
FF_COLOR_FG_RED,
},
},
// MainsailOSSmall
{
.names = {"MainsailOS_small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_MAINSAILOS_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
},
// Mageia
{
.names = {"Mageia"},
+1 -1
View File
@@ -14,7 +14,7 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex
FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData)
{
FF_LIBRARY_LOAD(imageMagick, &instance.config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
return ffLogoPrintImageImpl(requestData, &(FFIMData) {
+1 -1
View File
@@ -14,7 +14,7 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex
FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData)
{
FF_LIBRARY_LOAD(imageMagick, &instance.config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR,
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR,
"libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11,
"libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11,
"libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, -1 // Required for Windows
+5 -5
View File
@@ -37,7 +37,7 @@ static FFstrbuf base64Encode(const FFstrbuf* in)
static bool printImageIterm(void)
{
const FFLogoOptions* options = &instance.config.logo;
const FFOptionsLogo* options = &instance.config.logo;
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
if(!ffAppendFileBuffer(options->source.chars, &buf))
{
@@ -118,7 +118,7 @@ static bool printImageIterm(void)
static bool printImageKittyDirect(void)
{
const FFLogoOptions* options = &instance.config.logo;
const FFOptionsLogo* options = &instance.config.logo;
FF_STRBUF_AUTO_DESTROY base64 = base64Encode(&options->source);
if (!options->width || !options->height)
@@ -222,7 +222,7 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso
static bool compressBlob(void** blob, size_t* length)
{
FF_LIBRARY_LOAD(zlib, &instance.config.libZ, false, "libz" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD(zlib, &instance.config.library.libZ, false, "libz" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL(zlib, compressBound, false)
FF_LIBRARY_LOAD_SYMBOL(zlib, compress2, false)
@@ -296,7 +296,7 @@ static void writeCacheUint32(FFLogoRequestData* requestData, uint32_t value, con
static void printImagePixels(FFLogoRequestData* requestData, const FFstrbuf* result, const char* cacheFileName)
{
const FFLogoOptions* options = &instance.config.logo;
const FFOptionsLogo* options = &instance.config.logo;
//Calculate character dimensions
instance.state.logoWidth = requestData->logoCharacterWidth + options->paddingLeft + options->paddingRight;
instance.state.logoHeight = requestData->logoCharacterHeight + options->paddingTop - 1;
@@ -398,7 +398,7 @@ static bool printImageKitty(FFLogoRequestData* requestData, const ImageData* ima
#include <chafa.h>
static bool printImageChafa(FFLogoRequestData* requestData, const ImageData* imageData)
{
FF_LIBRARY_LOAD(chafa, &instance.config.libChafa, false,
FF_LIBRARY_LOAD(chafa, &instance.config.library.libChafa, false,
"libchafa" FF_LIBRARY_EXTENSION, 1,
"libchafa-0" FF_LIBRARY_EXTENSION, -1 // Required for Windows
)
+15 -15
View File
@@ -18,7 +18,7 @@ typedef enum FFLogoSize
static void ffLogoPrintCharsRaw(const char* data, size_t length)
{
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
if (!options->width || !options->height)
@@ -55,13 +55,13 @@ static void ffLogoPrintCharsRaw(const char* data, size_t length)
void ffLogoPrintChars(const char* data, bool doColorReplacement)
{
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
uint32_t currentlineLength = 0;
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(2048);
if (instance.config.brightColor)
if (instance.config.display.brightColor)
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_BOLT);
ffStrbufAppendNC(&result, options->paddingTop, '\n');
@@ -212,11 +212,11 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
static void logoApplyColors(const FFlogo* logo)
{
if(instance.config.colorTitle.length == 0)
ffStrbufAppendS(&instance.config.colorTitle, logo->colorTitle ? logo->colorTitle : logo->colors[0]);
if(instance.config.display.colorTitle.length == 0)
ffStrbufAppendS(&instance.config.display.colorTitle, logo->colorTitle ? logo->colorTitle : logo->colors[0]);
if(instance.config.colorKeys.length == 0)
ffStrbufAppendS(&instance.config.colorKeys, logo->colorKeys ? logo->colorKeys : logo->colors[1]);
if(instance.config.display.colorKeys.length == 0)
ffStrbufAppendS(&instance.config.display.colorKeys, logo->colorKeys ? logo->colorKeys : logo->colors[1]);
}
static bool logoHasName(const FFlogo* logo, const FFstrbuf* name, bool small)
@@ -301,7 +301,7 @@ static void logoPrintStruct(const FFlogo* logo)
{
logoApplyColors(logo);
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
const char* const* colors = logo->colors;
for(int i = 0; *colors != NULL && i < FASTFETCH_LOGO_MAX_COLORS; i++, colors++)
@@ -344,7 +344,7 @@ static inline void logoPrintDetected(FFLogoSize size)
static bool logoPrintData(bool doColorReplacement)
{
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
if(options->source.length == 0)
return false;
@@ -355,7 +355,7 @@ static bool logoPrintData(bool doColorReplacement)
static void updateLogoPath(void)
{
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
if(ffPathExists(options->source.chars, FF_PATHTYPE_FILE))
return;
@@ -384,7 +384,7 @@ static void updateLogoPath(void)
static bool logoPrintFileIfExists(bool doColorReplacement, bool raw)
{
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
@@ -417,7 +417,7 @@ static bool logoPrintImageIfExists(FFLogoType logo, bool printError)
static bool logoTryKnownType(void)
{
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
if(options->type == FF_LOGO_TYPE_NONE)
{
@@ -462,14 +462,14 @@ void ffLogoPrint(void)
//In pipe mode, we don't have a logo or padding.
//We also don't need to set main color, because it won't be printed anyway.
//So we can return quickly here.
if(instance.config.pipe || instance.state.resultDoc)
if(instance.config.display.pipe || instance.state.resultDoc)
{
instance.state.logoHeight = 0;
instance.state.logoWidth = 0;
return;
}
const FFLogoOptions* options = &instance.config.logo;
const FFOptionsLogo* options = &instance.config.logo;
if (options->type == FF_LOGO_TYPE_NONE)
{
@@ -535,7 +535,7 @@ void ffLogoPrintRemaining(void)
void ffLogoBuiltinPrint(void)
{
FFLogoOptions* options = &instance.config.logo;
FFOptionsLogo* options = &instance.config.logo;
for(uint8_t ch = 0; ch < 26; ++ch)
{
-6
View File
@@ -32,10 +32,4 @@ extern const FFlogo ffLogoUnknown;
//image/image.c
bool ffLogoPrintImageIfExists(FFLogoType type, bool printError);
//option.c
void ffInitLogoOptions(FFLogoOptions* options);
bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const char* value);
void ffDestroyLogoOptions(FFLogoOptions* options);
const char* ffParseLogoJsonConfig();
#endif

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