Compare commits

...

75 Commits

Author SHA1 Message Date
Carter Li 33953a0d18 Merge pull request #583 from fastfetch-cli/dev
Release v2.1.1
2023-10-14 06:08:00 -05:00
李通洲 98e8e599a6 Release v2.1.1 2023-10-14 18:24:58 +08:00
李通洲 5e19838713 Doc: update changelog 2023-10-14 18:19:10 +08:00
李通洲 501803c873 Logo (Builtin): add Xenia
https://github.com/hykilpikonna/hyfetch/issues/197
2023-10-14 18:15:04 +08:00
李通洲 e9c2a43de1 Brightness: add --brightness-ddcci-sleep to set the sleep times (in ms) when sending DDC/CI requests
Fix #580
2023-10-14 10:04:08 +08:00
李通洲 af94596202 Revert "Brightness (Linux): allow specifying busno for ddcutil"
This doesn't seem to improve much performance, but increase code
complexity a lot

This reverts commit 42e87b498c.
2023-10-14 09:35:40 +08:00
李通洲 42e87b498c Brightness (Linux): allow specifying busno for ddcutil
Ref: #580
2023-10-14 01:38:02 +08:00
李通洲 839ff311de Wifi (macOS): work around #581 2023-10-13 16:47:45 +08:00
李通洲 ebab281471 Processes (Linux): fix implementation
`sysinfo.procs` reports number of all running threads, instead of processes
2023-10-11 21:10:47 +08:00
李通洲 582788645d Doc: add information about how to make Termux API actually work 2023-10-11 16:32:20 +08:00
李通洲 643fed7d1c Doc: metion bug #581 2023-10-11 16:31:47 +08:00
李通洲 076324e60e Wifi (macOS): remove undesired code 2023-10-11 15:23:21 +08:00
李通洲 1fe92738d8 macOS: embed Info.plist 2023-10-11 15:17:14 +08:00
李通洲 e319be19de Wifi (macOS): print <unknown ssid> when we can't get SSID
SSID is not available after Sonoma. According to the doc: SSID information is not available unless Location Services is enabled and the user has authorized the calling app to use location services.
2023-10-11 14:48:48 +08:00
李通洲 ab8448ee47 DiskIO (Windows): fix device name detection 2023-10-10 21:51:15 +08:00
李通洲 5493f418ed Users: fix crashing on Windows; rename tty to more common name sessionName 2023-10-10 20:21:11 +08:00
李通洲 4e75fa958d Logo (Builtin): add EndeavourSmall
Ref: https://github.com/dylanaraps/neofetch/pull/2391
2023-10-10 19:21:05 +08:00
李通洲 0847432dd9 CPUUsage: rename cpuusage-display-type to separate 2023-10-10 19:02:42 +08:00
李通洲 e297144fe2 CPUUsage: fix multi core data detection 2023-10-10 18:46:59 +08:00
李通洲 42cf88be9d CPUUsage: support display value per core 2023-10-10 16:24:44 +08:00
李通洲 6b008ed93b CPUUsage (FreeBSD): count cpu cores separately 2023-10-10 13:56:19 +08:00
李通洲 c96d21c7c0 CPUUsage (Linux): count cpu cores separately 2023-10-10 13:41:08 +08:00
李通洲 2feb53149a Revert "CpuUsage (apple): simplify implementation"
This reverts commit cabd36d078.
2023-10-10 13:41:08 +08:00
李通洲 e7df94495c Temp (FreeBSD): improve CPU temp detection 2023-10-10 13:41:08 +08:00
李通洲 42f6d029b0 Doc: update JSON schema; make it more IDE friendly 2023-10-09 20:27:40 +08:00
李通洲 ccbb252466 DiskIO: update doc and json schema 2023-10-09 19:24:25 +08:00
李通洲 d16bdb30b9 DiskIO: update formatting help messages; update json keys 2023-10-09 16:40:47 +08:00
李通洲 8fa6aee571 Disk: move physicalType to module DiskIO
Physical type applies to physical disks, not partitions
2023-10-09 16:32:31 +08:00
李通洲 4194e56912 DiskIO (Windows): better name detection for Github Action 2023-10-09 15:39:34 +08:00
李通洲 a0343d6bf7 CI: run --format json 2023-10-09 14:56:28 +08:00
李通洲 44b417deca DiskIO (FreeBSD): skip /dev/pass* 2023-10-09 14:26:51 +08:00
李通洲 5ccd196ae4 DiskIO: print devPath 2023-10-09 14:24:29 +08:00
李通洲 b76d6e9faa DiskIO (FreeBSD): add support 2023-10-09 14:20:40 +08:00
李通洲 2d2e0ddc6d Libc (FreeBSD): detect FBSD version 2023-10-09 13:28:30 +08:00
李通洲 430da1578d Libc (macOS): detect libSystem version 2023-10-09 10:43:58 +08:00
李通洲 1188db9475 CMake: simplify musl version detection 2023-10-09 10:43:40 +08:00
李通洲 685676bd0f CMake: don't hardcode system arch 2023-10-09 09:05:11 +08:00
李通洲 fa46dce0e1 CMake: detect uclibc and musl version 2023-10-08 21:03:10 +08:00
李通洲 2e60f34cd8 DiskIO: add to presets/all 2023-10-08 21:02:48 +08:00
李通洲 dc50e24a29 Doc: update changelog and readme 2023-10-08 21:02:31 +08:00
Jami Kettunen 1f23e93951 Logo: add Chimera Linux
Ref: https://github.com/chimera-linux/cports/blob/master/contrib/neofetch/patches/chimera.patch
2023-10-08 19:26:11 +08:00
李通洲 8df6409cb1 DiskIO (Windows): better device name detection 2023-10-08 16:46:53 +08:00
李通洲 5c5c66d960 DiskIO: fix segfault... 2023-10-08 16:38:50 +08:00
李通洲 0b0e286b9c DiskIO: support --diskio-name-prefix 2023-10-08 16:30:09 +08:00
李通洲 b2130477ae DiskIO (macOS): add support 2023-10-08 16:29:53 +08:00
李通洲 085d0924db Brightness (Linux): try improving compatibility of ddcutil 2.0
ddcutil 2.0 increases SONAME version to `libddcutil.so.5`. More testing needed

Ref: #576
2023-10-08 10:34:01 +08:00
李通洲 78249bf4f7 CPU: add new option --cpu-freq-ndigits
Fix #578
2023-10-08 10:10:06 +08:00
李通洲 4c9d9f6223 TerminalFont (Linux): fix typo 2023-10-08 09:56:45 +08:00
李通洲 d7649d9f8f DiskIO: fix building 2023-10-08 09:51:51 +08:00
李通洲 49e2acd15e Printing: fix --help *-format 2023-10-08 09:51:51 +08:00
李通洲 e4a6bf17e4 Terminal: support kgx (gnome console)
Fix #577
2023-10-08 09:51:32 +08:00
李通洲 276e22f6b0 DiskIO: init module 2023-10-07 23:56:15 +08:00
李通洲 b1d63e03d8 NetIO: fix --help netio-format 2023-10-07 22:58:50 +08:00
李通洲 55f0f75c95 Packages (Linux): print opkg in JSON format 2023-10-07 17:26:57 +08:00
李通洲 fe4eb564e1 NetIO: add missing #pragma once 2023-10-07 16:12:37 +08:00
李通洲 90ea096ca3 macOS: don't keep variable matchDict 2023-10-07 15:51:05 +08:00
李通洲 3077f885d8 Sound (macOS): ignore input devices 2023-10-07 15:45:14 +08:00
李通洲 41551ef200 Sound: fix typo 2023-10-07 15:15:39 +08:00
李通洲 4c96d0453e TerminalShell (Linux): add ash as a known shell 2023-10-07 15:15:24 +08:00
李通洲 d7ef7bc078 Doc: update changelog 2023-10-07 15:14:16 +08:00
李通洲 c77a758741 Packages (Linux): support opkg
Fix #574
2023-10-07 14:02:16 +08:00
李通洲 12208b2c7c Global: improve support of --help *-format
Also fix some bugs found when refactoring
2023-10-07 13:40:40 +08:00
李通洲 23d2cc3fdc Version: print libc version used when compiling 2023-10-05 22:23:22 +08:00
Md Rasel Hossain 1dfa0315db Fix several --help command related issues (#572)
* Help: fix wrong output for irrelevant commands

* Help: fix `module-format` related issues

* Help: remove unnecessary code
2023-10-05 19:59:24 +08:00
李通洲 f78f97a726 Revert "DisplayServer (Linux): add debug log for #568"
This reverts commit 1a4eb25194.
2023-10-04 16:28:54 +08:00
Carter Li 9972c61bbe Sound (macOS): support non-controllable devices 2023-10-04 14:59:13 +08:00
Carter Li 8795d99f79 Brightness: add DDC/CI support for Intel
Doesn't work for me. Need more testing
2023-10-04 14:41:06 +08:00
Carter Li f8aafb7ce4 Monitor (macOS): better intel platform support 2023-10-04 00:30:35 +08:00
Carter Li 27581d92b5 Disk (macOS): detect physical type 2023-10-04 00:30:35 +08:00
Carter Li 4a89b92185 Disk: allow custiomize disk key with mountFrom 2023-10-04 00:30:35 +08:00
李通洲 1a4eb25194 DisplayServer (Linux): add debug log for #568 2023-10-04 00:30:35 +08:00
李通洲 3eb9acea2e Doc: update changelog 2023-10-03 17:04:08 +08:00
李通洲 be860064c5 Users (Windows): fix crashing caused by uninitialized strings 2023-10-03 17:01:57 +08:00
李通洲 1985552636 Disk (Windows): fix crashing on Windows 7 VM 2023-10-03 16:50:57 +08:00
李通洲 985264d485 Fastfetch: add Directx Headers to --list-features 2023-10-02 23:19:44 +08:00
192 changed files with 2654 additions and 989 deletions
+19 -3
View File
@@ -44,10 +44,13 @@ jobs:
run: ctest
- name: run fastfetch
run: ./fastfetch --stat --show-errors --no-buffer --load-config presets/all
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: ./flashfetch
run: time ./flashfetch
linux:
name: Linux
@@ -84,6 +87,9 @@ jobs:
- name: run fastfetch
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
@@ -136,6 +142,9 @@ jobs:
- name: run fastfetch
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
@@ -165,12 +174,13 @@ jobs:
uses: vmactions/freebsd-vm@v0
with:
prepare: |
pkg install -y cmake git pkgconf 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
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
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package
./fastfetch --list-features
time ./fastfetch -c presets/ci
time ./fastfetch -c presets/ci --format json
time ./flashfetch
ldd fastfetch
ctest
@@ -227,6 +237,9 @@ jobs:
- name: run fastfetch
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
@@ -291,6 +304,9 @@ jobs:
- name: run fastfetch
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
+23
View File
@@ -1,3 +1,26 @@
# 2.1.1
Features:
* Support opkg (Packages, Linux)
* Support GNOME Console terminal version and font detection (Terminal, Linux)
* Add `--cpu-freq-ndigits` to set number of digits for CPU frequency (CPU)
* New module to detect physical disk I/O usage (DiskIO)
* Add `--cpuusage-separate` to display CPU usage per CPU logical core
* Add `--brightness-ddcci-sleep` to set the sleep times (in ms) when sending DDC/CI requests (Brightness, #580)
Bugfixes:
* Fix possible crashes on Windows 7 (Disk, Windows)
* Fix possible crashes caused by uninitialized strings (Users, Windows)
* Improve support of `--help *-format` and several bugs are found and fixed
* Don't incorrectly print `No active sound devices found` when using a non-controllable sound device (Sound, macOS)
* Fix implementation processes counting (Processes, Linux)
* Work around a issue that SSID cannot be detected on macOS Sonoma (Wifi, macOS)
Logo:
* Add Chimera Linux
* Add EndeavourSmall
* Add Xenia
# 2.1.0
This release introduces a new output format: JSON result
+46 -1
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.0
VERSION 2.1.1
LANGUAGES C
DESCRIPTION "Fast system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -222,6 +222,9 @@ fastfetch_load_text(src/data/help_config.txt DATATEXT_HELP_CONFIG)
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
if(APPLE)
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
endif()
####################
# Ascii image data #
@@ -273,6 +276,7 @@ set(LIBFASTFETCH_SRC
src/detection/cpu/cpu.c
src/detection/cpuusage/cpuusage.c
src/detection/disk/disk.c
src/detection/diskio/diskio.c
src/detection/displayserver/displayserver.c
src/detection/font/font.c
src/detection/gpu/gpu.c
@@ -310,6 +314,7 @@ set(LIBFASTFETCH_SRC
src/modules/datetime/datetime.c
src/modules/de/de.c
src/modules/disk/disk.c
src/modules/diskio/diskio.c
src/modules/font/font.c
src/modules/gpu/gpu.c
src/modules/host/host.c
@@ -375,6 +380,7 @@ if(LINUX)
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/disk/disk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/wayland.c
src/detection/displayserver/linux/wmde.c
@@ -385,6 +391,7 @@ if(LINUX)
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/icons/icons_linux.c
src/detection/libc/libc_linux.c
src/detection/lm/lm_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_linux.c
@@ -428,11 +435,13 @@ elseif(ANDROID)
src/detection/cursor/cursor_nosupport.c
src/detection/cpuusage/cpuusage_linux.c
src/detection/disk/disk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/displayserver_android.c
src/detection/font/font_nosupport.c
src/detection/gpu/gpu_nosupport.c
src/detection/host/host_android.c
src/detection/icons/icons_nosupport.c
src/detection/libc/libc_android.c
src/detection/lm/lm_nosupport.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
@@ -477,6 +486,7 @@ elseif(BSD)
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/diskio/diskio_bsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/wayland.c
src/detection/displayserver/linux/wmde.c
@@ -488,6 +498,7 @@ elseif(BSD)
src/detection/host/host_bsd.c
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/libc/libc_bsd.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_bsd.c
src/detection/media/media_linux.c
@@ -531,12 +542,14 @@ elseif(APPLE)
src/detection/cpuusage/cpuusage_apple.c
src/detection/cursor/cursor_apple.m
src/detection/disk/disk_bsd.c
src/detection/diskio/diskio_apple.c
src/detection/displayserver/displayserver_apple.c
src/detection/font/font_apple.m
src/detection/gpu/gpu_apple.c
src/detection/host/host_apple.c
src/detection/lm/lm_nosupport.c
src/detection/icons/icons_nosupport.c
src/detection/libc/libc_apple.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_apple.c
src/detection/media/media_apple.m
@@ -580,11 +593,13 @@ elseif(WIN32)
src/detection/cpuusage/cpuusage_windows.c
src/detection/cursor/cursor_windows.c
src/detection/disk/disk_windows.c
src/detection/diskio/diskio_windows.c
src/detection/displayserver/displayserver_windows.c
src/detection/font/font_windows.c
src/detection/gpu/gpu_windows.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/libc/libc_windows.cpp
src/detection/lm/lm_nosupport.c
src/detection/localip/localip_windows.c
src/detection/gamepad/gamepad_windows.c
@@ -651,6 +666,28 @@ if(yyjson_FOUND)
target_link_libraries(libfastfetch PRIVATE yyjson)
endif()
if(LINUX AND EXISTS "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1")
execute_process(COMMAND "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1"
ERROR_VARIABLE LD_MUSL_RESULT)
if("${LD_MUSL_RESULT}" MATCHES "Version ([0-9]+\\.[0-9]+\\.[0-9]+)")
target_compile_definitions(libfastfetch PUBLIC FF_MUSL_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(APPLE AND EXISTS "/usr/bin/otool")
execute_process(COMMAND /usr/bin/otool -L /usr/bin/otool
OUTPUT_VARIABLE OTOOL_OTOOL_RESULT)
if("${OTOOL_OTOOL_RESULT}" MATCHES "libSystem\\.B\\.dylib \\(.*current version ([0-9]+\\.[0-9]+\\.[0-9]+)\\)")
target_compile_definitions(libfastfetch PUBLIC FF_LIBSYSTEM_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(BSD AND EXISTS "/usr/local/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[^ )]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)")
target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1)
if(WIN32)
target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1)
@@ -856,6 +893,7 @@ elseif(BSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "usbhid"
PRIVATE "devstat"
)
elseif(ANDROID)
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
@@ -922,6 +960,13 @@ if(WIN32)
target_sources(flashfetch
PRIVATE src/util/windows/version.rc
)
elseif(APPLE)
target_link_options(fastfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
target_link_options(flashfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
endif()
###################
+5 -5
View File
@@ -98,7 +98,7 @@ For the image logo, WezTerm with iterm image protocol is known to work, surprisi
* [`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. Read [the official doc](https://wiki.termux.com/wiki/Termux:API) for detail or if you hang on these modules (IMPORTANT). [`termux-api`](https://github.com/termux/termux-packages/tree/master/packages/termux-api)
* [`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.
For the image logo, [Termux Monet](https://github.com/HardcodedCat/termux-monet) supports iterm image protocol.
@@ -108,21 +108,21 @@ All categories not listed here should work without needing a specific implementa
##### Available Modules
```
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, 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
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
```
##### Builtin logos
<!-- `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, 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, 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, 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, Xferience, YiffOS, Zorin
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 `fastfetch --print-logos` to print them
##### Package managers
```
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, opkg, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps
```
##### WM themes
@@ -137,7 +137,7 @@ Budgie, Cinnamon, Gnome, KDE Plasma, LXQt, Mate, XFCE4
##### Terminal fonts
```
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal, Yakuake
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
+228 -43
View File
@@ -545,6 +545,7 @@
"datetime",
"display",
"disk",
"diskio",
"de",
"font",
"gamepad",
@@ -595,7 +596,6 @@
],
"properties": {
"type": {
"title": "Module type",
"type": "string"
}
},
@@ -614,45 +614,151 @@
"title": "No additional properties",
"properties": {
"type": {
"enum": [
"bios",
"board",
"brightness",
"chassis",
"cpuusage",
"cursor",
"datetime",
"de",
"font",
"gamepad",
"host",
"icons",
"kernel",
"lm",
"locale",
"media",
"memory",
"monitor",
"opencl",
"os",
"packages",
"player",
"poweradapter",
"processes",
"shell",
"swap",
"terminal",
"terminalfont",
"terminalsize",
"theme",
"uptime",
"users",
"version",
"vulkan",
"wallpaper",
"wm",
"wifi",
"wmtheme"
"anyOf": [
{
"const": "bios",
"description": "Print BIOS name, version, release date, etc"
},
{
"const": "board",
"description": "Print mather board name and other info"
},
{
"const": "chassis",
"description": "Print chassis type (desktop, laptop, etc)"
},
{
"const": "cursor",
"description": "Print cursor style name"
},
{
"const": "datetime",
"description": "Print current date and time"
},
{
"const": "de",
"description": "Print desktop environment name"
},
{
"const": "font",
"description": "Print system font name"
},
{
"const": "gamepad",
"description": "List connected gamepads"
},
{
"const": "host",
"description": "Print product name of your computer"
},
{
"const": "icons",
"description": "Print icon style name"
},
{
"const": "kernel",
"description": "Print system kernel version"
},
{
"const": "lm",
"description": "Print login manager (desktop manager) name and version"
},
{
"const": "locale",
"description": "Print system locale name"
},
{
"const": "media",
"description": "Print playing song name"
},
{
"const": "memory",
"description": "Print system memory usage info"
},
{
"const": "monitor",
"description": "Print connected physical monitor information"
},
{
"const": "opencl",
"description": "Print highest OpenCL version supported by the GPU"
},
{
"const": "os",
"description": "Print operating system name and version"
},
{
"const": "packages",
"description": "List installed package managers and count of installed packages"
},
{
"const": "player",
"description": "Print music player name"
},
{
"const": "poweradapter",
"description": "Print power adapter name and charging watts"
},
{
"const": "processes",
"description": "Count running processes"
},
{
"const": "shell",
"description": "Print current shell name and version"
},
{
"const": "swap",
"description": "Print swap (paging file) space usage"
},
{
"const": "terminal",
"description": "Print current terminal name and version"
},
{
"const": "terminalfont",
"description": "Print font name and size used by current terminal"
},
{
"const": "terminalsize",
"description": "Print current terminal size"
},
{
"const": "theme",
"description": "Print current theme information"
},
{
"const": "uptime",
"description": "Print system uptime"
},
{
"const": "users",
"description": "List users currently logged in"
},
{
"const": "version",
"description": "Print Fastfetch version"
},
{
"const": "vulkan",
"description": "Print highest Vulkan version supported by the GPU"
},
{
"const": "wallpaper",
"description": "Print image file path of current wallpaper"
},
{
"const": "wm",
"description": "Print window manager name and version"
},
{
"const": "wifi",
"description": "Print connected Wi-Fi info (SSID, connection and security protocol)"
},
{
"const": "wmtheme",
"description": "Print current theme of window manager"
}
]
},
"key": {
@@ -674,7 +780,8 @@
"title": "Battery",
"properties": {
"type": {
"const": "battery"
"const": "battery",
"description": "Print battery capacity, status, etc"
},
"dir": {
"title": "The directory where the battery folders are. Standard: `/sys/class/power_supply/`. Linux only",
@@ -704,6 +811,7 @@
"title": "Bluetooth",
"properties": {
"type": {
"description": "List bluetooth devices",
"const": "bluetooth"
},
"showDisconnected": {
@@ -726,10 +834,27 @@
},
"additionalProperties": false
},
{
"title": "Brightness",
"properties": {
"type": {
"const": "brightness",
"description": "Print current brightness / luminance of your monitors"
},
"ddcciSleep": {
"type": "integer",
"description": "Set the sleep times (in ms) when sending DDC/CI requests.\nSee <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for detail",
"minimum": 0,
"maximum": 400,
"default": 10
}
}
},
{
"title": "CPU",
"properties": {
"type": {
"description": "Print CPU name, frequency, etc",
"const": "cpu"
},
"temp": {
@@ -737,6 +862,13 @@
"type": "boolean",
"default": false
},
"freqNdigits": {
"title": "Set the number of digits to keep after the decimal point when printing CPU frequency",
"type": "integer",
"minimum": 0,
"maximum": 9,
"default": 2
},
"key": {
"$ref": "#/$defs/key"
},
@@ -752,10 +884,25 @@
},
"additionalProperties": false
},
{
"title": "CPU Usage",
"properties": {
"type": {
"const": "cpuusage",
"description": "Print CPU usage. Costs some time to collect data"
},
"separate": {
"type": "boolean",
"description": "Display CPU usage per CPU logical core, instead of an average result",
"default": false
}
}
},
{
"title": "Colors",
"properties": {
"type": {
"description": "Print some colored blocks",
"const": "colors"
},
"symbol": {
@@ -783,6 +930,7 @@
"title": "Command",
"properties": {
"type": {
"description": "Running custom shell scripts",
"const": "command"
},
"shell": {
@@ -810,9 +958,9 @@
},
{
"title": "Custom",
"description": "Print a custom string, with or without key",
"properties": {
"type": {
"description": "Print a custom string, with or without key",
"const": "custom"
},
"key": {
@@ -839,6 +987,7 @@
"title": "Display",
"properties": {
"type": {
"description": "Print resolutions, refresh rates, etc",
"const": "display"
},
"compactType": {
@@ -874,6 +1023,7 @@
"title": "Disk",
"properties": {
"type": {
"description": "Print partitions, space usage, disk type, etc",
"const": "disk"
},
"folders": {
@@ -925,10 +1075,37 @@
},
"additionalProperties": false
},
{
"title": "DiskIO",
"properties": {
"type": {
"description": "Print physical disk I/O throughput",
"const": "diskio"
},
"namePrefix": {
"title": "Show disks with given name prefix only",
"type": "string"
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
},
"additionalProperties": false
},
{
"title": "GPU",
"properties": {
"type": {
"description": "Print GPU names, graphic memory size, type, etc",
"const": "gpu"
},
"temp": {
@@ -969,6 +1146,7 @@
"title": "Local IP",
"properties": {
"type": {
"description": "List local IP addresses (v4 or v6), MAC addresses, etc",
"const": "localip"
},
"showIpv4": {
@@ -1021,9 +1199,10 @@
"additionalProperties": false
},
{
"title": "Network throughput (usage)",
"title": "NetIO",
"properties": {
"type": {
"description": "Print network I/O throughput",
"const": "netio"
},
"namePrefix": {
@@ -1054,6 +1233,7 @@
"title": "OpenGL",
"properties": {
"type": {
"description": "Print highest OpenGL version supported by the GPU",
"const": "opengl"
},
"library": {
@@ -1085,6 +1265,7 @@
"title": "Public IP",
"properties": {
"type": {
"description": "Print your public IP address, etc",
"const": "publicip"
},
"url": {
@@ -1118,6 +1299,7 @@
"title": "Separator",
"properties": {
"type": {
"description": "Print a separator line",
"const": "separator"
},
"string": {
@@ -1132,6 +1314,7 @@
"title": "Sound",
"properties": {
"type": {
"description": "Print sound devices, volume, etc",
"const": "sound"
},
"soundType": {
@@ -1163,6 +1346,7 @@
"title": "Title",
"properties": {
"type": {
"description": "Print title, which contains your user name, hostname",
"const": "title"
},
"fqdn": {
@@ -1207,6 +1391,7 @@
"title": "Weather",
"properties": {
"type": {
"description": "Print weather information",
"const": "weather"
},
"location": {
+1 -1
View File
@@ -1 +1 @@
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:NetIO:Version:Break:Colors
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:NetIO:DiskIO:Version:Break:Colors
+1
View File
@@ -52,6 +52,7 @@
"gamepad",
"weather",
"netio",
"diskio",
"version",
"break",
"colors"
+3
View File
@@ -60,6 +60,9 @@ void ffPrepareCommandOption(FFdata* data)
if(ffStrbufContainIgnCaseS(&data->structure, FF_CPUUSAGE_MODULE_NAME))
ffPrepareCPUUsage();
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
ffPrepareDiskIO(&instance.config.diskIo);
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
ffPrepareNetIO(&instance.config.netIo);
+5
View File
@@ -93,6 +93,7 @@ static void defaultConfig(void)
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);
@@ -307,6 +308,7 @@ static void destroyConfig(void)
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);
@@ -469,6 +471,9 @@ void ffListFeatures(void)
#ifdef FF_HAVE_DDCUTIL
"libddcutil\n"
#endif
#ifdef FF_HAVE_DIRECTX_HEADERS
"Directx Headers\n"
#endif
""
, stdout);
}
+8
View File
@@ -112,6 +112,14 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
ffPrepareCPUUsage();
break;
}
case 'd': case 'D': {
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
{
if (module) ffParseDiskIOJsonObject(&cfg->diskIo, module);
ffPrepareDiskIO(&cfg->diskIo);
}
break;
}
case 'n': case 'N': {
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
{
+1
View File
@@ -30,6 +30,7 @@ static FFModuleBaseInfo* D[] = {
(void*) &instance.config.de,
(void*) &instance.config.display,
(void*) &instance.config.disk,
(void*) &instance.config.diskIo,
NULL,
};
+4 -1
View File
@@ -18,6 +18,7 @@ typedef struct FFModuleBaseInfo
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 (*printHelpFormat)(void);
} FFModuleBaseInfo;
static inline void ffOptionInitModuleBaseInfo(
@@ -26,7 +27,8 @@ 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* generateJson, // void (*const generateJson)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
void (*printHelpFormat)(void)
)
{
baseInfo->name = name;
@@ -34,6 +36,7 @@ static inline void ffOptionInitModuleBaseInfo(
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
baseInfo->generateJson = (__typeof__(baseInfo->generateJson)) generateJson;
baseInfo->printHelpFormat = printHelpFormat;
}
typedef struct FFModuleArgs
+15
View File
@@ -132,3 +132,18 @@ void ffPrintCharTimes(char c, uint32_t times)
if(remaining > 0)
fwrite(str, 1, remaining, stdout);
}
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[])
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(name);
ffStrbufLowerCase(&buffer);
printf("--%s-format:\n", buffer.chars);
printf("Sets the format string for %s output.\n", name);
puts("To see how a format string is constructed, take a look at \"fastfetch --help format\".");
puts("The following values are passed:");
for(unsigned i = 0; i < numArgs; i++)
printf(" {%u}: %s\n", i + 1, args[i]);
printf("The default is something similar to \"%s\".\n", def);
}
+2
View File
@@ -25,4 +25,6 @@ FF_C_PRINTF(4, 5) void ffPrintError(const char* moduleName, uint8_t moduleIndex,
void ffPrintColor(const FFstrbuf* colorValue);
void ffPrintCharTimes(char c, uint32_t times);
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
#endif
+10 -6
View File
@@ -132,17 +132,21 @@ Module specific options:
--disk-show-readonly <?value>: Set if read only volumes should be printed. Default is false
--disk-show-unknown <?value>: Set if unknown (unable to detect sizes) volumes should be printed. Default is false
--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
--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/
--cpu-temp <?value>: Detect and display CPU temperature if supported. Default is false
--gpu-temp <?value>: Detect and display GPU temperature if supported. 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
--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
--gpu-temp <?value>: Detect and display GPU temperature if supported. 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
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
--localip-show-ipv4 <?value>: Show IPv4 addresses in local ip module. Default is true
--localip-show-ipv6 <?value>: Show IPv6 addresses in local ip module. Default is false
--localip-show-mac <?value>: Show mac addresses in local ip module. Default is false
@@ -150,8 +154,8 @@ Module specific options:
--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-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-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
--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 `+`).
+1 -5
View File
@@ -17,12 +17,8 @@ static double detectBatteryTemp(void)
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
{
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
if (matchDict == NULL)
return "IOServiceMatching(\"AppleSmartBattery\") failed";
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleSmartBattery"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
+1 -1
View File
@@ -12,6 +12,6 @@ typedef struct FFBrightnessResult
double min, max, current;
} FFBrightnessResult;
const char* ffDetectBrightness(FFlist* result); // list of FFBrightnessResult
const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result); // list of FFBrightnessResult
#endif
+90 -12
View File
@@ -1,9 +1,27 @@
#include "brightness.h"
#include "detection/displayserver/displayserver.h"
#include "util/apple/cf_helpers.h"
#include "util/apple/ddcci.h"
#include "util/edidHelper.h"
#include <CoreGraphics/CoreGraphics.h>
// DDC/CI
#ifdef __aarch64__
typedef CFTypeRef IOAVServiceRef;
extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import));
extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import));
extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import));
extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import));
extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import));
#else
// DDC/CI (Intel)
#include <IOKit/IOKitLib.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <IOKit/i2c/IOI2CInterface.h>
extern void CGSServiceForDisplayNumber(CGDirectDisplayID display, io_service_t* service) __attribute__((weak_import));
#endif
// ACPI
extern int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness) __attribute__((weak_import));
// Works for internal display
@@ -31,19 +49,16 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
return NULL;
}
#ifdef __aarch64__
// https://github.com/waydabber/m1ddc
// Works for Apple Silicon and USB-C adapter connection ( but not HTMI )
FF_MAYBE_UNUSED static const char* detectWithDdcci(FFlist* result)
static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
{
if (!IOAVServiceCreate || !IOAVServiceReadI2C)
return "IOAVService is not available";
CFMutableDictionaryRef matchDict = IOServiceMatching("DCPAVServiceProxy");
if (matchDict == NULL)
return "IOServiceMatching(\"DCPAVServiceProxy\") failed";
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("DCPAVServiceProxy"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
FF_STRBUF_AUTO_DESTROY location = ffStrbufCreate();
@@ -78,7 +93,7 @@ FF_MAYBE_UNUSED static const char* detectWithDdcci(FFlist* result)
for (uint32_t i = 0; i < 2; ++i)
{
IOAVServiceWriteI2C(service, 0x37, 0x51, i2cIn, sizeof(i2cIn));
usleep(10000);
usleep(options->ddcciSleep * 1000);
}
}
@@ -105,17 +120,80 @@ FF_MAYBE_UNUSED static const char* detectWithDdcci(FFlist* result)
return NULL;
}
#else
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
{
if (!CGSServiceForDisplayNumber) return "CGSServiceForDisplayNumber is not available";
const char* ffDetectBrightness(FFlist* result)
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
{
if (display->type == FF_DISPLAY_TYPE_EXTERNAL)
{
io_service_t framebuffer = 0;
CGSServiceForDisplayNumber((CGDirectDisplayID)display->id, &framebuffer);
if (framebuffer == 0) continue;
IOItemCount count;
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0) continue;
io_service_t interface = 0;
if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue;
uint8_t i2cOut[12] = {};
IOI2CConnectRef connect;
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
{
IOObjectRelease(interface);
continue;
}
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
IOI2CRequest request = {
.commFlags = kNilOptions,
.sendAddress = 0x6e,
.sendTransactionType = kIOI2CSimpleTransactionType,
.sendBuffer = (vm_address_t) i2cIn,
.sendBytes = sizeof(i2cIn) / sizeof(i2cIn[0]),
.minReplyDelay = options->ddcciSleep,
.replyAddress = 0x6F,
.replySubAddress = 0x51,
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
.replyBytes = sizeof(i2cOut) / sizeof(i2cOut[0]),
.replyBuffer = (vm_address_t) i2cOut,
};
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
IOI2CInterfaceClose(connect, kNilOptions);
IOObjectRelease(interface);
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess) continue;
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9];
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInitCopy(&brightness->name, &display->name);
}
}
return NULL;
}
#endif
const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result)
{
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
detectWithDisplayServices(displayServer, result);
#ifdef __aarch64__
if (displayServer->displays.length > result->length)
detectWithDdcci(result);
#endif
detectWithDdcci(displayServer, options, result);
return NULL;
}
+2 -2
View File
@@ -9,7 +9,7 @@
#include <sys/fcntl.h>
#include <unistd.h>
const char* ffDetectBrightness(FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
// https://man.freebsd.org/cgi/man.cgi?query=backlight&sektion=9
char path[] = "/dev/backlight/backlight0";
@@ -42,7 +42,7 @@ const char* ffDetectBrightness(FFlist* result)
#else
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FF_MAYBE_UNUSED FFlist* result)
{
return "Backlight is supported only on FreeBSD 13 and newer";
}
+7 -4
View File
@@ -92,16 +92,19 @@ static const char* detectWithBacklight(FFlist* result)
#include <ddcutil_c_api.h>
static const char* detectWithDdcci(FFlist* result)
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
{
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD(libddcutil, &instance.config.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)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_any_vcp_value)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_close_display)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_set_default_sleep_multiplier)
libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330
ffddca_set_default_sleep_multiplier(options->ddcciSleep / 40.0);
FF_AUTO_FREE DDCA_Display_Info_List* infoList = NULL;
if (__builtin_expect(ffddca_get_display_info_list2(false, &infoList) < 0, 0))
return "ddca_get_display_info_list2(false, &infoList) failed";
@@ -137,14 +140,14 @@ static const char* detectWithDdcci(FFlist* result)
}
#endif
const char* ffDetectBrightness(FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
detectWithBacklight(result);
#ifdef FF_HAVE_DDCUTIL
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
if (result->length < displayServer->displays.length)
detectWithDdcci(result);
detectWithDdcci(options, result);
#endif
return NULL;
@@ -1,6 +1,6 @@
#include "brightness.h"
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FF_MAYBE_UNUSED FFlist* result)
{
return "Not supported on this platform";
}
@@ -73,7 +73,7 @@ static bool hasBuiltinDisplay(const FFDisplayServerResult* displayServer)
}
extern "C"
const char* ffDetectBrightness(FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
+1 -5
View File
@@ -29,12 +29,8 @@ static const char* detectFrequency(FFCPUResult* cpu)
{
// https://github.com/giampaolo/psutil/pull/2222/files
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleARMIODevice");
if (matchDict == NULL)
return "IOServiceMatching(\"AppleARMIODevice\") failed";
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleARMIODevice"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
+4 -1
View File
@@ -16,7 +16,10 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
ffDetectThermalTemp(&cpu->temperature);
{
if (!ffDetectCpuTemp(&cpu->temperature))
ffDetectThermalTemp(&cpu->temperature);
}
return NULL;
}
+35 -23
View File
@@ -4,42 +4,54 @@
#include <stdint.h>
// We need to use uint64_t because sizeof(long) == 4 on Windows
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll);
static uint64_t inUseAll1, totalAll1;
static FFlist cpuTimes1;
void ffPrepareCPUUsage(void)
{
ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
assert(cpuTimes1.elementSize == 0);
ffListInit(&cpuTimes1, sizeof(FFCpuUsageInfo));
ffGetCpuUsageInfo(&cpuTimes1);
}
const char* ffGetCpuUsageResult(double* result)
const char* ffGetCpuUsageResult(FFlist* result)
{
const char* error = NULL;
if(inUseAll1 == 0 && totalAll1 == 0)
if(cpuTimes1.elementSize == 0)
{
error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
if(error)
return error;
ffListInit(&cpuTimes1, sizeof(FFCpuUsageInfo));
error = ffGetCpuUsageInfo(&cpuTimes1);
if(error) return error;
ffTimeSleep(200);
}
while(true)
{
uint64_t inUseAll2, totalAll2;
error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2);
if(error)
return error;
if(cpuTimes1.length == 0) return "No CPU cores found";
if(inUseAll2 != inUseAll1)
FF_LIST_AUTO_DESTROY cpuTimes2 = ffListCreate(sizeof(FFCpuUsageInfo));
retry:
error = ffGetCpuUsageInfo(&cpuTimes2);
if(error) return error;
if(cpuTimes1.length != cpuTimes2.length) return "Unexpected CPU usage result";
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
if (cpuTime2->totalAll <= cpuTime1->totalAll)
{
*result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100;
inUseAll1 = inUseAll2;
totalAll1 = totalAll2;
return NULL;
}
else
ffListClear(&cpuTimes2);
ffTimeSleep(200);
goto retry;
}
}
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
*(double*) ffListAdd(result) = (double)(cpuTime2->inUseAll - cpuTime1->inUseAll) / (double)(cpuTime2->totalAll - cpuTime1->totalAll) * 100;
cpuTime1->inUseAll = cpuTime2->inUseAll;
cpuTime1->totalAll = cpuTime2->totalAll;
}
return NULL;
}
+9 -1
View File
@@ -3,6 +3,14 @@
#ifndef FF_INCLUDED_detection_cpuusage_cpuusage
#define FF_INCLUDED_detection_cpuusage_cpuusage
const char* ffGetCpuUsageResult(double* result);
#include "fastfetch.h"
typedef struct FFCpuUsageInfo {
uint64_t inUseAll;
uint64_t totalAll;
} FFCpuUsageInfo;
const char* ffGetCpuUsageInfo(FFlist* cpuTimes);
const char* ffGetCpuUsageResult(FFlist* result); // list of double
#endif
+20 -11
View File
@@ -4,20 +4,29 @@
#include <mach/processor_info.h>
#include <mach/mach_host.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
host_cpu_load_info_data_t cpustats;
mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
natural_t numCPUs = 0U;
processor_info_array_t cpuInfo;
mach_msg_type_number_t numCpuInfo;
*inUseAll = *totalAll = 0;
if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUs, &cpuInfo, &numCpuInfo) != KERN_SUCCESS)
return "host_processor_info() failed";
if (numCPUs * CPU_STATE_MAX != numCpuInfo)
return "Unexpected host_processor_info() result";
if (host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)(&cpustats), &count) != KERN_SUCCESS)
return "host_statistics() failed";
*inUseAll = cpustats.cpu_ticks[CPU_STATE_USER]
+ cpustats.cpu_ticks[CPU_STATE_SYSTEM]
+ cpustats.cpu_ticks[CPU_STATE_NICE];
*totalAll = *inUseAll + cpustats.cpu_ticks[CPU_STATE_IDLE];
for (natural_t i = 0U; i < numCPUs; ++i)
{
integer_t inUse = cpuInfo[CPU_STATE_MAX * i + CPU_STATE_USER]
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_SYSTEM]
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_NICE];
integer_t total = inUse + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_IDLE];
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
}
+26 -9
View File
@@ -1,19 +1,36 @@
#include "detection/cpuusage/cpuusage.h"
#include "util/mallocHelper.h"
#include <sys/types.h>
#include <sys/user.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
#include <stdlib.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
// interrupt processing, user processes, system processing, lock spinning, and idling
uint64_t cpTime[5];
size_t neededLength = sizeof(cpTime);
if(sysctlbyname("kern.cp_time", cpTime, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_time) failed";
size_t neededLength = 0;
if(sysctlbyname("kern.cp_times", NULL, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_times, NULL) failed";
*inUseAll = cpTime[0] + cpTime[1] + cpTime[2] + cpTime[3];
*totalAll = *inUseAll + cpTime[4];
uint32_t coreCount = neededLength / (CPUSTATES * (uint32_t) sizeof(uint64_t));
assert(coreCount > 0);
FF_AUTO_FREE uint64_t (*cpTimes)[CPUSTATES] = malloc(neededLength);
if(sysctlbyname("kern.cp_times", cpTimes, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_times, cpTime) failed";
for (uint32_t i = 0; i < coreCount; ++i)
{
uint64_t* cpTime = cpTimes[i];
uint64_t inUse = cpTime[CP_USER] + cpTime[CP_NICE] + cpTime[CP_SYS];
uint64_t total = cpTime[CP_INTR] + cpTime[CP_IDLE];
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
}
+16 -11
View File
@@ -1,14 +1,13 @@
#include "fastfetch.h"
#include "detection/cpuusage/cpuusage.h"
#include "common/io/io.h"
#include <stdio.h>
#include <inttypes.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
FILE* procStat = fopen("/proc/stat", "r");
FF_AUTO_CLOSE_FILE FILE* procStat = fopen("/proc/stat", "r");
if(procStat == NULL)
{
#ifdef __ANDROID__
@@ -17,16 +16,22 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
return "fopen(\"""/proc/stat\", \"r\") == NULL";
#endif
}
// Skip first line
if (fscanf(procStat, "cpu%*[^\n]\n") < 0)
return "fscanf() first line failed";
if (fscanf(procStat, "cpu%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0)
uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
while (fscanf(procStat, "cpu%*d%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%*[^\n]\n", &user, &nice, &system, &idle, &iowait, &irq, &softirq) == 7)
{
fclose(procStat);
return "fscanf() failed";
}
*inUseAll = user + nice + system;
*totalAll = *inUseAll + idle + iowait + irq + softirq;
uint64_t inUse = user + nice + system;
uint64_t total = inUse + idle + iowait + irq + softirq;
fclose(procStat);
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
}
+9 -6
View File
@@ -6,7 +6,7 @@
#include <ntstatus.h>
#include <winternl.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
ULONG size = 0;
if(NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
@@ -16,8 +16,6 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessorPerformanceInformation, pinfo, size, &size)))
return "NtQuerySystemInformation(SystemProcessorPerformanceInformation, size) failed";
*inUseAll = *totalAll = 0;
for (uint32_t i = 0; i < size / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); ++i)
{
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* coreInfo = pinfo + i;
@@ -28,9 +26,14 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
coreInfo->KernelTime.QuadPart -= coreInfo->IdleTime.QuadPart;
coreInfo->KernelTime.QuadPart += dpcTime + interruptTime;
LONGLONG inUse = coreInfo->UserTime.QuadPart + coreInfo->KernelTime.QuadPart;
*inUseAll += (uint64_t)inUse;
*totalAll += (uint64_t)(inUse + coreInfo->IdleTime.QuadPart);
uint64_t inUse = (uint64_t) (coreInfo->UserTime.QuadPart + coreInfo->KernelTime.QuadPart);
uint64_t total = inUse + (uint64_t)coreInfo->IdleTime.QuadPart;
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
-8
View File
@@ -5,13 +5,6 @@
#include "fastfetch.h"
typedef enum FFDiskPhysicalType
{
FF_DISK_PHYSICAL_TYPE_UNKNOWN,
FF_DISK_PHYSICAL_TYPE_HDD,
FF_DISK_PHYSICAL_TYPE_SSD,
} FFDiskPhysicalType;
typedef struct FFDisk
{
FFstrbuf mountFrom;
@@ -19,7 +12,6 @@ typedef struct FFDisk
FFstrbuf filesystem;
FFstrbuf name;
FFDiskVolumeType type;
FFDiskPhysicalType physicalType;
uint64_t bytesUsed;
uint64_t bytesFree;
+2 -1
View File
@@ -21,6 +21,8 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk)
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
}
#elif __APPLE__
#include "util/apple/cf_helpers.h"
#include <sys/attr.h>
#include <unistd.h>
@@ -71,7 +73,6 @@ const char* ffDetectDisksImpl(FFlist* disks)
#endif
FFDisk* disk = ffListAdd(disks);
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
disk->bytesTotal = fs->f_blocks * fs->f_bsize;
disk->bytesFree = (uint64_t)fs->f_bfree * fs->f_bsize;
+5 -17
View File
@@ -195,7 +195,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
return false;
}
static bool detectPhysicalTypeAndReturnRemovable(FFDisk* currentDisk)
static bool isRemovable(FFDisk* currentDisk)
{
// https://stackoverflow.com/a/73302025
// Note my USB mobile hard disk isn't detected as removable, but my USB flash disk does.
@@ -218,20 +218,10 @@ static bool detectPhysicalTypeAndReturnRemovable(FFDisk* currentDisk)
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
ffStrbufAppendS(&basePath, entry->d_name);
index = basePath.length;
// /sys/block/sdx/queue/rotational
ffStrbufAppendS(&basePath, "/queue/rotational");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffReadFileBuffer(basePath.chars, &buffer))
currentDisk->physicalType = ffStrbufEqualS(&buffer, "1") ? FF_DISK_PHYSICAL_TYPE_HDD : FF_DISK_PHYSICAL_TYPE_SSD;
else
currentDisk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
ffStrbufSubstrBefore(&basePath, index);
// /sys/block/sdx/removable
ffStrbufAppendS(&basePath, entry->d_name);
ffStrbufAppendS(&basePath, "/removable");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
}
@@ -240,10 +230,9 @@ static bool detectPhysicalTypeAndReturnRemovable(FFDisk* currentDisk)
static void detectType(const FFlist* disks, FFDisk* currentDisk)
{
bool isRemovable = detectPhysicalTypeAndReturnRemovable(currentDisk);
if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
if(isRemovable)
if(isRemovable(currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else if(isSubvolume(disks, currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
@@ -289,7 +278,6 @@ const char* ffDetectDisksImpl(FFlist* disks)
//We have a valid device, add it to the list
FFDisk* disk = ffListAdd(disks);
disk->type = FF_DISK_VOLUME_TYPE_NONE;
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
//detect mountFrom
ffStrbufInitS(&disk->mountFrom, device->mnt_fsname);
-29
View File
@@ -28,37 +28,8 @@ const char* ffDetectDisksImpl(FFlist* disks)
ffStrbufInitWS(&disk->mountpoint, mountpoint);
wchar_t volumeName[64];
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
if(mountpoint[1] == ':')
{
memcpy(volumeName, L"\\\\.\\ :", sizeof(L"\\\\.\\ :"));
volumeName[4] = mountpoint[0];
FF_AUTO_CLOSE_FD HANDLE handle = CreateFileW(volumeName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (handle != INVALID_HANDLE_VALUE)
{
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
if(DeviceIoControl(
handle,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceSeekPenaltyProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&dspd,
sizeof(dspd),
NULL,
NULL
))
disk->physicalType = dspd.IncursSeekPenalty ? FF_DISK_PHYSICAL_TYPE_HDD : FF_DISK_PHYSICAL_TYPE_SSD;
}
}
if(GetVolumeNameForVolumeMountPointW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
{
ffStrbufInitWS(&disk->mountFrom, volumeName);
}
else
ffStrbufInit(&disk->mountFrom);
+67
View File
@@ -0,0 +1,67 @@
#include "diskio.h"
#include "common/time.h"
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options);
static FFlist ioCounters1;
static uint64_t time1;
void ffPrepareDiskIO(FFDiskIOOptions* options)
{
ffListInit(&ioCounters1, sizeof(FFDiskIOResult));
ffDiskIOGetIoCounters(&ioCounters1, options);
time1 = ffTimeGetNow();
}
const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
{
const char* error = NULL;
if (time1 == 0)
{
ffListInit(&ioCounters1, sizeof(FFDiskIOResult));
error = ffDiskIOGetIoCounters(&ioCounters1, options);
if (error)
return error;
time1 = ffTimeGetNow();
}
if (ioCounters1.length == 0)
return "No physical disk found";
uint64_t time2 = ffTimeGetNow();
while (time2 - time1 < 1000)
{
ffTimeSleep((uint32_t) (1000 - (time2 - time1)));
time2 = ffTimeGetNow();
}
error = ffDiskIOGetIoCounters(result, options);
if (error)
return error;
if (result->length != ioCounters1.length)
return "Different number of physical disks. Hardware change?";
for (uint32_t i = 0; i < result->length; ++i)
{
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
if (!ffStrbufEqual(&icPrev->name, &icCurr->name))
return "Network interface name changed";
static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout");
for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t))
{
uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off);
uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off);
uint64_t temp = *currValue;
*currValue -= *prevValue;
*currValue /= (time2 - time1) / 1000 /* seconds */;
*prevValue = temp;
}
}
time1 = time2;
return NULL;
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "fastfetch.h"
typedef enum FFDiskIOPhysicalType
{
FF_DISKIO_PHYSICAL_TYPE_UNKNOWN,
FF_DISKIO_PHYSICAL_TYPE_HDD,
FF_DISKIO_PHYSICAL_TYPE_SSD,
} FFDiskIOPhysicalType;
typedef struct FFDiskIOResult
{
FFstrbuf name;
FFstrbuf interconnect;
FFDiskIOPhysicalType type;
FFstrbuf devPath;
uint64_t bytesRead;
uint64_t readCount;
uint64_t bytesWritten;
uint64_t writeCount;
} FFDiskIOResult;
const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options);
+89
View File
@@ -0,0 +1,89 @@
#include "diskio.h"
#include "util/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOBlockStorageDriver.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
static inline void wrapIoObjectRelease(io_service_t* service)
{
assert(service);
if (*service)
IOObjectRelease(*service);
}
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
while((registryEntry = IOIteratorNext(iterator)) != 0)
{
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
io_name_t deviceName;
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
continue;
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
continue;
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
continue;
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef statistics = IORegistryEntryCreateCFProperty(entryDriver, CFSTR(kIOBlockStorageDriverStatisticsKey), kCFAllocatorDefault, kNilOptions);
if (!statistics)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInit(&device->devPath);
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey), (int64_t*) &device->writeCount);
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
if (bsdName)
{
ffCfStrGetString(bsdName, &device->devPath);
ffStrbufPrependS(&device->devPath, "/dev/");
}
ffStrbufInit(&device->interconnect);
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
{
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (protocolCharacteristics)
ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->interconnect);
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (deviceCharacteristics)
{
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
if (mediumType)
{
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
device->type = FF_DISKIO_PHYSICAL_TYPE_SSD;
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
device->type = FF_DISKIO_PHYSICAL_TYPE_HDD;
}
}
}
}
return NULL;
}
+51
View File
@@ -0,0 +1,51 @@
#include "diskio.h"
#include <devstat.h>
#include <memory.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
if (devstat_checkversion(NULL) < 0)
return "devstat_checkversion() failed";
struct statinfo stats = {
.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)),
};
if (devstat_getdevs(NULL, &stats) < 0)
return "devstat_getdevs() failed";
for (int i = 0; i < stats.dinfo->numdevs; i++)
{
struct devstat* current = &stats.dinfo->devices[i];
if (current->device_type & DEVSTAT_TYPE_PASS)
continue;
char deviceName[128];
snprintf(deviceName, sizeof(deviceName), "%s%d", current->device_name, current->unit_number);
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInitF(&device->devPath, "/dev/%s", deviceName);
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
ffStrbufInit(&device->interconnect);
switch (current->device_type & DEVSTAT_TYPE_IF_MASK)
{
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
}
device->bytesRead = current->bytes[DEVSTAT_READ];
device->readCount = current->operations[DEVSTAT_READ];
device->bytesWritten = current->bytes[DEVSTAT_WRITE];
device->writeCount = current->operations[DEVSTAT_WRITE];
}
if (stats.dinfo->mem_ptr)
free(stats.dinfo->mem_ptr);
free(stats.dinfo);
return NULL;
}
+108
View File
@@ -0,0 +1,108 @@
#include "diskio.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <limits.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS("/dev/disk/by-id/");
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
return "opendir(batteryDir) == NULL";
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (entry->d_name[0] == '.')
continue;
char* part = strstr(entry->d_name, "-part");
if (part && isdigit(part[strlen("-part")]))
continue;
if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive indentifier
continue;
// Other exceptions?
ffStrbufAppendS(&baseDir, entry->d_name);
char pathDev[PATH_MAX];
ssize_t pathLen = readlink(baseDir.chars, pathDev, PATH_MAX);
ffStrbufSubstrBefore(&baseDir, baseDirLength);
if (pathLen < 0) continue;
pathDev[pathLen] = '\0'; // ../../nvme0n1
char pathDev1[PATH_MAX];
const char* devName = basename(pathDev);
snprintf(pathDev1, PATH_MAX, "/dev/%s", devName);
// Avoid duplicated disks
bool flag = false;
FF_LIST_FOR_EACH(FFDiskIOResult, disk, *result)
{
if (ffStrbufEqualS(&disk->devPath, pathDev1))
{
flag = true;
break;
}
}
if (flag) continue;
char pathSysBlock[PATH_MAX];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
FF_AUTO_CLOSE_FILE FILE* sysBlockStat = fopen(pathSysBlock, "r");
if (!sysBlockStat) continue;
// I/Os merges sectors ticks ...
uint64_t nRead, sectorRead, nWritten, sectorWritten;
if (fscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, &sectorRead, &nWritten, &sectorWritten) == 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
char* slash = strchr(entry->d_name, '-');
if (slash)
{
char* slash2 = strchr(slash + 1, '-');
if (slash2)
ffStrbufInitNS(&device->name, (uint32_t) (slash2 - slash - 1), slash + 1);
else
ffStrbufInitS(&device->name, slash + 1);
ffStrbufInitNS(&device->interconnect, (uint32_t) (slash - entry->d_name), entry->d_name);
}
else
{
ffStrbufInitS(&device->name, entry->d_name);
ffStrbufInit(&device->interconnect);
}
ffStrbufReplaceAllC(&device->name, '_', ' ');
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->interconnect);
result->length--;
continue;
}
ffStrbufInitS(&device->devPath, pathDev1);
device->bytesRead = sectorRead * 512;
device->bytesWritten = sectorWritten * 512;
device->readCount = nRead;
device->writeCount = nWritten;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffReadFileBuffer(pathSysBlock, &buffer))
device->type = ffStrbufEqualS(&buffer, "1") ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
}
return NULL;
}
+89
View File
@@ -0,0 +1,89 @@
#include "diskio.h"
#include "common/io/io.h"
#include "util/windows/registry.h"
#include "util/windows/unicode.h"
#include <winioctl.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_HKEY_AUTO_DESTROY hKey = NULL;
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", &hKey, NULL))
return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum\") failed";
uint32_t nDevices;
if (!ffRegReadUint(hKey, L"Count", &nDevices, NULL))
return "ffRegReadUint(hKey, L\"Count\", &nDevices) failed";
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
for (uint32_t idev = 0; idev <= nDevices; ++idev) {
_ultow(idev, pNum, 10);
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
continue;
DISK_PERFORMANCE diskPerformance;
DWORD ioctrlSize = sizeof(diskPerformance);
DWORD dwSize;
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL))
{
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInit(&device->name);
ffStrbufInit(&device->interconnect);
if (ffRegReadStrbuf(hKey, pNum, &device->name, NULL))
{
// SCSI\Disk&Ven_NVMe&Prod_WDC_PC_SN810_SDC\5&19cebb7&0&000000
uint32_t index = ffStrbufFirstIndexC(&device->name, '\\');
if (index != device->name.length)
{
ffStrbufAppendNS(&device->interconnect, index, device->name.chars); // SCSI
ffStrbufSubstrAfter(&device->name, index);
}
ffStrbufSubstrBeforeLastC(&device->name, '\\');
ffStrbufSubstrAfterFirstS(&device->name, "&Ven_");
ffStrbufRemoveS(&device->name, "&Prod");
ffStrbufReplaceAllC(&device->name, '_', ' ');
ffStrbufTrim(&device->name, ' ');
}
else
ffStrbufSetWS(&device->name, szDevice);
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->interconnect);
result->length--;
continue;
}
ffStrbufInitWS(&device->devPath, szDevice);
device->bytesRead = (uint64_t) diskPerformance.BytesRead.QuadPart;
device->readCount = (uint64_t) diskPerformance.ReadCount;
device->bytesWritten = (uint64_t) diskPerformance.BytesWritten.QuadPart;
device->writeCount = (uint64_t) diskPerformance.WriteCount;
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
DWORD retSize = 0;
if(DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceSeekPenaltyProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&dspd,
sizeof(dspd),
&retSize,
NULL
) && retSize == sizeof(dspd))
device->type = dspd.IncursSeekPenalty ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
}
}
return NULL;
}
+1 -2
View File
@@ -30,9 +30,8 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAcceleratorClassName);
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOAcceleratorClassName), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#ifndef FF_INCLUDED_detection_libc_libc
#define FF_INCLUDED_detection_libc_libc
#include "fastfetch.h"
typedef struct FFLibcResult
{
const char* name;
const char* version;
} FFLibcResult;
const char* ffDetectLibc(FFLibcResult* result);
#endif
+25
View File
@@ -0,0 +1,25 @@
#include "libc.h"
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
#include <features.h>
const char* ffDetectLibc(FFLibcResult* result)
{
#if __ANDROID_NDK__
result->name = "ndk-bionic";
result->version = FF_STR(__NDK_MAJOR__) "." FF_STR(__NDK_MINOR__) "." FF_STR(__NDK_BUILD__)
#if __NDK_BETA__
"-beta" FF_STR(__NDK_BETA__)
#elif __NDK_CANARY__
"-canary"
#endif
;
return NULL;
#else
return "Unknown Android libc";
#endif
}
+13
View File
@@ -0,0 +1,13 @@
#include "libc.h"
const char* ffDetectLibc(FFLibcResult* result)
{
result->name = "libSystem";
#ifdef FF_LIBSYSTEM_VERSION
result->version = FF_LIBSYSTEM_VERSION;
#else
result->version = NULL;
#endif
return NULL;
}
+13
View File
@@ -0,0 +1,13 @@
#include "libc.h"
const char* ffDetectLibc(FFLibcResult* result)
{
result->name = "FBSD";
#ifdef FF_FBSD_VERSION
result->version = FF_FBSD_VERSION;
#else
result->version = NULL;
#endif
return NULL;
}
+26
View File
@@ -0,0 +1,26 @@
#include "libc.h"
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
#include <features.h>
const char* ffDetectLibc(FFLibcResult* result)
{
#ifdef __UCLIBC__
result->name = "uClibc";
result->version = FF_STR(__UCLIBC_MAJOR__) "." FF_STR(__UCLIBC_MINOR__) "." FF_STR(__UCLIBC_SUBLEVEL__);
#elif defined(__GNU_LIBRARY__)
result->name = "glibc";
result->version = FF_STR(__GLIBC__) "." FF_STR(__GLIBC_MINOR__);
#else
result->name = "musl";
#ifdef FF_MUSL_VERSION
result->version = FF_MUSL_VERSION;
#else
result->version = NULL;
#endif
#endif
return NULL;
}
+65
View File
@@ -0,0 +1,65 @@
extern "C"
{
#include "libc.h"
}
#ifdef __MINGW32__
#include <_mingw.h>
#endif
template<uint32_t Major, uint32_t Minor>
class version_t {
constexpr static auto buflen() noexcept {
unsigned int len = 2; // "."
if (Major == 0)
len++;
else
for (auto n = Major; n; len++, n /= 10);
if (Minor == 0)
len++;
else
for (auto n = Minor; n; len++, n /= 10);
return len;
}
char buf[buflen()] = {};
public:
constexpr version_t() noexcept {
auto ptr = buf + buflen();
*--ptr = '\0';
if (Minor == 0) {
*--ptr = '0';
} else {
for (auto n = Minor; n; n /= 10)
*--ptr = "0123456789"[n % 10];
}
*--ptr = '.';
if (Major == 0) {
*--ptr = '0';
} else {
for (auto n = Major; n; n /= 10)
*--ptr = "0123456789"[n % 10];
}
}
constexpr operator const char *() const { return buf; }
};
template<uint32_t Major, uint32_t Minor>
constexpr version_t<Major, Minor> version;
extern "C"
const char* ffDetectLibc(FFLibcResult* result)
{
#ifdef _UCRT
result->name = "ucrt";
#else
result->name = "msvcrt";
#endif
result->version = version<(__MSVCRT_VERSION__ >> 8), (__MSVCRT_VERSION__ & 8)>;
return NULL;
}
+55 -113
View File
@@ -1,139 +1,81 @@
#include "monitor.h"
#include "detection/displayserver/displayserver.h"
#include "util/apple/cf_helpers.h"
#include "util/apple/ddcci.h"
#include "util/edidHelper.h"
#import <AppKit/NSScreen.h>
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
static const char* detectWithDisplayServices(const FFDisplayServerResult* displayServer, FFlist* results)
static bool detectHdrSupportWithNSScreen(FFDisplayResult* display)
{
if(!CoreDisplay_DisplayCreateInfoDictionary) return "CoreDisplay_DisplayCreateInfoDictionary is not available";
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
NSScreen* mainScreen = NSScreen.mainScreen;
if (display->primary)
return mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1;
else
{
if (display->type == FF_DISPLAY_TYPE_BUILTIN)
for (NSScreen* screen in NSScreen.screens)
{
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id);
if(displayInfo)
if (screen == mainScreen) continue;
NSNumber* screenNumber = [screen.deviceDescription valueForKey:@"NSScreenNumber"];
if (screenNumber && screenNumber.longValue == (long) display->id)
{
int width, height;
if (ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelWidth"), &width) || // Default resolution (limited by connectors, GPUs, etc.)
ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelHeight"), &height) ||
width <= 0 || height <= 0)
continue;
FFMonitorResult* monitor = (FFMonitorResult*) ffListAdd(results);
monitor->width = (uint32_t) width;
monitor->height = (uint32_t) height;
ffStrbufInitCopy(&monitor->name, &display->name);
CGSize size = CGDisplayScreenSize((CGDirectDisplayID) display->id);
monitor->physicalWidth = (uint32_t) (size.width + 0.5);
monitor->physicalHeight = (uint32_t) (size.height + 0.5);
monitor->hdrCompatible = false;
if (CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")))
monitor->hdrCompatible = true;
else
{
NSScreen* mainScreen = NSScreen.mainScreen;
if (display->primary)
monitor->hdrCompatible = mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1;
else
{
for (NSScreen* screen in NSScreen.screens)
{
if (screen == mainScreen) continue;
NSNumber* screenNumber = [screen.deviceDescription valueForKey:@"NSScreenNumber"];
if (screenNumber && screenNumber.longValue == (long) display->id)
{
monitor->hdrCompatible = screen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1;
break;
}
}
continue;
}
}
return screen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1;
}
}
}
return NULL;
}
static const char* detectWithDdcci(FFlist* results)
{
if (!IOAVServiceCreate || !IOAVServiceReadI2C)
return "IOAVService is not available";
CFMutableDictionaryRef matchDict = IOServiceMatching("DCPAVServiceProxy");
if (matchDict == NULL)
return "IOServiceMatching(\"DCPAVServiceProxy\") failed";
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
FF_STRBUF_AUTO_DESTROY location = ffStrbufCreate();
io_registry_entry_t registryEntry;
while((registryEntry = IOIteratorNext(iterator)) != 0)
{
CFMutableDictionaryRef properties;
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
{
IOObjectRelease(registryEntry);
continue;
}
ffStrbufClear(&location);
if(ffCfDictGetString(properties, CFSTR("Location"), &location) || ffStrbufEqualS(&location, "Embedded"))
{
// Builtin display should be handled by DisplayServices
IOObjectRelease(registryEntry);
continue;
}
FF_CFTYPE_AUTO_RELEASE IOAVServiceRef service = IOAVServiceCreateWithService(kCFAllocatorDefault, (io_service_t) registryEntry);
IOObjectRelease(registryEntry);
if (!service) continue;
FF_CFTYPE_AUTO_RELEASE CFDataRef edid = NULL;
if (IOAVServiceCopyEDID(service, &edid) != KERN_SUCCESS)
continue;
uint32_t edidLength = (uint32_t) CFDataGetLength(edid);
if (edidLength == 0 || edidLength % 128 != 0)
continue;
uint32_t width, height;
const uint8_t* edidData = CFDataGetBytePtr(edid);
ffEdidGetPhysicalResolution(edidData, &width, &height);
if (width == 0 || height == 0) continue;
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
display->width = width;
display->height = height;
ffStrbufInit(&display->name);
ffEdidGetName(edidData, &display->name);
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, edidLength);
}
return NULL;
return false;
}
const char* ffDetectMonitor(FFlist* results)
{
if(!CoreDisplay_DisplayCreateInfoDictionary) return "CoreDisplay_DisplayCreateInfoDictionary is not available";
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
detectWithDisplayServices(displayServer, results);
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
{
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id);
if(!displayInfo) continue;
uint8_t edidData[128] = {};
uint32_t edidLength = 0;
if (false || !ffCfDictGetData(displayInfo, CFSTR("IODisplayEDID"), 0, sizeof(edidData), edidData, &edidLength))
{
uint32_t width, height;
ffEdidGetPhysicalResolution(edidData, &width, &height);
if (width > 0 && height > 0)
{
FFMonitorResult* monitor = (FFMonitorResult*) ffListAdd(results);
ffStrbufInitCopy(&monitor->name, &display->name);
monitor->width = width;
monitor->height = height;
ffEdidGetPhysicalSize(edidData, &monitor->physicalWidth, &monitor->physicalHeight);
monitor->hdrCompatible = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) ||
detectHdrSupportWithNSScreen(display);
continue;
}
}
int width, height;
if (ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelWidth"), &width) || // Default resolution (limited by connectors, GPUs, etc.)
ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelHeight"), &height) ||
width <= 0 || height <= 0)
continue;
FFMonitorResult* monitor = (FFMonitorResult*) ffListAdd(results);
monitor->width = (uint32_t) width;
monitor->height = (uint32_t) height;
ffStrbufInitCopy(&monitor->name, &display->name);
CGSize size = CGDisplayScreenSize((CGDirectDisplayID) display->id);
monitor->physicalWidth = (uint32_t) (size.width + 0.5);
monitor->physicalHeight = (uint32_t) (size.height + 0.5);
monitor->hdrCompatible = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) ||
detectHdrSupportWithNSScreen(display);
}
if (displayServer->displays.length > results->length)
detectWithDdcci(results);
return NULL;
}
+2
View File
@@ -1,3 +1,5 @@
#pragma once
#include "fastfetch.h"
typedef struct FFNetIOResult
+1
View File
@@ -19,6 +19,7 @@ typedef struct FFPackagesResult
uint32_t nixDefault;
uint32_t nixSystem;
uint32_t nixUser;
uint32_t opkg;
uint32_t pacman;
uint32_t paludis;
uint32_t pkg;
+1
View File
@@ -280,6 +280,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts)
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR);
packageCounts->brew += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Cellar", DT_DIR);
packageCounts->paludis += countFilesRecursive(baseDir, "/var/db/paludis/repositories", "environment.bz2");
packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:"); // openwrt
}
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts)
@@ -6,12 +6,8 @@
const char* ffDetectPowerAdapterImpl(FFlist* results)
{
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
if (matchDict == NULL)
return "IOServiceMatching(\"AppleSmartBattery\") failed";
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleSmartBattery"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
+17 -5
View File
@@ -1,13 +1,25 @@
#include "processes.h"
#include <sys/sysinfo.h>
#include "common/io/io.h"
#include <ctype.h>
const char* ffDetectProcesses(uint32_t* result)
{
struct sysinfo info;
if(sysinfo(&info) != 0)
return "sysinfo() failed";
FF_AUTO_CLOSE_DIR DIR* dir = opendir("/proc");
if(dir == NULL)
return "opendir(\"/proc\") failed";
uint32_t num = 0;
struct dirent* entry;
while ((entry = readdir(dir)) != NULL)
{
if (entry->d_type == DT_DIR && isdigit(entry->d_name[0]))
++num;
}
*result = num;
*result = (uint32_t) info.procs;
return NULL;
}
+31 -16
View File
@@ -32,21 +32,48 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
{
AudioDeviceID deviceId = deviceIds[index];
uint32_t muted;
dataSize = sizeof(muted);
FF_CFTYPE_AUTO_RELEASE CFStringRef name = NULL;
dataSize = sizeof(name);
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyMute,
kAudioObjectPropertyName,
kAudioObjectPropertyScopeOutput,
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize, &muted) != kAudioHardwareNoError)
}, 0, NULL, &dataSize, &name) != kAudioHardwareNoError)
continue;
// Ignore input devices
if(AudioObjectGetPropertyDataSize(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyStreams,
kAudioObjectPropertyScopeInput,
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize) == kAudioHardwareNoError && dataSize > 0)
continue;
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;
device->active = false;
device->volume = FF_SOUND_VOLUME_UNKNOWN;
ffStrbufInitF(&device->identifier, "%u", (unsigned) deviceId);
ffStrbufInit(&device->name);
ffCfStrGetString(name, &device->name);
uint32_t muted;
dataSize = sizeof(muted);
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyMute,
kAudioObjectPropertyScopeOutput,
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize, &muted) != kAudioHardwareNoError)
muted = false; // Device may not support volume control
uint32_t active;
dataSize = sizeof(active);
@@ -96,18 +123,6 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
}
}
}
CFStringRef name;
dataSize = sizeof(name);
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioObjectPropertyName,
kAudioObjectPropertyScopeOutput,
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize, &name) == kAudioHardwareNoError)
{
ffCfStrGetString(name, &device->name);
CFRelease(name);
}
}
return NULL;
+1 -5
View File
@@ -140,12 +140,8 @@ static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV
static const char *smcOpen(io_connect_t *conn)
{
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSMC");
if (matchDict == NULL)
return "IOServiceMatching(\"AppleSmartBattery\") failed";
io_iterator_t iterator;
if (IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleSMC"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_object_t device = IOIteratorNext(iterator);
+11
View File
@@ -1,6 +1,17 @@
#include "temps_bsd.h"
#include "common/sysctl.h"
const char* ffDetectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
// In tenth of degrees Celsius
*current = (double) temp / 10;
return NULL;
}
const char* ffDetectThermalTemp(double* current)
{
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
+1
View File
@@ -3,6 +3,7 @@
#ifndef FF_INCLUDED_detection_temps_windows
#define FF_INCLUDED_detection_temps_windows
const char* ffDetectCpuTemp(double* current);
const char* ffDetectThermalTemp(double* current);
#endif
@@ -27,6 +27,27 @@ static const char* getSystemMonospaceFont(void)
return ffSettingsGet("/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
}
static void detectKgx(FFTerminalFontResult* terminalFont)
{
// kgx (gnome console) doesn't support profiles
if(!ffSettingsGet("/org/gnome/Console/use-system-font", "org.gnome.Console", NULL, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue)
{
FF_AUTO_FREE const char* fontName = ffSettingsGet("/org/gnome/Console/custom-font", "org.gnome.Console", NULL, "custom-font", FF_VARIANT_TYPE_STRING).strValue;
if(ffStrSet(fontName))
ffFontInitPango(&terminalFont->font, fontName);
else
ffStrbufAppendF(&terminalFont->error, "Couldn't get terminal font from GSettings (org.gnome.Console::custom-font)");
}
else
{
FF_AUTO_FREE const char* fontName = getSystemMonospaceFont();
if(ffStrSet(fontName))
ffFontInitPango(&terminalFont->font, fontName);
else
ffStrbufAppendS(&terminalFont->error, "Could't get system monospace font name from GSettings / DConf");
}
}
static void detectFromGSettings(const char* profilePath, const char* profileList, const char* profile, const char* defaultProfileKey, FFTerminalFontResult* terminalFont)
{
FF_AUTO_FREE const char* defaultProfile = ffSettingsGetGSettings(profileList, NULL, defaultProfileKey, FF_VARIANT_TYPE_STRING).strValue;
@@ -51,7 +72,7 @@ static void detectFromGSettings(const char* profilePath, const char* profileList
}
else
{
const char* fontName = getSystemMonospaceFont();
FF_AUTO_FREE const char* fontName = getSystemMonospaceFont();
if(ffStrSet(fontName))
ffFontInitPango(&terminalFont->font, fontName);
else
@@ -243,6 +264,8 @@ void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FF
detectFromGSettings("/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont);
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "gnome-terminal-"))
detectFromGSettings("/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "kgx"))
detectKgx(terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "mate-terminal"))
detectFromGSettings("/org/mate/terminal/profiles/", "org.mate.terminal.global", "org.mate.terminal.profile", "default-profile", terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "deepin-terminal"))
@@ -206,6 +206,20 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
return true;
}
FF_MAYBE_UNUSED static bool getTerminalVersionKgx(FFstrbuf* version)
{
if(ffProcessAppendStdOut(version, (char* const[]){
"gnome-terminal",
"--version",
NULL
})) return false;
//# KGX 45.0 using VTE 0.74.0 +BIDI +GNUTLS +ICU +SYSTEMD
ffStrbufSubstrAfterFirstS(version, "KGX ");
ffStrbufSubstrBeforeFirstC(version, ' ');
return true;
}
FF_MAYBE_UNUSED static bool getTerminalVersionKonsole(FFstrbuf* exe, FFstrbuf* version)
{
const char* konsoleVersion = getenv("KONSOLE_VERSION");
@@ -150,6 +150,7 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
//Known shells
if (
strcasecmp(name, "ash") == 0 ||
strcasecmp(name, "bash") == 0 ||
strcasecmp(name, "zsh") == 0 ||
strcasecmp(name, "ksh") == 0 ||
@@ -384,7 +385,9 @@ const FFTerminalShellResult* ffDetectTerminalShell()
#elif defined(__linux__) || defined(__FreeBSD__)
else if(ffStrbufStartsWithS(&result.terminalProcessName, "gnome-terminal-"))
ffStrbufInitStatic(&result.terminalPrettyName, "gnome-terminal");
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Terminal");
else if(ffStrbufStartsWithS(&result.terminalProcessName, "kgx"))
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Console");
#elif defined(__APPLE__)
+1 -1
View File
@@ -10,7 +10,7 @@ typedef struct FFUserResult
FFstrbuf name;
FFstrbuf hostName;
FFstrbuf clientIp;
FFstrbuf tty;
FFstrbuf sessionName;
uint64_t loginTime; // ms
} FFUserResult;
+1 -1
View File
@@ -31,7 +31,7 @@ next:
FFUserResult* user = (FFUserResult*) ffListAdd(users);
ffStrbufInitS(&user->name, n->ut_user);
ffStrbufInitS(&user->hostName, n->ut_host);
ffStrbufInitS(&user->tty, n->ut_line);
ffStrbufInitS(&user->sessionName, n->ut_line);
#ifdef __linux__
if(n->ut_addr_v6[0] || n->ut_addr_v6[1] || n->ut_addr_v6[2] || n->ut_addr_v6[3])
ffStrbufInitF(&user->clientIp, "%u.%u.%u.%u", n->ut_addr_v6[0], n->ut_addr_v6[1], n->ut_addr_v6[2], n->ut_addr_v6[3]);
+4 -5
View File
@@ -28,17 +28,18 @@ const char* ffDetectUsers(FFlist* users)
FFUserResult* user = (FFUserResult*) ffListAdd(users);
ffStrbufInitWS(&user->name, session->pUserName);
ffStrbufInitWS(&user->hostName, session->pHostName);
ffStrbufInitWS(&user->sessionName, session->pSessionName);
ffStrbufInit(&user->clientIp);
user->loginTime = 0;
DWORD bytes = 0;
PWTS_CLIENT_ADDRESS address = NULL;
if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSClientAddress, (LPWSTR *) &address, &bytes))
{
if (address->AddressFamily == 2 /*AF_INET*/)
ffStrbufInitF(&user->clientIp, "%u.%u.%u.%u", address->Address[2], address->Address[3], address->Address[4], address->Address[5]);
ffStrbufSetF(&user->clientIp, "%u.%u.%u.%u", address->Address[2], address->Address[3], address->Address[4], address->Address[5]);
WTSFreeMemory(address);
}
else
ffStrbufInitS(&user->clientIp, "0.0.0.0");
bytes = 0;
PWTSINFOW wtsInfo = NULL;
@@ -47,8 +48,6 @@ const char* ffDetectUsers(FFlist* users)
user->loginTime = to_ms(*(uint64_t*) &wtsInfo->LogonTime);
WTSFreeMemory(wtsInfo);
}
else
user->loginTime = 0;
}
WTSFreeMemoryExW(WTSTypeSessionInfoLevel1, sessionInfo, 1);
+20 -1
View File
@@ -1,4 +1,5 @@
#include "wifi.h"
#include "common/processing.h"
#import <CoreWLAN/CoreWLAN.h>
@@ -31,7 +32,22 @@ const char* ffDetectWifi(FFlist* result)
if(!inf.serviceActive)
continue;
ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String);
if (inf.ssid)
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
ffStrbufSetStatic(&item->conn.ssid, "<unknown ssid>"); // https://developer.apple.com/forums/thread/732431
ffStrbufAppendS(&item->conn.macAddress, inf.hardwareAddress.UTF8String);
switch(inf.activePHYMode)
{
@@ -116,6 +132,9 @@ const char* ffDetectWifi(FFlist* result)
case 15 /*kCWSecurityOWETransition*/:
ffStrbufAppendS(&item->conn.security, "OWE Transition");
break;
case kCWSecurityUnknown:
// Ignore
break;
default:
ffStrbufAppendF(&item->conn.security, "Unknown (%ld)", inf.security);
break;
+18 -493
View File
@@ -21,22 +21,23 @@
#include "modules/modules.h"
static void constructAndPrintCommandHelpFormat(const char* name, const char* def, uint32_t numArgs, ...)
static void printCommandFormatHelp(const char* command)
{
va_list argp;
va_start(argp, numArgs);
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateNS((uint32_t) (strlen(command) - strlen("-format")), command);
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(command[0]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
if (ffStrbufIgnCaseEqualS(&type, baseInfo->name))
{
if (baseInfo->printHelpFormat)
baseInfo->printHelpFormat();
else
fprintf(stderr, "Error: Module '%s' doesn't support output formatting\n", baseInfo->name);
return;
}
}
printf("--%s-format:\n", name);
printf("Sets the format string for %s output.\n", name);
puts("To see how a format string is constructed, take a look at \"fastfetch --help format\".");
puts("The following values are passed:");
for(uint32_t i = 1; i <= numArgs; i++)
printf(" {%u}: %s\n", i, va_arg(argp, const char*));
printf("The default is something similar to \"%s\".\n", def);
va_end(argp);
fprintf(stderr, "Error: Module '%s' is not supported\n", type.chars);
}
static inline void printCommandHelp(const char* command)
@@ -49,486 +50,10 @@ static inline void printCommandHelp(const char* command)
puts(FASTFETCH_DATATEXT_HELP_FORMAT);
else if(ffStrEqualsIgnCase(command, "load-config") || ffStrEqualsIgnCase(command, "config"))
puts(FASTFETCH_DATATEXT_HELP_CONFIG);
else if(ffStrEqualsIgnCase(command, "title-format"))
{
constructAndPrintCommandHelpFormat("title", "{6}{7}{8}", 8,
"User name",
"Host name",
"Home directory",
"Executable path of current process",
"User's default shell",
"User name (colored)",
"@ symbol (colored)",
"Host name (colored)"
);
}
else if(ffStrEqualsIgnCase(command, "os-format"))
{
constructAndPrintCommandHelpFormat("os", "{3} {12}", 12,
"System name (typically just Linux)",
"Name of the OS",
"Pretty name of the OS",
"ID of the OS",
"ID like of the OS",
"Variant of the OS",
"Variant ID of the OS",
"Version of the OS",
"Version ID of the OS",
"Version codename of the OS",
"Build ID of the OS",
"Architecture of the OS"
);
}
else if(ffStrEqualsIgnCase(command, "host-format"))
{
constructAndPrintCommandHelpFormat("host", "{2} {3}", 8,
"product family",
"product name",
"product version",
"product sku",
"chassis type",
"chassis vendor",
"chassis version",
"sys vendor"
);
}
else if(ffStrEqualsIgnCase(command, "bios-format"))
{
constructAndPrintCommandHelpFormat("bios", "{2} {3}", 4,
"bios date",
"bios release",
"bios vendor",
"bios version"
);
}
else if(ffStrEqualsIgnCase(command, "board-format"))
{
constructAndPrintCommandHelpFormat("board", "{2} {3}", 3,
"board name",
"board vendor",
"board version"
);
}
else if(ffStrEqualsIgnCase(command, "chassis-format"))
{
constructAndPrintCommandHelpFormat("chassis", "{2} {3}", 4,
"chassis type",
"chassis vendor",
"chassis version"
);
}
else if(ffStrEqualsIgnCase(command, "kernel-format"))
{
constructAndPrintCommandHelpFormat("kernel", "{2}", 3,
"Kernel sysname",
"Kernel release",
"Kernel version"
);
}
else if(ffStrEqualsIgnCase(command, "uptime-format"))
{
constructAndPrintCommandHelpFormat("uptime", "{} days {} hours {} mins", 4,
"Days",
"Hours",
"Minutes",
"Seconds"
);
}
else if(ffStrEqualsIgnCase(command, "processes-format"))
{
constructAndPrintCommandHelpFormat("processes", "{}", 1,
"Count"
);
}
else if(ffStrEqualsIgnCase(command, "packages-format"))
{
constructAndPrintCommandHelpFormat("packages", "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (eopkg), {8} (xbps), {9} (nix-system), {10} (nix-user), {11} (nix-default), {12} (apk), {13} (pkg), {14} (flatpak-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (port), {20} (scoop), {21} (choco), {22} (pkgtool), {23} (paludis), {24} (winget)", 24,
"Number of all packages",
"Number of pacman packages",
"Pacman branch on manjaro",
"Number of dpkg packages",
"Number of rpm packages",
"Number of emerge packages",
"Number of eopkg packages",
"Number of xbps packages",
"Number of nix-system packages",
"Number of nix-user packages",
"Number of nix-default packages",
"Number of apk packages",
"Number of pkg packages",
"Number of flatpak-system packages",
"Number of flatpak-user packages",
"Number of snap packages",
"Number of brew packages",
"Number of brew-cask packages",
"Number of macports packages",
"Number of scoop packages",
"Number of choco packages",
"Number of pkgtool packages",
"Number of paludis packages"
"Number of winget packages"
);
}
else if(ffStrEqualsIgnCase(command, "shell-format"))
{
constructAndPrintCommandHelpFormat("shell", "{3} {4}", 6,
"Shell process name",
"Shell path with exe name",
"Shell exe name",
"Shell version",
"Shell pid",
"Shell pretty name"
);
}
else if(ffStrEqualsIgnCase(command, "display-format"))
{
constructAndPrintCommandHelpFormat("display", "{}x{} @ {}Hz", 7,
"Screen width",
"Screen height",
"Screen refresh rate",
"Screen scaled width",
"Screen scaled height",
"Screen name",
"Screen type",
"Screen rotation"
);
}
else if(ffStrEqualsIgnCase(command, "brightness-format"))
{
constructAndPrintCommandHelpFormat("brightness", "{}", 2,
"Screen brightness",
"Screen name"
);
}
else if(ffStrEqualsIgnCase(command, "monitor-format"))
{
constructAndPrintCommandHelpFormat("monitor", "{}", 6,
"Display name",
"Display native resolution width in pixels",
"Display native resolution height in pixels",
"Display physical width in millimeters",
"Display physical height in millimeters",
"Display physical diagonal length in inches",
"Display physical pixels per inch (PPI)"
);
}
else if(ffStrEqualsIgnCase(command, "de-format"))
{
constructAndPrintCommandHelpFormat("de", "{2} {3}", 3,
"DE process name",
"DE pretty name",
"DE version"
);
}
else if(ffStrEqualsIgnCase(command, "wm-format"))
{
constructAndPrintCommandHelpFormat("wm", "{2} ({3})", 3,
"WM process name",
"WM pretty name",
"WM protocol name"
);
}
else if(ffStrEqualsIgnCase(command, "wmtheme-format"))
{
constructAndPrintCommandHelpFormat("wmtheme", "{}", 1,
"WM theme name"
);
}
else if(ffStrEqualsIgnCase(command, "theme-format"))
{
constructAndPrintCommandHelpFormat("theme", "{}", 1,
"Combined themes"
);
}
else if(ffStrEqualsIgnCase(command, "icons-format"))
{
constructAndPrintCommandHelpFormat("icons", "{}", 1,
"Combined icons"
);
}
else if(ffStrEqualsIgnCase(command, "wallpaper-format"))
{
constructAndPrintCommandHelpFormat("wallpaper", "{}", 1,
"Wallpaper image file"
);
}
else if(ffStrEqualsIgnCase(command, "font-format"))
{
constructAndPrintCommandHelpFormat("font", "{} [QT], {} [GTK2], {} [GTK3], {} [GTK4]", 4,
"Font 1",
"Font 2",
"Font 3",
"Font 4"
);
}
else if(ffStrEqualsIgnCase(command, "cursor-format"))
{
constructAndPrintCommandHelpFormat("cursor", "{} ({}pt)", 2,
"Cursor theme",
"Cursor size"
);
}
else if(ffStrEqualsIgnCase(command, "terminal-format"))
{
constructAndPrintCommandHelpFormat("terminal", "{3}", 10,
"Terminal process name",
"Terminal path with exe name",
"Terminal exe name",
"Terminal pid",
"Terminal pretty name",
"Terminal version"
);
}
else if(ffStrEqualsIgnCase(command, "terminalfont-format"))
{
constructAndPrintCommandHelpFormat("terminalfont", "{}", 4,
"Terminal font",
"Terminal font name",
"Termianl font size",
"Terminal font styles"
);
}
else if(ffStrEqualsIgnCase(command, "cpu-format"))
{
constructAndPrintCommandHelpFormat("cpu", "{1} ({5}) @ {7}GHz", 8,
"Name",
"Vendor",
"Physical core count",
"Logical core count",
"Online core count",
"Min frequency",
"Max frequency",
"Temperature"
);
}
else if(ffStrEqualsIgnCase(command, "cpuusage-format"))
{
constructAndPrintCommandHelpFormat("cpuusage", "{0}%", 1,
"CPU usage without percent mark"
);
}
else if(ffStrEqualsIgnCase(command, "gpu-format"))
{
constructAndPrintCommandHelpFormat("gpu", "{} {}", 6,
"GPU vendor",
"GPU name",
"GPU driver",
"GPU temperature",
"GPU core count",
"GPU type"
);
}
else if(ffStrEqualsIgnCase(command, "memory-format"))
{
constructAndPrintCommandHelpFormat("memory", "{} / {} ({}%)", 3,
"Used size",
"Total size",
"Percentage used"
);
}
else if(ffStrEqualsIgnCase(command, "swap-format"))
{
constructAndPrintCommandHelpFormat("swap", "{} / {} ({}%)", 3,
"Used size",
"Total size",
"Percentage used"
);
}
else if(ffStrEqualsIgnCase(command, "disk-format"))
{
constructAndPrintCommandHelpFormat("disk", "{1} / {2} ({3}%)", 9,
"Size used",
"Size total",
"Size percentage",
"Files used",
"Files total",
"Files percentage",
"True if external volume",
"True if hidden volume",
"Filesystem"
);
}
else if(ffStrEqualsIgnCase(command, "battery-format"))
{
constructAndPrintCommandHelpFormat("battery", "{}%, {}", 5,
"Battery manufactor",
"Battery model",
"Battery technology",
"Battery capacity",
"Battery status"
);
}
else if(ffStrEqualsIgnCase(command, "poweradapter-format"))
{
constructAndPrintCommandHelpFormat("poweradapter", "{}%, {}", 5,
"PowerAdapter watts",
"PowerAdapter name",
"PowerAdapter manufacturer",
"PowerAdapter model",
"PowerAdapter description"
);
}
else if(ffStrEqualsIgnCase(command, "lm-format"))
{
constructAndPrintCommandHelpFormat("lm", "{} ({})", 2,
"LM service",
"LM type"
);
}
else if(ffStrEqualsIgnCase(command, "locale-format"))
{
constructAndPrintCommandHelpFormat("locale", "{}", 1,
"Locale code"
);
}
else if(ffStrEqualsIgnCase(command, "localip-format"))
{
constructAndPrintCommandHelpFormat("localip", "{}", 5,
"Local IPv4 address",
"Local IPv6 address",
"Physical (MAC) address",
"Interface name",
"Is default route"
);
}
else if(ffStrEqualsIgnCase(command, "publicip-format"))
{
constructAndPrintCommandHelpFormat("publicip", "{}", 1,
"Public IP address"
);
}
else if(ffStrEqualsIgnCase(command, "netio-format"))
{
constructAndPrintCommandHelpFormat("netio", "{}", 3,
"Size of data received per second (formatted)",
"Size of data sent per second (formatted)",
"Interface name",
"Is default route"
);
}
else if(ffStrEqualsIgnCase(command, "wifi-format"))
{
constructAndPrintCommandHelpFormat("wifi", "{4} - {6}", 3,
"Interface description",
"Interface status",
"Connection status",
"Connection SSID",
"Connection mac address",
"Connection protocol",
"Connection signal quality (percentage)",
"Connection RX rate",
"Connection TX rate",
"Connection Security algorithm"
);
}
else if(ffStrEqualsIgnCase(command, "player-format"))
{
constructAndPrintCommandHelpFormat("player", "{}", 4,
"Pretty player name",
"Player name",
"Player Identifier",
"URL name"
);
}
else if(ffStrEqualsIgnCase(command, "media-format"))
{
constructAndPrintCommandHelpFormat("media", "{3} - {1}", 4,
"Pretty media name",
"Media name",
"Artist name",
"Album name"
);
}
else if(ffStrEqualsIgnCase(command, "datetime-format") == 0 || ffStrEqualsIgnCase(command, "date-format") || ffStrEqualsIgnCase(command, "time-format"))
{
constructAndPrintCommandHelpFormat("[date][time]", "{1}-{4}-{11} {14}:{18}:{20}", 20,
"year",
"last two digits of year",
"month",
"month with leading zero",
"month name",
"month name short",
"week number on year",
"weekday",
"weekday short",
"day in year",
"day in month",
"day in Week",
"hour",
"hour with leading zero",
"hour 12h format",
"hour 12h format with leading zero",
"minute",
"minute with leading zero",
"second",
"second with leading zero"
);
}
else if(ffStrEqualsIgnCase(command, "version-format"))
{
constructAndPrintCommandHelpFormat("version", "{1} {2}{3} (5)", 6,
"Project name",
"Version",
"Version tweak",
"Build type (debug or release)",
"Architecture",
"CMake build type (Debug, Release, RelWithDebInfo, MinSizeRel)",
"Date time when compiling",
"Compiler used"
);
}
else if(ffStrEqualsIgnCase(command, "vulkan-format"))
{
constructAndPrintCommandHelpFormat("vulkan", "{} (driver), {} (api version)", 3,
"Driver name",
"API version",
"Conformance version"
);
}
else if(ffStrEqualsIgnCase(command, "opengl-format"))
{
constructAndPrintCommandHelpFormat("opengl", "{}", 3,
"version",
"renderer",
"vendor",
"shading language version"
);
}
else if(ffStrEqualsIgnCase(command, "opencl-format"))
{
constructAndPrintCommandHelpFormat("opencl", "{}", 3,
"version",
"device",
"vendor"
);
}
else if(ffStrEqualsIgnCase(command, "bluetooth-format"))
{
constructAndPrintCommandHelpFormat("bluetooth", "{1} (4%)", 4,
"Name",
"Address",
"Type",
"Battery percentage"
);
}
else if(ffStrEqualsIgnCase(command, "sound-format"))
{
constructAndPrintCommandHelpFormat("sound", "{2} (3%)", 4,
"Main",
"Name",
"Volume",
"Identifier"
);
}
else if(ffStrEqualsIgnCase(command, "gamepad-format"))
{
constructAndPrintCommandHelpFormat("gamepad", "{1}", 1,
"Name",
"Identifier"
);
}
else if(isalpha(command[0]) && ffStrEndsWithIgnCase(command, "-format")) // x-format
printCommandFormatHelp(command);
else
fprintf(stderr, "No specific help for command %s provided\n", command);
fprintf(stderr, "Error: No specific help for command '%s' provided\n", command);
}
static void listAvailablePresets(void)
+1
View File
@@ -99,6 +99,7 @@ typedef struct FFconfig
FFDEOptions de;
FFDateTimeOptions dateTime;
FFDiskOptions disk;
FFDiskIOOptions diskIo;
FFDisplayOptions display;
FFFontOptions font;
FFGPUOptions gpu;
+18
View File
@@ -0,0 +1,18 @@
${c3}ddddddddddddddc ${c1},cc:
${c3}ddddddddddddddc ${c1},cc:
${c3}ddddddddddddddd ${c1},cc:
${c3}ddddddddddddl:' ${c1},cc:
${c3}dddddddddl' ${c1}..;cc:
${c3}dddddddo. ${c1},:cccccc:
${c3}ddddddl ${c1},ccc:'''''
${c3}dddddo. ${c1};ccc. ............
.ccc. cccccccccccc
${c2}...... ${c1}.ccc. .ccc'''''''''
${c2}OOOOOk. ${c1};ccc. .ccc; ......
${c2}OOOOOOd ${c1}'ccc:,....,:ccc' ${c4}coooooo
${c2}OOOOOOOx. ${c1}':cccccccc:' ${c4}.looooooo
${c2}OOOOOOOOOd, ${c1}`'''` ${c4}.coooooooo
${c2}OOOOOOOOOOOOdc,. ${c4}..,coooooooooooo
${c2}OOOOOOOOOOOOOOOO' ${c4}.oooooooooooooooo
${c2}OOOOOOOOOOOOOOOO' ${c4}.oooooooooooooooo
${c2}OOOOOOOOOOOOOOOO' ${c4}.oooooooooooooooo
+7
View File
@@ -0,0 +1,7 @@
/${c2}o${c3}.
${c1} :${c2}sssso${c3}-
${c1} :${c2}ossssssso${c3}:
${c1} /${c2}ssssssssssso${c3}+
${c1} -+${c2}ssssssssssssssso${c3}+
${c1} //${c2}osssssssssssssso${c3}+-
`+++++++++++++++-`
+21
View File
@@ -0,0 +1,21 @@
${c2} ,c. .c;
${c2} .${c1}KMMMk${c2}.... ....${c1}kMMMK${c2}.
${c2} .${c1}WMMMMMX${c2}..... .....${c1}KMMMMMW.
${c1} XMMMMMMM0${c2}..... ....${c1}OMMMMMMMN
${c1} dMMMMMMMMM;${c2}.... ..... ....,${c1}MMMMMMMMMd
${c1} WMMMMMMMMMl;${c3}okKKKKKKKKKOo${c1};cMMMMMMMMMM
${c1} 'MMMMMMMNX${c2}K0${c3}KKKKKKKKKKKKKKK${c2}0K${c1}XNMMMMMMM;
${c1} oMMMMMMM${c2}Oxo${c3}KKKKKKKKKKKKKKKKK${c2}oxO${c1}MMMMMMMd
${c1} dMMMMMMM${c2}dxxx${c3}KKKKKKKKKKKKKKK${c2}xxxd${c1}NMMMMMMk
${c1} :MMMMX0${c2}xxxxxx${c3}0KKKKKKKK0KK0${c2}xxxxxx0${c1}XMMMMc
${c1} MMMO${c2}xxxxxxxxdx${c3}kdd${c2}0x0${c3}ddk${c2}xdxxxxxxxx${c1}OMMM
${c1} ;${c2}xxkxddxxxxdodxxxxdxdxxxxdodxxxxddxkxx${c1};
${c1}dxd${c2}KMMMWXo${c1}'.....'${c2}cdxxxdc${c1}'.....'${c2}lXWMMMX${c1}dxd
${c1}cxd${c2}XMMMN${c1},..........${c2}dxd${c1}'.........'${c2}XMMMN${c1}dxl
${c1} .xx${c2}WMMl${c1}...''....'.;k:.'....''...${c2}lMMW${c1}xx.
${c1}..:kXMMx..'....''..kMk..''....'..xMMXkc..
${c1} dMMMMMMd.....'...xMMMx...''....dMMMMMMx
${c1} kMMMMWOoc:coOkolllokOoc:coOWMMMMO
${c1} .MMMMMMMMl${c2}...${c1}lNMMMMMMM.
${c1} KMMMMMMX${c2}l${c1}KMMMMMMX
${c1} .MMMMMMMMM.
+34
View File
@@ -826,6 +826,19 @@ static const FFlogo C[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// Chimera Linux
{
.names = {"Chimera Linux"},
.lines = FASTFETCH_DATATEXT_LOGO_CHIMERALINUX,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_MAGENTA,
FF_COLOR_FG_BLUE,
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_MAGENTA,
.colorTitle = FF_COLOR_FG_RED,
},
// ChonkySealOS
{
.names = {"ChonkySealOS"},
@@ -1264,6 +1277,17 @@ static const FFlogo E[] = {
.colorKeys = FF_COLOR_FG_MAGENTA,
.colorTitle = FF_COLOR_FG_RED,
},
// EndeavourSmall
{
.names = {"Endeavour_small", "endeavour-linux_small", "endeavouros_small", "endeavouros-linux_small"},
.lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUR_SMALL,
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_MAGENTA,
FF_COLOR_FG_BLUE,
},
},
// Endless
{
.names = {"Endless"},
@@ -4136,6 +4160,16 @@ static const FFlogo W[] = {
};
static const FFlogo X[] = {
// Xenia
{
.names = {"Xenia"},
.lines = FASTFETCH_DATATEXT_LOGO_XENIA,
.colors = {
FF_COLOR_FG_YELLOW,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_RED,
}
},
// Xferience
{
.names = {"Xferience"},
+12 -1
View File
@@ -103,7 +103,7 @@ void ffPrintBattery(FFBatteryOptions* options)
void ffInitBatteryOptions(FFBatteryOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BATTERY_MODULE_NAME, ffParseBatteryCommandOptions, ffParseBatteryJsonObject, ffPrintBattery, ffGenerateBatteryJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BATTERY_MODULE_NAME, ffParseBatteryCommandOptions, ffParseBatteryJsonObject, ffPrintBattery, ffGenerateBatteryJson, ffPrintBatteryHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
options->temp = false;
@@ -208,3 +208,14 @@ void ffGenerateBatteryJson(FFBatteryOptions* options, yyjson_mut_doc* doc, yyjso
ffStrbufDestroy(&battery->status);
}
}
void ffPrintBatteryHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_BATTERY_MODULE_NAME, "{4}, {5}", FF_BATTERY_NUM_FORMAT_ARGS, (const char* []) {
"Battery manufactor",
"Battery model",
"Battery technology",
"Battery capacity (percentage)",
"Battery status"
});
}
+1
View File
@@ -11,3 +11,4 @@ bool ffParseBatteryCommandOptions(FFBatteryOptions* options, const char* key, co
void ffDestroyBatteryOptions(FFBatteryOptions* options);
void ffParseBatteryJsonObject(FFBatteryOptions* options, yyjson_val* module);
void ffGenerateBatteryJson(FFBatteryOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintBatteryHelpFormat(void);
+11 -1
View File
@@ -55,7 +55,7 @@ exit:
void ffInitBiosOptions(FFBiosOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BIOS_MODULE_NAME, ffParseBiosCommandOptions, ffParseBiosJsonObject, ffPrintBios, ffGenerateBiosJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BIOS_MODULE_NAME, ffParseBiosCommandOptions, ffParseBiosJsonObject, ffPrintBios, ffGenerateBiosJson, ffPrintBiosHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
}
@@ -125,3 +125,13 @@ exit:
ffStrbufDestroy(&bios.vendor);
ffStrbufDestroy(&bios.version);
}
void ffPrintBiosHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_BIOS_MODULE_NAME, "{4} ({2})", FF_BIOS_NUM_FORMAT_ARGS, (const char* []) {
"bios date",
"bios release",
"bios vendor",
"bios version"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseBiosCommandOptions(FFBiosOptions* options, const char* key, const ch
void ffDestroyBiosOptions(FFBiosOptions* options);
void ffParseBiosJsonObject(FFBiosOptions* options, yyjson_val* module);
void ffGenerateBiosJson(FFBiosOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintBiosHelpFormat(void);
+11 -1
View File
@@ -75,7 +75,7 @@ void ffPrintBluetooth(FFBluetoothOptions* options)
void ffInitBluetoothOptions(FFBluetoothOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BLUETOOTH_MODULE_NAME, ffParseBluetoothCommandOptions, ffParseBluetoothJsonObject, ffPrintBluetooth, ffGenerateBluetoothJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BLUETOOTH_MODULE_NAME, ffParseBluetoothCommandOptions, ffParseBluetoothJsonObject, ffPrintBluetooth, ffGenerateBluetoothJson, ffPrintBluetoothHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
options->showDisconnected = false;
}
@@ -156,3 +156,13 @@ void ffGenerateBluetoothJson(FF_MAYBE_UNUSED FFBluetoothOptions* options, yyjson
ffStrbufDestroy(&device->address);
}
}
void ffPrintBluetoothHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_BLUETOOTH_MODULE_NAME, "{1} ({4})", FF_BLUETOOTH_NUM_FORMAT_ARGS, (const char* []) {
"Name",
"Address",
"Type",
"Battery percentage"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseBluetoothCommandOptions(FFBluetoothOptions* options, const char* key
void ffDestroyBluetoothOptions(FFBluetoothOptions* options);
void ffParseBluetoothJsonObject(FFBluetoothOptions* options, yyjson_val* module);
void ffGenerateBluetoothJson(FFBluetoothOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintBluetoothHelpFormat(void);
+10 -1
View File
@@ -51,7 +51,7 @@ exit:
void ffInitBoardOptions(FFBoardOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BOARD_MODULE_NAME, ffParseBoardCommandOptions, ffParseBoardJsonObject, ffPrintBoard, NULL);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BOARD_MODULE_NAME, ffParseBoardCommandOptions, ffParseBoardJsonObject, ffPrintBoard, ffGenerateBoardJson, ffPrintBoardHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
}
@@ -118,3 +118,12 @@ exit:
ffStrbufDestroy(&board.vendor);
ffStrbufDestroy(&board.version);
}
void ffPrintBoardHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_BOARD_MODULE_NAME, "{1} ({3})", FF_BOARD_NUM_FORMAT_ARGS, (const char* []) {
"board name",
"board vendor",
"board version"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseBoardCommandOptions(FFBoardOptions* options, const char* key, const
void ffDestroyBoardOptions(FFBoardOptions* options);
void ffParseBoardJsonObject(FFBoardOptions* options, yyjson_val* module);
void ffGenerateBoardJson(FFBoardOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintBoardHelpFormat(void);
+1 -1
View File
@@ -9,7 +9,7 @@ void ffPrintBreak(FF_MAYBE_UNUSED FFBreakOptions* options)
void ffInitBreakOptions(FF_MAYBE_UNUSED FFBreakOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BREAK_MODULE_NAME, ffParseBreakCommandOptions, ffParseBreakJsonObject, ffPrintBreak, NULL);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BREAK_MODULE_NAME, ffParseBreakCommandOptions, ffParseBreakJsonObject, ffPrintBreak, NULL, NULL);
}
bool ffParseBreakCommandOptions(FF_MAYBE_UNUSED FFBreakOptions* options, FF_MAYBE_UNUSED const char* key, FF_MAYBE_UNUSED const char* value)
+28 -3
View File
@@ -11,7 +11,7 @@ void ffPrintBrightness(FFBrightnessOptions* options)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFBrightnessResult));
const char* error = ffDetectBrightness(&result);
const char* error = ffDetectBrightness(options, &result);
if(error)
{
@@ -86,8 +86,10 @@ void ffPrintBrightness(FFBrightnessOptions* options)
void ffInitBrightnessOptions(FFBrightnessOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BRIGHTNESS_MODULE_NAME, ffParseBrightnessCommandOptions, ffParseBrightnessJsonObject, ffPrintBrightness, ffGenerateBrightnessJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BRIGHTNESS_MODULE_NAME, ffParseBrightnessCommandOptions, ffParseBrightnessJsonObject, ffPrintBrightness, ffGenerateBrightnessJson, ffPrintBrightnessHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
options->ddcciSleep = 10;
}
bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* key, const char* value)
@@ -97,6 +99,12 @@ bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* k
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffStrEqualsIgnCase(key, "ddcci-sleep"))
{
options->ddcciSleep = ffOptionParseUInt32(key, value);
return true;
}
return false;
}
@@ -118,6 +126,12 @@ void ffParseBrightnessJsonObject(FFBrightnessOptions* options, yyjson_val* modul
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffStrEqualsIgnCase(key, "ddcciSleep"))
{
options->ddcciSleep = (uint32_t) yyjson_get_uint(val);
continue;
}
ffPrintError(FF_BRIGHTNESS_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
@@ -126,7 +140,7 @@ void ffGenerateBrightnessJson(FF_MAYBE_UNUSED FFBrightnessOptions* options, yyjs
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFBrightnessResult));
const char* error = ffDetectBrightness(&result);
const char* error = ffDetectBrightness(options, &result);
if (error)
{
@@ -157,3 +171,14 @@ void ffGenerateBrightnessJson(FF_MAYBE_UNUSED FFBrightnessOptions* options, yyjs
ffStrbufDestroy(&item->name);
}
}
void ffPrintBrightnessHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_BRIGHTNESS_MODULE_NAME, "{1}", FF_BRIGHTNESS_NUM_FORMAT_ARGS, (const char* []) {
"Screen brightness (percentage)",
"Screen name",
"Maximum brightness value",
"Minimum brightness value",
"Current brightness value",
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* k
void ffDestroyBrightnessOptions(FFBrightnessOptions* options);
void ffParseBrightnessJsonObject(FFBrightnessOptions* options, yyjson_val* module);
void ffGenerateBrightnessJson(FFBrightnessOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintBrightnessHelpFormat(void);
+2
View File
@@ -8,4 +8,6 @@ typedef struct FFBrightnessOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
uint32_t ddcciSleep; // ms
} FFBrightnessOptions;
+10 -1
View File
@@ -52,7 +52,7 @@ exit:
void ffInitChassisOptions(FFChassisOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CHASSIS_MODULE_NAME, ffParseChassisCommandOptions, ffParseChassisJsonObject, ffPrintChassis, ffGenerateChassisJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CHASSIS_MODULE_NAME, ffParseChassisCommandOptions, ffParseChassisJsonObject, ffPrintChassis, ffGenerateChassisJson, ffPrintChassisHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
}
@@ -119,3 +119,12 @@ exit:
ffStrbufDestroy(&result.vendor);
ffStrbufDestroy(&result.version);
}
void ffPrintChassisHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_CHASSIS_MODULE_NAME, "{1}", FF_CHASSIS_NUM_FORMAT_ARGS, (const char* []) {
"chassis type",
"chassis vendor",
"chassis version"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseChassisCommandOptions(FFChassisOptions* options, const char* key, co
void ffDestroyChassisOptions(FFChassisOptions* options);
void ffParseChassisJsonObject(FFChassisOptions* options, yyjson_val* module);
void ffGenerateChassisJson(FFChassisOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintChassisHelpFormat(void);
+1 -1
View File
@@ -57,7 +57,7 @@ void ffPrintColors(FFColorsOptions* options)
void ffInitColorsOptions(FFColorsOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_COLORS_MODULE_NAME, ffParseColorsCommandOptions, ffParseColorsJsonObject, ffPrintColors, NULL);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_COLORS_MODULE_NAME, ffParseColorsCommandOptions, ffParseColorsJsonObject, ffPrintColors, NULL, NULL);
ffOptionInitModuleArg(&options->moduleArgs);
ffStrbufSetStatic(&options->moduleArgs.key, " ");
options->symbol = FF_COLORS_SYMBOL_BLOCK;
+21 -3
View File
@@ -4,6 +4,8 @@
#include "modules/command/command.h"
#include "util/stringUtils.h"
#define FF_COMMAND_NUM_FORMAT_ARGS 1
void ffPrintCommand(FFCommandOptions* options)
{
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
@@ -30,13 +32,22 @@ void ffPrintCommand(FFCommandOptions* options)
return;
}
ffPrintLogoAndKey(FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffStrbufPutTo(&result, stdout);
if (options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffStrbufPutTo(&result, stdout);
}
else
{
ffPrintFormat(FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs, FF_COMMAND_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &result}
});
}
}
void ffInitCommandOptions(FFCommandOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_COMMAND_MODULE_NAME, ffParseCommandCommandOptions, ffParseCommandJsonObject, ffPrintCommand, ffGenerateCommandJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_COMMAND_MODULE_NAME, ffParseCommandCommandOptions, ffParseCommandJsonObject, ffPrintCommand, ffGenerateCommandJson, ffPrintCommandHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
ffStrbufInitStatic(&options->shell,
@@ -136,3 +147,10 @@ void ffGenerateCommandJson(FF_MAYBE_UNUSED FFCommandOptions* options, yyjson_mut
yyjson_mut_obj_add_strbuf(doc, module, "result", &result);
}
void ffPrintCommandHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_COMMAND_MODULE_NAME, "{1}", FF_COMMAND_NUM_FORMAT_ARGS, (const char* []) {
"Command result"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseCommandCommandOptions(FFCommandOptions* options, const char* key, co
void ffDestroyCommandOptions(FFCommandOptions* options);
void ffParseCommandJsonObject(FFCommandOptions* options, yyjson_val* module);
void ffGenerateCommandJson(FFCommandOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintCommandHelpFormat(void);
+29 -2
View File
@@ -48,7 +48,7 @@ void ffPrintCPU(FFCPUOptions* options)
ffStrbufAppendF(&str, " (%u)", cpu.coresOnline);
if(cpu.frequencyMax > 0.0)
ffStrbufAppendF(&str, " @ %.9g GHz", cpu.frequencyMax);
ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, cpu.frequencyMax);
if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET
{
@@ -79,9 +79,10 @@ void ffPrintCPU(FFCPUOptions* options)
void ffInitCPUOptions(FFCPUOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CPU_MODULE_NAME, ffParseCPUCommandOptions, ffParseCPUJsonObject, ffPrintCPU, ffGenerateCPUJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CPU_MODULE_NAME, ffParseCPUCommandOptions, ffParseCPUJsonObject, ffPrintCPU, ffGenerateCPUJson, ffPrintCPUHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
options->temp = false;
options->freqNdigits = 2;
}
bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char* value)
@@ -97,6 +98,12 @@ bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char
return true;
}
if (ffStrEqualsIgnCase(subKey, "freq-ndigits"))
{
options->freqNdigits = (uint8_t) ffOptionParseUInt32(key, value);
return true;
}
return false;
}
@@ -124,6 +131,12 @@ void ffParseCPUJsonObject(FFCPUOptions* options, yyjson_val* module)
continue;
}
if (ffStrEqualsIgnCase(key, "freqNdigits"))
{
options->freqNdigits = (uint8_t) yyjson_get_uint(val);
continue;
}
ffPrintError(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
@@ -168,3 +181,17 @@ void ffGenerateCPUJson(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_mut_va
ffStrbufDestroy(&cpu.name);
ffStrbufDestroy(&cpu.vendor);
}
void ffPrintCPUHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_CPU_MODULE_NAME, "{1} ({5}) @ {7} GHz", FF_CPU_NUM_FORMAT_ARGS, (const char* []) {
"Name",
"Vendor",
"Physical core count",
"Logical core count",
"Online core count",
"Min frequency",
"Max frequency",
"Temperature"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char
void ffDestroyCPUOptions(FFCPUOptions* options);
void ffParseCPUJsonObject(FFCPUOptions* options, yyjson_val* module);
void ffGenerateCPUJson(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintCPUHelpFormat(void);
+1
View File
@@ -10,4 +10,5 @@ typedef struct FFCPUOptions
FFModuleArgs moduleArgs;
bool temp;
uint8_t freqNdigits;
} FFCPUOptions;
+84 -16
View File
@@ -6,12 +6,12 @@
#include "util/stringUtils.h"
#define FF_CPUUSAGE_DISPLAY_NAME "CPU Usage"
#define FF_CPUUSAGE_NUM_FORMAT_ARGS 1
#define FF_CPUUSAGE_NUM_FORMAT_ARGS 5
void ffPrintCPUUsage(FFCPUUsageOptions* options)
{
double percentage = 0.0/0.0;
const char* error = ffGetCpuUsageResult(&percentage);
FF_LIST_AUTO_DESTROY percentages = ffListCreate(sizeof(double));
const char* error = ffGetCpuUsageResult(&percentages);
if(error)
{
@@ -19,34 +19,75 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
return;
}
double maxValue = -999, minValue = 999, sumValue = 0;
uint32_t maxIndex = 999, minIndex = 999;
uint32_t index = 0;
FF_LIST_FOR_EACH(double, percent, percentages)
{
sumValue += *percent;
if (*percent > maxValue)
{
maxValue = *percent;
maxIndex = index;
}
if (*percent < minValue)
{
minValue = *percent;
minIndex = index;
}
++index;
}
double avgValue = sumValue / (double) percentages.length;
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
if(instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
ffAppendPercentBar(&str, percentage, 0, 50, 80);
if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
if (!options->separate)
{
if(str.length > 0)
ffStrbufAppendC(&str, ' ');
ffAppendPercentNum(&str, percentage, 50, 80, str.length > 0);
if(instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
ffAppendPercentBar(&str, avgValue, 0, 50, 80);
if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
{
if(str.length > 0)
ffStrbufAppendC(&str, ' ');
ffAppendPercentNum(&str, avgValue, 50, 80, str.length > 0);
}
}
else
{
FF_LIST_FOR_EACH(double, percent, percentages)
{
if(str.length > 0)
ffStrbufAppendC(&str, ' ');
ffAppendPercentNum(&str, *percent, 50, 80, false);
}
}
ffStrbufPutTo(&str, stdout);
}
else
{
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
ffAppendPercentNum(&percentageStr, percentage, 50, 80, false);
FF_STRBUF_AUTO_DESTROY avgStr = ffStrbufCreate();
ffAppendPercentNum(&avgStr, avgValue, 50, 80, false);
FF_STRBUF_AUTO_DESTROY minStr = ffStrbufCreate();
ffAppendPercentNum(&minStr, minValue, 50, 80, false);
FF_STRBUF_AUTO_DESTROY maxStr = ffStrbufCreate();
ffAppendPercentNum(&maxStr, maxValue, 50, 80, false);
ffPrintFormat(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_CPUUSAGE_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &percentageStr}
{FF_FORMAT_ARG_TYPE_STRBUF, &avgStr},
{FF_FORMAT_ARG_TYPE_STRBUF, &maxStr},
{FF_FORMAT_ARG_TYPE_UINT, &maxIndex},
{FF_FORMAT_ARG_TYPE_STRBUF, &minStr},
{FF_FORMAT_ARG_TYPE_UINT, &minIndex},
});
}
}
void ffInitCPUUsageOptions(FFCPUUsageOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CPUUSAGE_MODULE_NAME, ffParseCPUUsageCommandOptions, ffParseCPUUsageJsonObject, ffPrintCPUUsage, ffGenerateCPUUsageJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CPUUSAGE_MODULE_NAME, ffParseCPUUsageCommandOptions, ffParseCPUUsageJsonObject, ffPrintCPUUsage, ffGenerateCPUUsageJson, ffPrintCPUUsageHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
}
@@ -57,6 +98,12 @@ bool ffParseCPUUsageCommandOptions(FFCPUUsageOptions* options, const char* key,
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffStrEqualsIgnCase(subKey, "separate"))
{
options->separate = ffOptionParseBoolean(value);
return true;
}
return false;
}
@@ -78,19 +125,40 @@ void ffParseCPUUsageJsonObject(FFCPUUsageOptions* options, yyjson_val* module)
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffStrEqualsIgnCase(key, "separate"))
{
options->separate = yyjson_get_bool(val);
continue;
}
ffPrintError(FF_CPUUSAGE_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
void ffGenerateCPUUsageJson(FF_MAYBE_UNUSED FFCPUUsageOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
double percentage = 0.0/0.0;
const char* error = ffGetCpuUsageResult(&percentage);
FF_LIST_AUTO_DESTROY percentages = ffListCreate(sizeof(double));
const char* error = ffGetCpuUsageResult(&percentages);
if(error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_obj_add_real(doc, module, "result", percentage);
yyjson_mut_val* result = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(double, percent, percentages)
{
yyjson_mut_arr_add_real(doc, result, *percent);
}
}
void ffPrintCPUUsageHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_CPUUSAGE_MODULE_NAME, "{1}", FF_CPUUSAGE_NUM_FORMAT_ARGS, (const char* []) {
"CPU usage (percentage, average)",
"CPU usage (percentage, maximum)",
"CPU core index of maximum usage",
"CPU usage (percentage, minimum)",
"CPU core index of minimum usage",
});
}
+1
View File
@@ -12,3 +12,4 @@ bool ffParseCPUUsageCommandOptions(FFCPUUsageOptions* options, const char* key,
void ffDestroyCPUUsageOptions(FFCPUUsageOptions* options);
void ffParseCPUUsageJsonObject(FFCPUUsageOptions* options, yyjson_val* module);
void ffGenerateCPUUsageJson(FFCPUUsageOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintCPUUsageHelpFormat(void);
+2
View File
@@ -8,4 +8,6 @@ typedef struct FFCPUUsageOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
bool separate;
} FFCPUUsageOptions;
+9 -1
View File
@@ -52,7 +52,7 @@ void ffPrintCursor(FFCursorOptions* options)
void ffInitCursorOptions(FFCursorOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CURSOR_MODULE_NAME, ffParseCursorCommandOptions, ffParseCursorJsonObject, ffPrintCursor, ffGenerateCursorJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CURSOR_MODULE_NAME, ffParseCursorCommandOptions, ffParseCursorJsonObject, ffPrintCursor, ffGenerateCursorJson, ffPrintCursorHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
}
@@ -111,3 +111,11 @@ void ffGenerateCursorJson(FF_MAYBE_UNUSED FFCursorOptions* options, yyjson_mut_d
ffStrbufDestroy(&result.theme);
ffStrbufDestroy(&result.size);
}
void ffPrintCursorHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_CURSOR_MODULE_NAME, "{1} ({2}px)", FF_CURSOR_NUM_FORMAT_ARGS, (const char* []) {
"Cursor theme",
"Cursor size"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseCursorCommandOptions(FFCursorOptions* options, const char* key, cons
void ffDestroyCursorOptions(FFCursorOptions* options);
void ffParseCursorJsonObject(FFCursorOptions* options, yyjson_val* module);
void ffGenerateCursorJson(FFCursorOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintCursorHelpFormat(void);
+1 -1
View File
@@ -19,7 +19,7 @@ void ffPrintCustom(FFCustomOptions* options)
void ffInitCustomOptions(FFCustomOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CUSTOM_MODULE_NAME, ffParseCustomCommandOptions, ffParseCustomJsonObject, ffPrintCustom, NULL);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_CUSTOM_MODULE_NAME, ffParseCustomCommandOptions, ffParseCustomJsonObject, ffPrintCustom, NULL, NULL);
ffOptionInitModuleArg(&options->moduleArgs);
ffStrbufSetStatic(&options->moduleArgs.key, " ");
}
+27 -1
View File
@@ -143,7 +143,7 @@ void ffPrintDateTime(FFDateTimeOptions* options)
void ffInitDateTimeOptions(FFDateTimeOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_DATETIME_MODULE_NAME, ffParseDateTimeCommandOptions, ffParseDateTimeJsonObject, ffPrintDateTime, ffGenerateDateTimeJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_DATETIME_MODULE_NAME, ffParseDateTimeCommandOptions, ffParseDateTimeJsonObject, ffPrintDateTime, ffGenerateDateTimeJson, ffPrintDateTimeHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
}
@@ -183,3 +183,29 @@ void ffGenerateDateTimeJson(FF_MAYBE_UNUSED FFDateTimeOptions* options, yyjson_m
{
yyjson_mut_obj_add_uint(doc, module, "result", ffTimeGetNow());
}
void ffPrintDateTimeHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_DATETIME_MODULE_NAME, "{1}-{4}-{11} {14}:{18}:{20}", FF_DATETIME_NUM_FORMAT_ARGS, (const char* []) {
"year",
"last two digits of year",
"month",
"month with leading zero",
"month name",
"month name short",
"week number on year",
"weekday",
"weekday short",
"day in year",
"day in month",
"day in Week",
"hour",
"hour with leading zero",
"hour 12h format",
"hour 12h format with leading zero",
"minute",
"minute with leading zero",
"second",
"second with leading zero"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseDateTimeCommandOptions(FFDateTimeOptions* options, const char* key,
void ffDestroyDateTimeOptions(FFDateTimeOptions* options);
void ffParseDateTimeJsonObject(FFDateTimeOptions* options, yyjson_val* module);
void ffGenerateDateTimeJson(FFDateTimeOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintDateTimeHelpFormat(void);
+10 -1
View File
@@ -42,7 +42,7 @@ void ffPrintDE(FFDEOptions* options)
void ffInitDEOptions(FFDEOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_DE_MODULE_NAME, ffParseDECommandOptions, ffParseDEJsonObject, ffPrintDE, ffGenerateDEJson);
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_DE_MODULE_NAME, ffParseDECommandOptions, ffParseDEJsonObject, ffPrintDE, ffGenerateDEJson, ffPrintDEHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
}
@@ -93,3 +93,12 @@ void ffGenerateDEJson(FF_MAYBE_UNUSED FFDEOptions* options, yyjson_mut_doc* doc,
yyjson_mut_obj_add_strbuf(doc, obj, "prettyName", &result->dePrettyName);
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->deVersion);
}
void ffPrintDEHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_DE_MODULE_NAME, "{2} {3}", FF_DE_NUM_FORMAT_ARGS, (const char* []) {
"DE process name",
"DE pretty name",
"DE version"
});
}
+1
View File
@@ -10,3 +10,4 @@ bool ffParseDECommandOptions(FFDEOptions* options, const char* key, const char*
void ffDestroyDEOptions(FFDEOptions* options);
void ffParseDEJsonObject(FFDEOptions* options, yyjson_val* module);
void ffGenerateDEJson(FFDEOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module);
void ffPrintDEHelpFormat(void);

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