Compare commits

...

262 Commits

Author SHA1 Message Date
Carter Li c3e5222bcd Merge pull request #978 from fastfetch-cli/dev
Release: v2.14.0
2024-05-30 02:54:50 +00:00
李通洲 c0c76292cb Release: v2.14.0 2024-05-30 10:20:22 +08:00
李通洲 49840a8f70 Vulkan: print reason on error
Ref: #976
2024-05-30 10:13:19 +08:00
李通洲 44257b7ede Shell: don't try to get arg1 if python was executed without extra args 2024-05-30 09:58:06 +08:00
李通洲 d7e9094297 Shell (macOS): better xonsh detection
Fix #977
2024-05-30 09:31:25 +08:00
李通洲 1863bde916 InitSystem: better systemd version detection 2024-05-30 08:45:14 +08:00
李通洲 7c1b6c6a10 CI: test initsystem 2024-05-29 19:13:04 +08:00
李通洲 7e8b204644 InitSystem: resolve real path of exe path 2024-05-29 19:12:43 +08:00
李通洲 e8dc500f24 Processing (Linux): return errors more actively
fix assertion errors
2024-05-29 16:24:18 +08:00
李通洲 bb11cff700 InitSystem: detect version 2024-05-29 14:36:28 +08:00
李通洲 90690ba315 InitSystem: add new module
Fix #974
2024-05-29 11:14:39 +08:00
李通洲 3811bb1be4 TerminalShell: move process info query logic into common place 2024-05-28 23:43:15 +08:00
李通洲 1f3d18cdbc Doc: document --color-separator 2024-05-28 19:13:01 +08:00
李通洲 3ae2047364 Doc: update changelog 2024-05-28 19:12:08 +08:00
Carter Li 66ba5d0a5f Doc: document named placeholders 2024-05-28 16:34:11 +08:00
Carter Li 983e5c680f Display: add option --color-separator 2024-05-28 16:13:06 +08:00
Carter Li 745865d66a Presets: convert hard coded ANSI escape code to formatting placeholders 2024-05-28 16:10:24 +08:00
Carter Li 8bdca1b1a8 Formatting: small optimizations 2024-05-28 15:38:45 +08:00
Carter Li 5172a13b15 Global: fix outputColor doesn't work if module keys are disabled 2024-05-28 15:37:00 +08:00
Carter Li 3ba899261f Util: add ffCharIsDigit and use it 2024-05-28 15:34:59 +08:00
Carter Li 5fa18a8a1c Custom: detect & convert color placeholders ({#xxx}) 2024-05-28 14:23:19 +08:00
Carter Li 81e0af8999 Format: support named color placeholders 2024-05-28 14:03:51 +08:00
Carter Li a14a73b259 Doc: update changelog 2024-05-28 10:25:41 +08:00
Carter Li c8451cab52 Global: support for named format arguments
Fix #796
2024-05-28 10:23:29 +08:00
Dariqq 965777323e Packages (Linux): Add Guix package manager. (#972)
- Add 3 new count results: guixHome, guixSystem and guixUser.
- Add initial detection logic based on neofetch.
- Add a guixAll variable as sum of all guix results.
- Add options to disable guix detection.
2024-05-28 08:50:18 +08:00
Carter Li ad709c4153 README: update screenshot [ci skip] 2024-05-27 10:25:37 +08:00
李通洲 0869bfaeed Doc: update changelog [ci skip] 2024-05-27 09:40:58 +08:00
李通洲 dee208f3e3 Chore: remove unnecessary files [ci skip] 2024-05-27 08:49:47 +08:00
李通洲 7e1c426e34 README: add more installation methods [ci skip] 2024-05-26 10:16:32 +08:00
Carter Li 0ae2d389da CMake: we support FreeBSD only, not OpenBSD nor NetBSD 2024-05-26 10:16:32 +08:00
Anonyzard 20b433f40a Logo: Cereus Linux (#968)
* Logo: Add Cereus Linux

* Update cereus.txt

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-05-26 09:39:44 +08:00
李通洲 152f5d3fa6 Revert "OS (Linux): remove special handling of Loc-OS"
This reverts commit 5ec272acff.
2024-05-26 09:38:35 +08:00
李通洲 b030bd6751 README: add example of FIGlet text logo [ci skip] 2024-05-25 15:22:28 +08:00
李通洲 e0d5a9024a Logo (File / Data): apply default color palettes 2024-05-25 14:36:20 +08:00
李通洲 f83a31e0a6 Presets: update examples/7.jsonc to fix archlinux compatibility 2024-05-25 09:54:42 +08:00
李通洲 099e2b5f8f Editor (Windows): support editor version detection 2024-05-24 23:50:19 +08:00
lucsansag 374997b599 Board: fix typo (#965) 2024-05-24 19:50:26 +08:00
李通洲 f938f5e03b CMake: remove useless code 2024-05-24 16:44:15 +08:00
李通洲 d7098e728d CMake: set link library dirs 2024-05-24 15:48:18 +08:00
Carter Li 5302a82444 Fastfetch: disable dlsym function call if dlopen is disabled 2024-05-24 15:30:35 +08:00
Carter Li 64a3573c49 Packaging: update debian stuff 2024-05-24 14:44:15 +08:00
Carter Li 3d48de8c98 CMake: be able to build as a dynamic linked binary 2024-05-24 14:40:14 +08:00
李通洲 4b33e1b691 Terminal (Windows): don't try to detect terminals in MSYS shell
May fix CI hanging
2024-05-24 11:07:52 +08:00
李通洲 6326405c26 Percentage: support monochrome bar type
Fix #961
2024-05-24 10:19:58 +08:00
李通洲 b25e8c2721 Fastfetch: list available presets in exe path
For better winget support
2024-05-24 09:18:48 +08:00
李通洲 81318f45bb Fastfetch: don't detect .conf in --list-config-paths 2024-05-24 09:09:12 +08:00
Carter Li 2f6cabb839 Library: prepare for static linking 2024-05-23 16:35:16 +08:00
李通洲 4fd65ad0b8 CI: try fixing musl build 2024-05-23 13:31:53 +08:00
李通洲 6ecb383a6a Editor: remove unused functions 2024-05-23 09:00:16 +08:00
Carter Li 1b3977fc47 Merge pull request #958 from fastfetch-cli/dev
Release v2.13.2
2024-05-22 12:12:15 +00:00
李通洲 f00969cb81 Editor: fix path detection not working on Android 2024-05-22 18:38:25 +08:00
李通洲 b3e79477a6 EDITOR: always print exe in JSON results 2024-05-22 16:40:37 +08:00
李通洲 82c7f27ae7 Release: v2.13.2 2024-05-22 16:32:35 +08:00
李通洲 624a4956fc CI: test more functions 2024-05-22 16:32:35 +08:00
李通洲 30a5dd52b1 Editor: add new module
Fix #430
2024-05-22 16:32:27 +08:00
李通洲 92136370bb CI: add bootmgr 2024-05-22 16:09:09 +08:00
李通洲 d196b8079e GPU (Linux): don't query DRM drivers for driver version
Fix #956
2024-05-22 13:37:50 +08:00
李通洲 a3dbac7dfc Completion (Fish): fix compatibility for old python versions 2024-05-22 10:34:07 +08:00
李通洲 59c853fb01 GPU: write & use our own simplified nvml header 2024-05-21 22:31:36 +08:00
李通洲 5ec272acff OS (Linux): remove special handling of Loc-OS
Unless a proper reason is provided
2024-05-21 18:53:31 +08:00
CuerdOS c72fdab301 Logo (Builtin): Added CuerdOS support (#954)
* Added CuerdOS support

* Update os_linux.c

* Update os_linux.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-05-21 18:51:48 +08:00
李通洲 183f12d8b5 Presets: fix bad nerd icons 2024-05-21 15:47:37 +08:00
Carter Li 395810cd79 DisplayServer (Wayland): don't display eDP-1-unknown 2024-05-21 14:25:09 +08:00
Carter Li 36cf5856b5 Merge pull request #952 from fastfetch-cli/dev
Release: v2.13.1
2024-05-21 01:42:10 +00:00
李通洲 01d1336cf0 CPU (FreeBSD): remove unused variables 2024-05-21 09:28:21 +08:00
李通洲 28f2e9ea96 Release: v2.13.1 2024-05-21 09:24:53 +08:00
Carter Li 2d4e7f10c4 CPU: add option --show-pe-core-count 2024-05-21 09:21:03 +08:00
Carter Li aa1a5b8c36 CPU: fix CPU frequency not displayed if bios_limit doesn't exist
Regression of 264b6794f3
2024-05-21 08:44:49 +08:00
Carter Li 43bdb68cbf Merge pull request #949 from fastfetch-cli/dev
Release: v2.13.0
2024-05-20 13:28:45 +00:00
李通洲 8b43e331e3 GPU (Linux): silence compiler warnings 2024-05-20 21:07:28 +08:00
李通洲 302716fa61 GPU: silence compiler warnings 2024-05-20 20:43:24 +08:00
李通洲 188b6aba10 Release: v2.13.0 2024-05-20 20:40:25 +08:00
李通洲 7af9cab688 CI: try fixing Win32 build 2024-05-20 19:37:14 +08:00
李通洲 714b88c638 Packages (Linux): try fixing nix-user detection
Fix #937
2024-05-20 19:14:32 +08:00
李通洲 d9f1db10aa Completions (Fish): disable enum value suggestion 2024-05-20 19:05:38 +08:00
李通洲 bb10e1c9a3 Doc: update help message of --gpu-detection-method 2024-05-20 19:04:57 +08:00
李通洲 264b6794f3 CPU (Linux): detect bios limited frequency and print it by default
To match neofetch's behavior

Fix #947
2024-05-20 18:35:10 +08:00
Carter Li a8b734c877 GPU: change option --gpu-force-vulkan to --gpu-detection-method 2024-05-20 16:46:04 +08:00
Carter Li 10ca77610e GPU (Linux): detect GPU core count and freq for asahi linux 2024-05-20 15:32:13 +08:00
Carter Li c2eaea3665 Logo (Builtin): fix KDE neon
Fix #948
2024-05-20 15:31:18 +08:00
Carter Li 1619f0ab6c GPU (Linux): fix memory leaks 2024-05-20 11:00:51 +08:00
李通洲 aba211221b Doc: update README [ci skip] 2024-05-19 23:07:10 +08:00
李通洲 81485baadb CPU: better compatibility for Intel CPUs 2024-05-19 22:18:07 +08:00
李通洲 1b4fc38330 GPU (Linux): detect drm driver version 2024-05-19 22:18:06 +08:00
李通洲 3571d9277d CPU (Linux): take --cpu-freq-ndigits into account in --cpu-format 2024-05-19 22:18:06 +08:00
李通洲 e9b535d277 GPU (Linux): improve perf 2024-05-19 22:18:06 +08:00
李通洲 09ffd32144 GPU (Linux): improve Intel GPU detection code 2024-05-19 22:18:06 +08:00
Sergey Fedorov 27aa5c0343 opencl.c: unbreak build on macOS with no OpenCL support (#940)
Fixes: https://github.com/fastfetch-cli/fastfetch/issues/939
2024-05-19 21:51:46 +08:00
Sergey Fedorov 1d95f9b224 CMakeLists: unbreak build with GCC on macOS (#941) 2024-05-19 21:46:34 +08:00
李通洲 4f1cb779ab OS (Linux): fix BUILD_ID not parsed 2024-05-19 11:12:38 +08:00
Shu Niu 758ddae344 macOS: Add support for old MacOS version (#936)
* Add support for old MacOS version,  fix-1.

* Add support for old MacOS version,  fix-2.

* Add support for old MacOS version with fixing metal gpu api.

* Update disk_bsd.c

* Update disk_bsd.c

* Update gpu_apple.m

* Update monitor_apple.m

* Update os_apple.m

* Update wifi_apple.m

* Update camera_apple.m

* Update camera_apple.m

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-05-19 09:31:08 +08:00
李通洲 14969b31d0 CPU (Windows): fix silly mistake 2024-05-18 20:53:11 +08:00
李通洲 d88e2eeb36 CPU (macOS): fix compiling 2024-05-18 19:57:24 +08:00
李通洲 7946e69a66 CPU: print core count for different core types 2024-05-18 18:08:38 +08:00
Carter Li 15766f5266 Disk (BSD): dont set createTime if stat fails to detect it 2024-05-18 13:38:07 +08:00
Carter Li ed02845c40 OS (Linux): better code name detection 2024-05-18 13:11:22 +08:00
Carter Li 4ffa0ffcb7 Disk (FreeBSD): ensure createTime is inited 2024-05-18 13:09:37 +08:00
Carter Li c04c040713 Wifi (FreeBSD): fix bssid & status detection 2024-05-18 11:58:35 +08:00
Matheus Castello c763896b49 Logo (builtin): Fix TorizonCore logo colors (#934)
You can verify the colors of the logo from https://www.torizon.io/

Signed-off-by: Matheus Castello <matheus.castello@toradex.com>
2024-05-18 11:57:21 +08:00
李通洲 e9a44f71b2 Bootmgr (Android): fix compiling 2024-05-18 11:08:21 +08:00
李通洲 5078c8d910 Revert "GPU (Windows): try removing limitation"
This reverts commit eda9496479.
2024-05-18 10:39:51 +08:00
李通洲 f9e0efb7ee Smbios: improve SMBIOS data reading code 2024-05-18 10:35:17 +08:00
Carter Li 926390508e CPU (FreeBSD): fix core count detection 2024-05-18 16:43:33 +08:00
Carter Li 45446c1c1d Bootmgr (FreeBSD): silence compiler warnings 2024-05-18 16:41:30 +08:00
Carter Li b79c47cac9 CPU (BSD): fix max freq detection 2024-05-18 01:50:21 +08:00
Carter Li fd16e69464 CPU (macOS): fix core count detection 2024-05-18 01:46:56 +08:00
李通洲 92abf3e063 TerminalShell (Linux): ignore valgrind 2024-05-18 00:34:08 +08:00
Carter Li 90a242a4aa CPU (BSD): detect max / min frequency; detect core count of different core types 2024-05-18 00:34:08 +08:00
furretpaws 1118c57d8f Logo (Builtin): Added "Furreto Linux" support (#927)
* added furreto

* fixed

* fix i think

* Update furreto.txt

Remove left padding and empty lines. Replace `${cN}` with `$N`

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-05-18 00:28:34 +08:00
李通洲 eda9496479 GPU (Windows): try removing limitation 2024-05-17 21:42:11 +08:00
李通洲 0b94ff5adb CPU (Windows): detect core count of different core types 2024-05-17 21:31:24 +08:00
李通洲 62bf3ec021 Util (Windows): add nt.h and use it 2024-05-17 21:30:47 +08:00
李通洲 ab2268a927 CPU (macOS): detect core count for different core types 2024-05-17 16:47:26 +08:00
Carter Li 1421627a47 CPU (Linux): detect core count for different core types 2024-05-17 08:35:22 +00:00
李通洲 02e5232bda TerminalShell: ignore clifm
Ref: https://github.com/leo-arch/clifm/issues/289
2024-05-17 13:57:07 +08:00
李通洲 289d03cfb2 Kernel (Windows): detect old release code name for Windows 10 2024-05-17 10:34:04 +08:00
李通洲 965ab1abc4 Packages: don't break existing config 2024-05-17 09:28:17 +08:00
Anonyzard 06b2ff9a08 Add Loc-OS Linux support (#926)
* Logo (Builtin): add Loc-OS

* Packages (Linux): add lpkg and lpkgbuild detection
2024-05-17 09:19:26 +08:00
李通洲 b4a6606faf Doc: update FAQ [ci skip] 2024-05-16 23:47:25 +08:00
李通洲 def758580f Doc: update FAQ [ci skip] 2024-05-16 23:34:40 +08:00
李通洲 5ea2b2ecc9 Doc: update FAQ [ci skip] 2024-05-16 23:26:07 +08:00
李通洲 b3886c6c47 Doc: update FAQ section [ci skip] 2024-05-16 21:58:43 +08:00
李通洲 bc76220a5b Doc: update JSON schema [ci skip] 2024-05-16 18:48:27 +08:00
李通洲 60fa7946f5 Logo (Builtin): fix build 2024-05-16 18:30:40 +08:00
SpoinkOSDevs b6a703bd56 Logo (builtin): Add SpoinkOS Logo [FIXED!] (#925)
* Update builtin.c

* Create spoinkos.txt

* Fix coding style

* Remove left padding

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-05-16 16:44:01 +08:00
李通洲 462c3b0e06 Bios / Bootmgr: update descriptions 2024-05-16 16:37:57 +08:00
李通洲 72138dbde5 Bootmgr (macOS): add support 2024-05-16 16:27:37 +08:00
李通洲 b2ea5d8f3e Bootmgr: reuse shared code 2024-05-16 13:24:34 +08:00
Carter Li 49080c5361 Bootmgr (FreeBSD): add support
Requires root permission
2024-05-16 11:01:11 +08:00
李通洲 445dd94b53 Bootmgr: add new module 2024-05-15 21:49:15 +08:00
李通洲 7c03fc1550 Bios: move bootmgr detection to a new module 2024-05-15 21:40:18 +08:00
李通洲 06a8f12d6a Bios (Windows): detect secure boot state & boot manager
Boot manager detection requires Administrator privilege to work
2024-05-15 20:39:22 +08:00
Carter Li 8c7edf4d2d Bios (Linux): detect boot manager & secure boot 2024-05-15 19:00:26 +08:00
李通洲 85b4679373 Logo: fix Manjaro Linux
Fix #921
2024-05-14 22:04:37 +08:00
Carter Li 215029ea27 Merge pull request #919 from fastfetch-cli/dev
Release: v2.12.0
2024-05-14 15:53:45 +08:00
李通洲 533f54fb73 Doc: update changelog [ci skip] 2024-05-14 15:20:22 +08:00
李通洲 a6212c5b01 PhysicalMemory: add Ramaxel vendor id support 2024-05-14 14:11:12 +08:00
李通洲 ba76b18367 Fastfetch: remove support of flag based config 2024-05-14 14:08:54 +08:00
李通洲 4290efb49d Release: v2.12.0 2024-05-14 10:48:21 +08:00
李通洲 30b85fc169 JsonConfig: report row and column on JSON parsing errors 2024-05-14 10:47:20 +08:00
李通洲 dc94ac8d0c Doc: update json_schema 2024-05-14 10:25:29 +08:00
李通洲 1d9e612262 Presets: update [ci skip] 2024-05-14 09:11:27 +08:00
李通洲 be1791e386 LocalIP: add option --localip-show-all-ips 2024-05-13 23:33:06 +08:00
李通洲 3b8c2d6ee6 Logo (Builtin): add Quirinux 2024-05-13 22:27:35 +08:00
Null-Ping c661e55053 PhysicalMemory: Fix ram vendor names from ids. (#917)
Change 0x0198 from HyperX to Kingston to match https://www.jedec.org/standards-documents/docs/jep-106ab. (The standard does not contain an entry for HyperX at all).
Remove the ambiguous 0x1315 - according to the standard, it belongs to Tioga Technologies and not Crucial.
Rename Hynix to SK Hynix to match the standard.
2024-05-13 22:20:27 +08:00
李通洲 56403bab5c PhysicalMemory: try converting vendor ID to name 2024-05-13 20:29:46 +08:00
李通洲 caef317ade GPU: a tiny optimization 2024-05-13 19:33:31 +08:00
李通洲 131e01f35b Presets: add archey
Ref: https://github.com/HorlogeSkynet/archey4
2024-05-13 16:45:14 +08:00
李通洲 c8e3c6882a Kernel: print kernel name in default format 2024-05-13 16:41:00 +08:00
李通洲 c985bdbbfd Logo: add macOS3 2024-05-13 15:50:10 +08:00
李通洲 b80eb47ecd PhysicalMemory: better Linux compatibility 2024-05-13 15:08:27 +08:00
Carter Li 68942c1d3f PhysicalMemory (FreeBSD): fix EFAULT errors 2024-05-13 11:06:05 +08:00
李通洲 b36b74448f Doc: update changelog 2024-05-12 20:24:56 +08:00
李通洲 217bb6657e PhysicalMemory: fix output format 2024-05-12 20:17:57 +08:00
李通洲 df2862996b PhysicalMemory: detect ecc & bank locator 2024-05-12 19:55:04 +08:00
李通洲 df6ab6427e PhysicalMemory: improve default output format; detect part number 2024-05-12 19:15:03 +08:00
李通洲 82d848727c Logo (Builtin): fix alternate logo doesn't work with type builtin
Fix #914
2024-05-12 18:32:05 +08:00
李通洲 d0d6323b1f PhysicalMemory (FreeBSD): add support 2024-05-12 18:32:05 +08:00
李通洲 6439921f85 Smbios (Windows): check if getting SMBIOS data succeeds 2024-05-11 18:07:56 +08:00
李通洲 d28907ee9d PhysicalMemory (Linux): add support
Note: this module requires root permission to work in Linux
2024-05-11 18:05:30 +08:00
李通洲 41f0971570 PhysicalMemory: ignore trash values 2024-05-11 15:12:28 +08:00
李通洲 ab0bd79bb8 PhysicalMemory: add module to ci.jsonc and all.jsonc 2024-05-11 15:05:43 +08:00
李通洲 07747aa819 PhysicalMemory (macOS): add support 2024-05-11 15:05:43 +08:00
李通洲 68efcdd0dd PhysicalMemory: add new module 2024-05-11 15:05:43 +08:00
李通洲 fef3100fd7 Smbios: add struct layout check 2024-05-11 15:05:43 +08:00
Bernhard M. Wiedemann 08a940bfd4 Logo: Add the openSUSE Slowroll distribution (#913) 2024-05-11 15:03:13 +08:00
李通洲 d6a99c631e Image: support specifying --logo-width only for --kitty-direct and --iterm
Fix: #836

Ref: https://github.com/kovidgoyal/kitty/issues/7424
2024-05-10 14:30:00 +08:00
李通洲 3d4077c2d0 Config: support more color prefixes 2024-05-10 13:39:06 +08:00
djinnalexio ce6b595421 🔧 JsonConfig: add missing brightness properties 2024-05-10 11:13:47 +08:00
djinnalexio 7d8c085254 🔧 JsonConfig: add dim colors to validation 2024-05-10 11:13:47 +08:00
Souma ec0af17fb5 Terminal (macOS): fix compatibility with (*term) (#909)
Ignore <shell> (<char>term).
This is because Fig(<shell> (figterm)) migrated to CodeWhisperer(<shell> (cwterm)) and CodeWhisperer renamed to Q(<shell> (qterm)).
Future changes will all be ignored by this change.
Related: #676
2024-05-09 19:39:17 +08:00
李通洲 2accfbc894 Networking (Windows): fix compiling 2024-05-09 16:35:51 +08:00
李通洲 01d2fa1228 Doc: update changelog (ci skip) 2024-05-09 16:32:10 +08:00
李通洲 f16843d60f Doc: update changelog 2024-05-09 16:27:24 +08:00
李通洲 acc77ebddd PublicIP: add option --publicip-ipv6 2024-05-09 15:54:49 +08:00
李通洲 7eb145fb7f Presets: add loadavg to all.jsonc and ci.jsonc 2024-05-09 09:56:34 +08:00
Carter Li 34a6eb13c6 Loadavg (BSD): add missing headers 2024-05-09 09:51:41 +08:00
李通洲 0f5e746fe2 Loadavg: add option --loadavg-ndigits 2024-05-09 09:40:53 +08:00
李通洲 b62ad16aa6 Loadavg (BSD): use sysctl 2024-05-09 09:20:18 +08:00
李通洲 f79498e4b5 PublicIP / Weather: clarify error messages
Fix #907
2024-05-09 08:49:25 +08:00
李通洲 31c433b353 Display: rename --temperature-* to --temp-* as stated in help messages
Fix #908
2024-05-09 08:46:59 +08:00
李通洲 852c6abf2e Loadavg (Android): fix compiling 2024-05-08 21:54:13 +08:00
Quinten Van Damme df3fa6f8a8 Logo: Fix dahliaOS detection (#906) 2024-05-08 19:30:25 +08:00
李通洲 738daa1c77 Loadavg: new module 2024-05-08 18:34:34 +08:00
李通洲 4204cfc500 Doc: update help message for --module-output-color 2024-05-08 16:17:05 +08:00
李通洲 9cb08d115a Separator: add --separator-output-color 2024-05-08 16:11:16 +08:00
李通洲 459f159b1b Fastfetch: revert to module color after printing custom colors 2024-05-08 15:25:59 +08:00
李通洲 2880536513 Fastfetch: support --module-ouput-color (WIP) 2024-05-08 15:01:57 +08:00
李通洲 64cb1bfdfd Doc: remove duplicated entry 2024-05-08 14:33:00 +08:00
李通洲 b80c30ace3 Doc: default --hide-cursor to false 2024-05-08 11:06:38 +08:00
李通洲 19b8849bfc Fastfetch: remove the long deprecated flag --set & `-set-keyless 2024-05-08 11:06:03 +08:00
Carter Li 8f457f047c TerminalFont (Linux): searching for font config in st binary 2024-05-08 09:54:33 +08:00
Carter Li 299bc7468f Terminal (Linux): fix exePath detection 2024-05-08 09:54:33 +08:00
Carter Li c213b0769b Merge remote-tracking branch 'origin/master' into dev 2024-05-07 09:34:02 +08:00
AcatXIo 260c883d07 Presets: Update hardware.jsonc (#899)
Update hardware.jsonc preset, fix logo being forced to arch, add more hardware information.
2024-05-07 08:54:36 +08:00
Carter Li da0db042fa Merge pull request #897 from fastfetch-cli/dev
Release: 2.11.5
2024-05-07 00:41:44 +08:00
李通洲 ae5732e2a8 Release: v2.11.5 2024-05-07 00:38:08 +08:00
李通洲 1f05a33807 Logo (Builtin): temp fix for openmandriva logo detection
Fix #896
2024-05-07 00:19:07 +08:00
李通洲 f090951abc Doc: remove --os-file completely 2024-05-06 22:48:46 +08:00
Carter Li 855fd6edee Merge pull request #890 from fastfetch-cli/dev
Release v2.11.4
2024-05-06 20:06:58 +08:00
李通洲 d4bd4401a8 Release: v2.11.4 2024-05-06 19:45:45 +08:00
李通洲 689feb39a4 OS (Linux): don't detect debian version on debian derived distros 2024-05-06 18:42:19 +08:00
Carter Li 0f64e2830a OS (Linux): detect pve & armbian 2024-05-06 16:46:27 +08:00
Carter Li 3e24cdc752 CMake: add option CUSTOM_OS_RELEASE_PATH
And remove `--os-file`
2024-05-06 16:25:08 +08:00
李通洲 dc9c285a0b Doc: update README
Who cares how people install a package...

Close #883
2024-05-06 15:56:46 +08:00
李通洲 1d03c9c85e Logo (Builtin): add armbian
Fix #842
2024-05-06 15:22:43 +08:00
李通洲 4eae11df64 Presets: fix neofetch 2024-05-06 15:09:12 +08:00
李通洲 eba13d5485 JsonConfig: fix setting size.ndigits doesn't work
Silly copy & paste error
2024-05-06 15:08:58 +08:00
apocelipes 16b875ef5a Fastfetch: fix memory leaks when passing informative options
Informative options (e.g. "--help", "--list-module") make fastfetch
exit before calling ffDestroyInstance. Using "atexit" to avoid this
kind of leak.
2024-05-06 14:40:27 +08:00
李通洲 366138e1bd CI: try fixing Linux armv7 2024-05-06 14:08:29 +08:00
李通洲 7fe18a5b7c CI: build armv7 package using ubuntu22.04
Hopefully make it usable on RaspberryPi

Fix #884
2024-05-06 09:33:58 +08:00
李通洲 39cd8cfb4c Camera: fix deprecation warning for macOS 14.0 hopefully
Fix #860
2024-05-06 09:25:06 +08:00
李通洲 8b441c85e5 Logo (Builtin): update ubuntu 2024-05-05 23:31:23 +08:00
李通洲 f66e901c44 Presets: remove unsupported format placeholders 2024-05-05 22:12:33 +08:00
李通洲 3815823a20 CMake: enforce glibc version 2024-05-05 21:29:49 +08:00
李通洲 33ff4870dc Fastfetch: enable pipe mode if $NO_COLOR is set 2024-05-05 20:16:43 +08:00
李通洲 479731f076 Custom: don't print ANSI escape code in pipe mode 2024-05-05 20:14:24 +08:00
李通洲 d2f3f47457 Colors: print non-colored blocks in pipe mode 2024-05-05 20:14:24 +08:00
李通洲 5ea89ecba5 Fastfetch: print non-colored logo in pipe mode 2024-05-05 20:14:23 +08:00
Carter Li 865f57bd76 Revert "FFstrbuf: avoid redundant checks (#881)" (#882)
This reverts commit e98e2a3d52.
2024-05-05 18:46:22 +08:00
Nour1248 e98e2a3d52 FFstrbuf: avoid redundant checks (#881) 2024-05-05 18:40:59 +08:00
Carter Li 6bb748869e Terminal (macOS): fix Apple Terminal detection
Fix #878
2024-05-05 13:36:14 +08:00
李通洲 654721b8c5 Doc: remove (kind of) outdated information
Fix #867
2024-05-05 08:39:51 +08:00
Carter Li 0542eac1b9 Doc: metion ANSI 256 colors
Fix #869
2024-05-05 07:33:32 +08:00
apocelipes b9faf8d77f fastfetch: fix #868 (#871)
Fix #868.
2024-05-05 07:10:51 +08:00
Carter Li 61f848146a Merge pull request #862 from fastfetch-cli/dev
Release: v2.11.3
2024-05-04 20:47:54 +08:00
李通洲 4175dfdc3a Doc: update changelog (ci skip) 2024-05-04 20:27:26 +08:00
李通洲 861d9006d7 Release: v2.11.3 2024-05-04 20:11:30 +08:00
李通洲 7ba07bd2e0 Logo (Image): partially revert 71cba24
Images in SSH session and tmux do work for me

Fix #861
2024-05-04 19:43:41 +08:00
李通洲 9fee36a286 Logo (Image): ensure line ending is printed when printing errors 2024-05-04 19:14:45 +08:00
李通洲 2fc9230b29 Disk (Windows): use sub thread to check accessiblity of remote volumes. 2024-05-04 15:15:00 +08:00
李通洲 5fb1286e15 Battery (Windows): simplify code 2024-05-04 12:11:42 +08:00
李通洲 a4cace4765 CMake: add CUSTOM_AMDGPU_IDS_PATH 2024-05-04 10:06:49 +08:00
李通洲 c6d2467a83 Merge remote-tracking branch 'upstream/master' into dev 2024-05-04 10:06:40 +08:00
AxeldeWater db0d38202e Update README.md again for same reason different location (#857)
Oversaw a place where it wasn't updated either
2024-05-04 07:13:38 +08:00
AxeldeWater 9fbb23b135 Update README.md about installing fastfetch on Debian/Ubuntu (#856)
Apparently the file naming standard was changed over time but this was not updated in the README
2024-05-04 00:00:44 +08:00
李通洲 3a990e495b PhysicalDisk: fix temp output in custom formation
I hate `void *`
2024-05-03 20:48:51 +08:00
李通洲 648530ee8f PhysicalDisk: fix doubled output in custom formation
Fix #852
2024-05-03 20:42:39 +08:00
Carter Li b12a59cdaf Merge pull request #851 from fastfetch-cli/dev
Release: v2.11.2
2024-05-03 14:36:04 +08:00
李通洲 83c1fe26e6 Doc: update changelog 2024-05-03 14:14:13 +08:00
李通洲 217f98a36c Global: tidy json result formats 2024-05-03 13:56:19 +08:00
李通洲 1011e21ba8 Processing: trim \r on Windows 2024-05-03 13:46:28 +08:00
李通洲 08c6a6e4cb OS (macOS): don't print build id
Remove special handling
2024-05-03 13:20:23 +08:00
李通洲 5e9fcaf7ca OS (Linux): don't use rolling as os version 2024-05-03 13:09:14 +08:00
李通洲 8b838cef61 OS (Linux): fix name detection for MX
Fix #847
2024-05-03 12:57:51 +08:00
李通洲 22d9d8e196 OS (Linux): fix OS detection for MX Linux (2nd attempt)
Ref: #847
2024-05-03 11:28:59 +08:00
李通洲 a789b8330a Doc: update logo_request.md 2024-05-03 10:10:13 +08:00
李通洲 903ecf37f7 Chore: silience some warnings 2024-05-03 10:07:16 +08:00
李通洲 c4a876f6aa OS (Linux): Prioritize lsb-release over os-release
Fix #847
2024-05-03 10:00:18 +08:00
李通洲 82285ebeb4 Release: 2.11.2 2024-05-03 10:00:18 +08:00
李通洲 36dadcdc7f Logo (Builtin): add MX2 & fix mx distro detection
Fix: #847
2024-05-03 09:11:59 +08:00
李通洲 030c05429a Logo (Builtin): add missing FF_LOGO_LINE_TYPE_SMALL_BIT flags 2024-05-03 09:11:59 +08:00
李通洲 a462a12370 Logo (Builtin): fix distro name of DraugerOS 2024-05-03 09:11:59 +08:00
李通洲 b386365d95 Logo (Builtin): fix ascii file name 2024-05-03 09:11:59 +08:00
李通洲 158db9d7c7 Logo (Builtin): add KernelOS
Fix #848
2024-05-03 09:11:59 +08:00
李通洲 407bfa8c95 Shell: don't try detecting version of raw sh shell
Fix #849
2024-05-03 09:11:59 +08:00
李通洲 1449290e9e GPU (Linux): check NULL returned by opendir
Fix #845
2024-05-03 09:11:59 +08:00
李通洲 4c0ea7354d Logo (Image): only print error if --show-error is specified 2024-05-03 09:11:59 +08:00
李通洲 71cba2451a Logo: disable image logos in ssh and tmux sessions 2024-05-03 01:10:04 +08:00
李通洲 ef3b5df048 Doc: update man page 2024-05-03 01:10:04 +08:00
Juan 3e98034e55 Packages (Linux): check xdg state home for nix user packages (#844)
Check $XDG_STATE_HOME/nix/profile if ~/.nix-profile is not found as addressed in #837.

Fix #837
2024-05-02 22:55:50 +08:00
李通洲 1c89101522 Doc: update changelog 2024-05-02 20:45:46 +08:00
245 changed files with 6394 additions and 13431 deletions
+2 -5
View File
@@ -7,6 +7,8 @@ assignees: ''
---
Be sure to read [FAQ](https://github.com/fastfetch-cli/fastfetch?tab=readme-ov-file#faq) before submitting a new issue.
<!-- We will try hard to solve the issue. However since platforms and hardwares vary greatly, it can be hard to find the root cause is. Providing following information may help us greatly. Thanks in advance -->
# General description of bug:
@@ -74,10 +76,5 @@ Use `time fastfetch --stat` to show time usage for each module.
## If fastfetch behaves incorrectly on shell starting
<!-- NOTE for zsh / p10k users:
There are known incompatibility between fastfetch and p10k instant prompt.
The p10k doc clearly states that you should NOT print anything to stdout after p10k-instant-prompt is initialized.
You should either put `fastfetch` before initialization of p10k-instant-prompt (recommended), remove it or use `fastfetch --pipe false` -->
* The bug is reproduceable with fresh / clean shell configuration (i.e. `fastfetch` is the single line of `.zshrc` or `~/.config/fish/config.fish`):
* Does `sleep 1` before running `fastfetch` work?
+1 -17
View File
@@ -7,23 +7,7 @@ assignees: ''
---
## Before requesting a new feature
* A lot of features are not enabled by default. Please try `fastfetch --list-modules` and `fastfetch -c all.jsonc` to see if it has been supported
* Fastfetch supports `Command` module, which can be used to grab output from a custom shell script. Please check if it fits your needs
```jsonc
// ~/.config/fastfetch/fastfetch.jsonc
{
"modules": [
{
"type": "command",
"text": "/path/to/your/script",
"key": "Feature Title"
}
]
}
```
Be sure to read [FAQ](https://github.com/fastfetch-cli/fastfetch?tab=readme-ov-file#faq) before submitting a new issue.
## Wanted features:
+1 -1
View File
@@ -11,7 +11,7 @@ Tip: A logo can be displayed by fastfetch without getting into fastfetch's offic
# OS
```
Paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
Paste content of /etc/os-release and /etc/lsb-release here. If none of these files exist, describe a way to identify the distro
```
# Ascii
+10 -3
View File
@@ -173,11 +173,15 @@ jobs:
id: runcmd
with:
arch: armv7
distro: ubuntu22.04
distro: ubuntu20.04
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev directx-headers-dev rpm
apt-get update && apt-get install -y wget
# CMake installed by apt has bug `list sub-command REMOVE_ITEM requires two or more arguments`
wget --no-check-certificate https://apt.kitware.com/ubuntu/pool/main/c/cmake/{cmake_3.29.2-0kitware1ubuntu20.04.1_armhf.deb,cmake-data_3.29.2-0kitware1ubuntu20.04.1_all.deb}
dpkg -i *.deb
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev directx-headers-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
@@ -201,6 +205,8 @@ jobs:
- name: setup alpine linux
uses: jirutka/setup-alpine@master
with:
branch: v3.19
- name: install dependencies
run: |
@@ -240,6 +246,7 @@ jobs:
- name: setup alpine linux
uses: jirutka/setup-alpine@master
with:
branch: v3.19
arch: aarch64
- name: install dependencies
@@ -480,7 +487,7 @@ jobs:
with:
msystem: CLANG32
update: true
install: git mingw-w64-clang-i686-7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd
- name: print msys version
run: uname -a
+1
View File
@@ -8,3 +8,4 @@ cscope.*
tags
fastfetch.kdev4
*.user
*.user.*
+193 -3
View File
@@ -1,21 +1,211 @@
# 2.14.0
Features:
* Support monochrome bar type (#960)
* Support editor version detection on Windows (Editor, Windows)
* Apply default color palettes in `--file` and `--data` (Logo)
* Print all presets in `--list-presets` for better Windows support (Windows)
* Support for guix package manager detection (Packages, Linux)
* Support named variable placeholders in custom module formattion string (#796)
* `--title-format '{user-name-colored}{at-symbol-colored}{host-name-colored}'` is equivalent to `--title-format '{6}{7}{8}'`
* Support named color placeholders in custom module formattion string
* `--<module>-format '{#red}'` is equivalent to `--<module>-format '{#31}'`
* `'{#red}'` or `'{#31}'` is preferred over `\u001b[31m` because is more readable and `--pipe` aware (will be ignored in pipe mode)
* Supported in `Custom` module too
* See `fastfetch -h format` for detail
* Add option `--color-separator` to set the color of key-value separators
* Support Guix package manager count (#792, Packages, Linux)
* Improve python based shell detection (#977, Shell, macOS)
* Print error reason when vulkan init fails (Vulkan)
Bugfixes:
* Don't detect `.conf` files in `--list-config-paths`
* Don't try to detect terminals in MSYS shell with process backtracing (Windows)
* Fix `outputColor` doesn't work if module keys are disabled
Logos:
* Add Cereus Linux
* Re-add special handling of Loc-OS
# 2.13.2
Another hotfix release :(
Bugfixes:
* Remove DRM driver version detection feature, which caused a performance regression for nouveau drivers (#956, Display, Linux)
* Fix compatibility for old python versions. Regression of `2.13.0`
* Don't use `*-unknown` as display name for Wayland protocol (Display, Linux)
Features:
* Add new module `Editor` which prints information of the default editor, i.e. $VISUAL or $EDITOR (#430, Editor)
Logos:
* Added CuerdOS
* Remove special handling of Loc-OS
# 2.13.1
Fix a regression introduced in v2.13.0
Bugfixes:
* Fix CPU frequency not displayed if `bios_limit` is not available (CPU, Linux)
Features:
* Add `--cpu-show-pe-core-count` to detect and display core count for performance / efficiency cores (CPU, FreeBSD)
# 2.13.0
Changes:
* Option `--gpu-force-vulkan <?bool>` has been changed to `--gpu-detection-method <enum>`
* Use `--gpu-detection-method vulkan` to get the old behavior
* See `fastfetch -h gpu-detection-method` for detail
* In Linux, BIOS limited CPU frequency is printed by default to match the behavior of neofetch (CPU, Linux, #947)
Features:
* Add new module `Bootmgr` which prints information of stage 2 bootloader (grub, system-boot, etc)
* Requires root permission to work on Windows and FreeBSD
* Requires booting in UEFI mode
* Add package manager lpkg and lpkg-build support (Packages, Linux)
* Improve macOS 10.13 compatibility (macOS)
* Detect core count for performance / efficiency cores (CPU)
* Test it with `fastfetch -s cpu --cpu-format '{9}'`
* Support min / max frequency and physical core count detection in FreeBSD, if kernel supports it (CPU, FreeBSD)
* Detect DRM driver version if DRM detection method is used (GPU, Linux)
Bugfixes:
* Don't detect `clifm` and `valgrind` as a terminal (Terminal, Linux)
* Improve stability (PhysicalMemory, FreeBSD)
* Fix bssid & status detection (Wifi, FreeBSD)
* Ensure createTime is correctly initialized (Disk, FreeBSD / macOS)
* Fix `--cpu-freq-ndigits` not working if `--cpu-format` is used
* Fix `nix-user` package count detection (Packages, Linux)
* Fix some memory leaks
Logos:
* Fix Manjaro logo not displayed
* Add SpoinkOS
* Add Loc-OS
* Add Furreto Linux
* Fix TorizonCore logo colors
* Fix KDE neon logo not displayed
# 2.12.0
Changes:
* The long deprecated flag based config files are removed.
* They can still be used with `xargs fastfetch < /path/to/config.conf`
* `--gen-config` can be used to migrate them to json based config files
* The long deprecated options `--set` and `--set-keyless` are removed.
* `Kernel` module now prints kernel name by default
Features:
* Support `st` terminal font detection for font configuration compiled in `st` binary (TerminalFont, Linux)
* Add option `--color-output` to change output color of all modules except `Title`, `Separator`
* `display.color.output` in JSONC config file
* Add option `--<module>-output-color` to change output color of one specified module, which overrides the global option `--color-output`
* Add option `--publicip-ipv6` to print IPv6 address (PublicIP)
* Add new module `Loadavg` to print load averages (Loadavg)
* Add new module `PhysicalMemory` to print information of physical memory devices (PhysicalMemory)
* Requires root permission to work on Linux and FreeBSD
* Support specifying `--logo-width` only for `--kitty-direct` and `--iterm` (Logo)
* Add option `--localip-show-all-ips` to show all IPs assigned to the same interface (LocalIP)
* Default to `false`
* Improve compatibility with `(*term)` (#909, Terminal, macOS)
* Support GPU core count and frequency detection for Asahi Linux (GPU, Linux)
Bugfixes:
* Rename option `--temperature-unit` to `--temp-unit` as documented in help messages
* Fix alternate logo doesn't work with `{ "type": "builtin" }` (#914, Logo)
Logos:
* Fix DahliaOS detection
* Add openSUSE Slowroll
* Add macOS3
* Add Quirinux
# 2.11.5
Bugfix:
* Fix logo printing for OpenMandriva (#896)
* Remove `--os-file` in help messages
# 2.11.4
Changes:
* Fastfetch will print a colorless ascii logo in `--pipe` mode for better `lolcat` compatibility. `fastfetch | lolcat` should work and no `--pipe false` needed.
* Previously the logo would be disabled in `--pipe` mode.
* Use `--pipe -l none` to get the old beheavior
* `--os-file` was removed and CMake option `-DCUSTOM_OS_RELEASE_PATH=/path/to/os-release` was introduced for configuring at compile time by package managers if needed. This option should not used in most cases.
Bugfixes:
* Fix possible out-of-bound memory access (#868)
* Fix Apple Terminal detection (#878, macOS, Terminal)
* Fix deprecation warning for macOS 14.0 hopefully (#860, macOS, Camera)
* Fix memory leaks when passing informative options (#888)
* Fix JSON config `size.ndigits` doesn't work
Features:
* Enable `--pipe` mode if environment variable `$NO_COLOR` is set
* Support Armbian and Proxmox distro detection (OS, Linux)
Logo:
* Add Armbian
# 2.11.3
Hotfix for nix (https://github.com/NixOS/nixpkgs/issues/308849#issuecomment-2093962376)
Features:
* Add cmake option `CUSTOM_AMDGPU_IDS_PATH` for specifying custom path of `amdgpu.ids`
Bugfixes:
* Fix hanging when detecting disconnected network drive (Disk, Windows)
* Ensure line ending is printed when printing image logo errors (Logo)
* Revert image logo limitation change in 2.11.2; allow image logo in SSH session and tmux again (#861, Logo)
* Fix doubled output in custom formation (PhysicalDisk, Windows)
# 2.11.2
Hotfix for Debian 11
Changes:
* Error messages when trying to print image logo will only be printed with `--show-errors`
* When generating JSON output, fastfetch will generate an empty array when no result is detected, instead of an error.
Bugfixes:
* Fix segfault in Debian 11 and some old kernels. Regression introduced in 2.11.0 (#845, GPU, Linux)
* Don't try detecting version of raw `sh` shell (#849, Shell, Linux)
* Trim `\r` on Windows
Features:
* Check xdg state home for nix user packages (#837, Packages, Linux)
* Disable image logos in ssh and tmux sessions (#839)
* Support MX Linux distro detection (#847, OS, Linux)
Logo:
* Add KernelOS
* Fix name of DraugerOS
* Add missing `FF_LOGO_LINE_TYPE_SMALL_BIT` flags
* Add MX2
# 2.11.1
Hotfix for Android
Bugfixes:
* Fix uninitialized variables which can cause crashes (#760 #838, Battery, Android)
* Don't detect hyfetch as shell when used as a backend of hyfetch
* Fix incorrect information in man page
* Don't detect hyfetch as shell when used as backend of [hyfetch](https://github.com/hykilpikonna/hyfetch)
* Fix incorrect information in man page (#828)
Features:
* Support sorcery package manager detection (Packages, Linux)
* Make `--custom-format` optional (Custom)
* Make `/` an alias of `C:\` for `--disk-folders` (Disk, Windows)
* Build for Linux armv7
Logo:
* Fix colors of Source Mage logo
# 2.11.0
Changes:
+75 -7
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.11.1
VERSION 2.14.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -14,9 +14,9 @@ set(PROJECT_LICENSE "MIT license")
###################
if(ANDROID)
set(LINUX FALSE)
elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel
elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
set(BSD TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT WIN32)
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
@@ -77,8 +77,17 @@ option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
set_property(CACHE BINARY_LINK_TYPE PROPERTY STRINGS ${BINARY_LINK_TYPE_OPTIONS})
if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS)
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
endif()
if (LINUX)
set(CUSTOM_PCI_IDS_PATH "" CACHE STRING "Custom path to file pci.ids, defaults to `/usr/share/hwdata/pci.ids`")
set(CUSTOM_AMDGPU_IDS_PATH "" CACHE STRING "Custom path to file amdgpu.ids, defaults to `/usr/share/libdrm/amdgpu.ids`")
set(CUSTOM_OS_RELEASE_PATH "" CACHE STRING "Custom path to file os-release, defaults to `/etc/os-release`")
endif()
####################
@@ -113,7 +122,7 @@ endif()
if(WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id -Wl,--subsystem,console:6.1,--major-os-version,6,--minor-os-version,1")
elseif(APPLE)
elseif(APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-arc")
endif()
@@ -282,12 +291,14 @@ set(LIBFASTFETCH_SRC
src/common/properties.c
src/common/settings.c
src/common/temps.c
src/detection/bootmgr/bootmgr.c
src/detection/chassis/chassis.c
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/editor/editor.c
src/detection/font/font.c
src/detection/gpu/gpu.c
src/detection/media/media.c
@@ -295,6 +306,7 @@ set(LIBFASTFETCH_SRC
src/detection/opencl/opencl.c
src/detection/os/os.c
src/detection/packages/packages.c
src/detection/physicalmemory/physicalmemory.c
src/detection/publicip/publicip.c
src/detection/terminaltheme/terminaltheme.c
src/detection/terminalfont/terminalfont.c
@@ -311,6 +323,7 @@ set(LIBFASTFETCH_SRC
src/modules/bios/bios.c
src/modules/bluetooth/bluetooth.c
src/modules/board/board.c
src/modules/bootmgr/bootmgr.c
src/modules/brightness/brightness.c
src/modules/break/break.c
src/modules/camera/camera.c
@@ -325,13 +338,16 @@ set(LIBFASTFETCH_SRC
src/modules/de/de.c
src/modules/disk/disk.c
src/modules/diskio/diskio.c
src/modules/editor/editor.c
src/modules/font/font.c
src/modules/gpu/gpu.c
src/modules/host/host.c
src/modules/icons/icons.c
src/modules/initsystem/initsystem.c
src/modules/gamepad/gamepad.c
src/modules/kernel/kernel.c
src/modules/lm/lm.c
src/modules/loadavg/loadavg.c
src/modules/locale/locale.c
src/modules/localip/localip.c
src/modules/memory/memory.c
@@ -342,6 +358,7 @@ set(LIBFASTFETCH_SRC
src/modules/os/os.c
src/modules/packages/packages.c
src/modules/physicaldisk/physicaldisk.c
src/modules/physicalmemory/physicalmemory.c
src/modules/processes/processes.c
src/modules/player/player.c
src/modules/poweradapter/poweradapter.c
@@ -389,6 +406,7 @@ if(LINUX)
src/detection/battery/battery_linux.c
src/detection/bios/bios_linux.c
src/detection/board/board_linux.c
src/detection/bootmgr/bootmgr_linux.c
src/detection/brightness/brightness_linux.c
src/detection/chassis/chassis_linux.c
src/detection/cpu/cpu_linux.c
@@ -397,6 +415,7 @@ if(LINUX)
src/detection/bluetooth/bluetooth_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -413,8 +432,10 @@ if(LINUX)
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/libc/libc_linux.c
src/detection/lm/lm_linux.c
src/detection/loadavg/loadavg_linux.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_linux.c
@@ -455,6 +476,7 @@ elseif(ANDROID)
src/detection/bios/bios_android.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/board/board_android.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_linux.c
@@ -462,14 +484,17 @@ elseif(ANDROID)
src/detection/cpuusage/cpuusage_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/physicalmemory/physicalmemory_nosupport.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/initsystem/initsystem_linux.c
src/detection/libc/libc_android.c
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_linux.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
@@ -511,6 +536,7 @@ elseif(BSD)
src/detection/bios/bios_bsd.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/board/board_bsd.c
src/detection/bootmgr/bootmgr_bsd.c
src/detection/brightness/brightness_bsd.c
src/detection/chassis/chassis_bsd.c
src/detection/cpu/cpu_bsd.c
@@ -518,6 +544,7 @@ elseif(BSD)
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_bsd.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_bsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -535,7 +562,9 @@ elseif(BSD)
src/detection/host/host_bsd.c
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/libc/libc_bsd.c
src/detection/loadavg/loadavg_bsd.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_bsd.c
@@ -577,6 +606,7 @@ elseif(APPLE)
src/detection/bios/bios_apple.c
src/detection/bluetooth/bluetooth_apple.m
src/detection/board/board_apple.c
src/detection/bootmgr/bootmgr_apple.c
src/detection/brightness/brightness_apple.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_apple.c
@@ -584,14 +614,17 @@ elseif(APPLE)
src/detection/cursor/cursor_apple.m
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_apple.c
src/detection/physicalmemory/physicalmemory_apple.m
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/gpu/gpu_apple.m
src/detection/host/host_apple.c
src/detection/lm/lm_nosupport.c
src/detection/icons/icons_nosupport.c
src/detection/initsystem/initsystem_linux.c
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_bsd.c
src/detection/libc/libc_apple.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
@@ -634,6 +667,7 @@ elseif(WIN32)
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_windows.c
src/detection/board/board_windows.c
src/detection/bootmgr/bootmgr_windows.c
src/detection/brightness/brightness_windows.cpp
src/detection/chassis/chassis_windows.c
src/detection/cpu/cpu_windows.c
@@ -647,13 +681,16 @@ elseif(WIN32)
src/detection/gpu/gpu_windows.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/initsystem/initsystem_nosupport.c
src/detection/libc/libc_windows.cpp
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_nosupport.c
src/detection/locale/locale_windows.c
src/detection/localip/localip_windows.c
src/detection/gamepad/gamepad_windows.c
src/detection/media/media_nosupport.c
src/detection/memory/memory_windows.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/monitor/monitor_windows.c
src/detection/netio/netio_windows.c
src/detection/opengl/opengl_windows.c
@@ -765,7 +802,7 @@ if(BSD AND EXISTS "/usr/local/bin/objdump")
endif()
endif()
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1 _FILE_OFFSET_BITS=64)
if(WIN32)
target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1)
elseif(APPLE)
@@ -784,6 +821,19 @@ if(NOT "${CUSTOM_PCI_IDS_PATH}" STREQUAL "")
message(STATUS "Custom file path of pci.ids: ${CUSTOM_PCI_IDS_PATH}")
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_PCI_IDS_PATH=${CUSTOM_PCI_IDS_PATH})
endif()
if(NOT "${CUSTOM_AMDGPU_IDS_PATH}" STREQUAL "")
message(STATUS "Custom file path of amdgpu.ids: ${CUSTOM_AMDGPU_IDS_PATH}")
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_AMDGPU_IDS_PATH=${CUSTOM_AMDGPU_IDS_PATH})
endif()
if(NOT "${CUSTOM_OS_RELEASE_PATH}" STREQUAL "")
message(STATUS "Custom file path of os_release: ${CUSTOM_OS_RELEASE_PATH}")
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_OS_RELEASE_PATH=${CUSTOM_OS_RELEASE_PATH})
endif()
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
message(STATUS "Enabling custom link type: ${BINARY_LINK_TYPE}")
target_compile_definitions(libfastfetch PRIVATE FF_DISABLE_DLOPEN=1)
endif()
function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
if(NOT ENABLE_${VARNAME})
@@ -813,6 +863,11 @@ function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_${VARNAME}=1)
target_include_directories(libfastfetch PRIVATE ${${VARNAME}_INCLUDE_DIRS})
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
target_link_directories(libfastfetch PUBLIC ${${VARNAME}_LIBRARY_DIRS})
target_link_libraries(libfastfetch PRIVATE ${${VARNAME}_LIBRARIES})
endif()
foreach(FLAG ${${VARNAME}_CFLAGS_OTHER})
if(FLAG MATCHES "-D.*")
string(SUBSTRING ${FLAG} 2 -1 FLAG)
@@ -1061,6 +1116,11 @@ elseif(APPLE)
)
endif()
if(BINARY_LINK_TYPE STREQUAL "static")
target_link_options(fastfetch PRIVATE "-static")
target_link_options(flashfetch PRIVATE "-static")
endif()
###################
# Testing targets #
###################
@@ -1148,7 +1208,15 @@ if(LINUX)
set(CPACK_DEBIAN_PACKAGE_SECTION, "utils")
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
if(NOT IS_MUSL)
EXECUTE_PROCESS (
COMMAND getconf GNU_LIBC_VERSION
OUTPUT_VARIABLE GLIBC_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
STRING (REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
endif()
endif()
find_program(HAVE_RPMBUILD "rpmbuild")
-34
View File
@@ -1,34 +0,0 @@
# Development help
This file is not an official documentation!
Here i just add things that are easy to forget.
## Features i am planning to implement
### Specific
- [ ] Split the project in different libs / executables, all linking static by default:
- `libffdetect`: contains all the detection stuff. To be used by anything that needs system information
- `libffprint`: contains the printing functions, logos, format etc
- `fastfetch` and `flashfetch`: Executables, that initialize the config of libffprint. Fist one at runtime, second one at compile time
- [ ] Make LocalIP module more configurable
- [ ] Automatic migrate old config files to newer versions
- [ ] ZSH completions
- [ ] Fish completions
- [ ] Make CPU usage detection much faster and more accurate
- [ ] Detect CPU usage in a common detection method and expose it both to the cpuUsage module and the cpu format string
- [ ] Per session caching
### General
- More presets
- More logos
- More package managers
- More DE detections
- More WM theme detections
- More terminal font detections
- Performance optimizations
- More module specific options
- Better error handling, especially the messages shown when using --show-errors
- Using package managers libraries for package count detection instead own. E.g. using libalpm instead of counting files in /var/lib/pacman/local
- Better documentation (especially default config file and the various --help options. Colored output?)
- General feature parity with neofetch, to demonstrate supremity of c
+101 -16
View File
@@ -30,7 +30,7 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
Some distros packaged an outdated fastfetch version. Older version is not supported, please always ensure that the latest version is used.
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `dpkg -i fastfetch-<version>-Linux.deb` (for Ubuntu 20.04 or newer and Debian 11 or newer).
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
* Arch Linux: `sudo pacman -S fastfetch`
* Fedora: `sudo dnf install fastfetch`
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
@@ -43,31 +43,28 @@ Replace sudo with doas depending on what you use.
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging).
If fastfetch is not packaged for your distro or an outdated version is packaged, [linuxbrew](https://brew.sh/) is a good alternate: `brew install fastfetch`
If fastfetch is not packaged for your distro or an outdated version is packaged, [linuxbrew](https://brew.sh/) is a good alternative: `brew install fastfetch`
### macOS
...via [HomeBrew](https://brew.sh):
`brew install fastfetch`
...via [MacPorts](https://www.macports.org):
`sudo port install fastfetch`
* [HomeBrew](https://formulae.brew.sh/formula/fastfetch#default): `brew install fastfetch`
* [MacPorts](https://ports.macports.org/port/fastfetch/): `sudo port install fastfetch`
### Windows
`scoop install fastfetch`
* [scoop](https://scoop.sh/#/apps?q=fastfetch): `scoop install fastfetch`
* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch`
* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
### FreeBSD
`pkg install fastfetch`
* `pkg install fastfetch`
### Android (Termux)
`pkg install fastfetch`
* `pkg install fastfetch`
## Build from source
@@ -101,11 +98,99 @@ Logos can be heavily customized too; see the [logo documentation](https://github
## FAQ
Q: Why do you need a very performant version of neofetch?
> I like putting neofetch in my ~/.bashrc to have a system overview whenever I use the terminal, but the slow speed annoyed me, so I created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration.
### Q: Neofetch is good enough. Why do I need fastfetch?
Q: It does not display [*] correctly for me, what can I do?
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
1. Fastfetch is actively maintained.
2. Fastfetch is faster. As the name suggests.
3. Fastfetch is more feature-rich. By default fastfetch only has a few modules enabled. Use `fastfetch -c all` to find what you want.
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module (notibily the difference of `MiB` and `G`), while fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
6. Fastfetch is more accurate. For example, [neofetch never actually supports Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
### Q: Fastfetch shows my local IP address. It leaks my privacy!
A local IP (10.x.x.x, 172.x.x.x, 192.168.x.x) has nothing to do with privacy. It only makes sense if you are on the same network, for example, if you connect to the same Wi-Fi network.
Actually the `Local IP` module is the most useful module for me personally. I (@CarterLi) have several VMs installed to test fastfetch and often need to SSH into them. I have fastfetch running on shell startup and I never need to type `ip addr` manually.
If you really don't like it, you can disable the `Local IP` module in `config.jsonc`.
### Q: Where is the config file? I can't find it.
`Fastfetch` don't generate config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See [Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration).
### Q: The configuration is so complex. Where is the documentation?
Fastfetch uses JSON (with comments) for configuration. I suggest you use an IDE with JSON schema support (like VSCode) to edit it.
Alternatively, you can refer to the presets in [`presets` directory](https://github.com/fastfetch-cli/fastfetch/tree/dev/presets).
### Q: I WANT THE DOCUMENTATION!
[Here is the documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Json-Schema). It is generated from [JSON schema](https://github.com/fastfetch-cli/fastfetch/blob/dev/doc/json_schema.json) but you won't like it.
### Q: How can I customize the module output?
Fastfetch uses `format` to generate output. For example to make `GPU` module show GPU name only and ignore other information, you can use
```jsonc
{
"modules": [
{
"type": "gpu",
"format": "{2}" // See `fastfetch -h gpu-format` for detail
}
]
}
```
which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
See `fastfetch -h format` for basic usage. For module specific formattion, see `fastfetch -h <module>-format`
### Q: I have my own ascii-art / image file. How can I show it with fastfetch?
Try `fastfetch -l /path/to/logo`. See [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for detail.
If you just want to display distro name in [FIGlet text](https://github.com/pwaller/pyfiglet)
```bash
# install pyfiglet and jq first
pyfiglet -s -f small_slant $(fastfetch -s os --format json | jq -r '.[0].result.name') && fastfetch -l none
```
![image](https://github.com/fastfetch-cli/fastfetch/assets/6134068/6466524e-ab8c-484f-848d-eec7ddeb7df2)
### Q: Fastfetch runs in white and black on shell startup. Why?
This issue usually happens when using fastfetch with `p10k`. There are known incompatibility between fastfetch and p10k instant prompt.
The p10k doc clearly states that you should NOT print anything to stdout after `p10k-instant-prompt` is initialized. You should either put `fastfetch` before initialization of `p10k-instant-prompt` (recommended)
You can always use `fastfetch --pipe false` to force fastfetch running in colorful mode.
### Q: I want feature A / B / C. Will fastfetch support it?
Fastfetch is a system information tool. We only accept hardware or system level software feature requests. For most personal uses, I recommend using `Command` module to detect it yourself, which can be used to grab output from a custom shell script:
```jsonc
// This module shows the default editor
{
"modules": [
{
"type": "command",
"text": "$EDITOR --version | head -1",
"key": "Editor"
}
]
}
```
Otherwise, open a feature request in [GitHub Issues](https://github.com/fastfetch-cli/fastfetch/issues).
### Q: I have questions. Where can I get help?
* For usage questions, please start a discussion in [GitHub Discussions](https://github.com/fastfetch-cli/fastfetch/discussions).
* For possible bugs, please open an issue in [GitHub Issues](https://github.com/fastfetch-cli/fastfetch/issues). Be sure to fill the bug-report template carefully for developers to investigate.
## Star History
+1 -5
View File
@@ -191,14 +191,13 @@ __fastfetch_completion()
"--escape-bedrock"
"--pipe"
"--title-fqdn"
"--escape-bedrock"
"--disk-folders"
"--disk-show-external"
"--disk-show-hidden"
"--disk-show-subvolumes"
"--gpu-hide-integrated"
"--gpu-hide-discrete"
"--gpu-force-vulkan"
"--gpu-force-method"
"--disk-show-unknown"
"--bluetooth-show-disconnected"
)
@@ -227,8 +226,6 @@ __fastfetch_completion()
"--separator"
"-s"
"--structure"
"--set"
"--set-keyless"
"--player-name"
"--percent-type"
"--publicip-url"
@@ -360,7 +357,6 @@ __fastfetch_completion()
local FF_OPTIONS_PATH=(
"-c"
"--config"
"--os-file"
"--lib-pci"
"--lib-vulkan"
"--lib-wayland"
+1 -1
View File
@@ -85,7 +85,7 @@ string match -r -a -g "^###> ?(.*)" < (status -f) | string collect | python3 | s
###> elif type == 'config':
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_config)"')
###> elif type == 'enum':
###> temp: str = ' '.join(map(lambda x: f"{x[0]}\\t{x[1]}", flag["arg"]["enum"].items()))
###> temp: str = ' '.join(flag["arg"]["enum"])
###> print(f'{command_prefix} -x -a "{temp}"')
###> elif type == 'logo':
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_logo)"')
+42
View File
@@ -1,3 +1,45 @@
fastfetch (2.13.2) jammy; urgency=medium
* Update to 2.13.2
-- Carter Li <zhangsongcui@live.cn> Fri, 24 May 2024 13:48:59 +0800
fastfetch (2.13.1) jammy; urgency=medium
* Update to 2.13.1
-- Carter Li <zhangsongcui@live.cn> Tue, 21 May 2024 15:10:37 +0800
fastfetch (2.12.0) jammy; urgency=medium
* Update to 2.12.0
-- Carter Li <zhangsongcui@live.cn> Tue, 14 May 2024 16:33:33 +0800
fastfetch (2.11.5) jammy; urgency=medium
* Update to 2.11.5
-- Carter Li <zhangsongcui@live.cn> Tue, 07 May 2024 09:30:05 +0800
fastfetch (2.11.3) jammy; urgency=medium
* Update to 2.11.3
-- Carter Li <zhangsongcui@live.cn> Mon, 06 May 2024 08:46:45 +0800
fastfetch (2.10.2) jammy; urgency=medium
* Update to 2.10.2
-- Carter Li <zhangsongcui@live.cn> Tue, 23 Apr 2024 15:18:23 +0800
fastfetch (2.10.1) jammy; urgency=medium
* Update to 2.10.1
-- Carter Li <zhangsongcui@live.cn> Tue, 23 Apr 2024 09:55:02 +0800
fastfetch (2.9.2) jammy; urgency=medium
* Update to 2.9.2
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.9.2_source.buildinfo universe/utils optional
fastfetch_2.13.2_source.buildinfo universe/utils optional
+4 -7
View File
@@ -107,12 +107,12 @@ To list all available modules, use \fB \-\-list\-modules \fR
.SS "Config Files"
fastfetch supports two types of config files. The legacy
configuration files and a JSONC based format.
Fastfetch uses JSONC based format for configuration. Fastfetch doesn't generate
config file automatically; it should be generated manually by \fB \-\-gen\-config\fR.
The config file will be saved in \fB~/.config/fastfetch/config.jsonc\fR by default.
A JSONC config file is a JSON file that also supports comments with (//). Those
files must have the extension '.jsonc'. You can migrate a legacy config
file to the JSONC format by using \fB\-\-gen\-config\fR.
files must have the extension '.jsonc'.
The specified configuration/preset files are searched in the following order:
@@ -122,9 +122,6 @@ The specified configuration/preset files are searched in the following order:
3. relative to /usr/share/fastfetch/presets/
When both a '.jsonc' and a '.conf' file with the same name is found,
the '.jsonc' file is preferred.
Fastfetch provides some default presets. List them with \fB\-\-list\-presets\fR.
.SH "SEE ALSO"
+185 -15
View File
@@ -4,9 +4,8 @@
"colors": {
"type": "string",
"enum": [
"reset_", "bright_", "dim_",
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default",
"bright_black", "bright_red", "bright_green", "bright_yellow", "bright_blue", "bright_magenta", "bright_cyan", "bright_white"
"reset_", "bright_", "dim_", "italic_", "underline_", "blink_", "inverse_", "hidden_", "strike_", "light_",
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default"
]
},
"key": {
@@ -24,9 +23,13 @@
"default": 0
},
"format": {
"description": "Output format of the module",
"description": "Output format of the module. See `-h &lt;module&gt;-format` for detail",
"type": "string"
},
"outputColor": {
"description": "Output color of the module. Left empty to use `display.color.output`",
"$ref": "#/$defs/colors"
},
"percent": {
"description": "Threshold of percentage colors",
"type": "object",
@@ -294,10 +297,6 @@
"type": "string",
"description": "The name of the player to use for module Media and Player. Linux only"
},
"osFile": {
"type": "string",
"description": "Set the path to the file containing OS information. Linux only"
},
"dsForceDrm": {
"description": "Force display detection to use DRM. Linux only",
"oneOf": [
@@ -384,6 +383,14 @@
"title": {
"description": "Set the color of the title",
"$ref": "#/$defs/colors"
},
"output": {
"description": "Set the color of the module output",
"$ref": "#/$defs/colors"
},
"separator": {
"description": "Set the color of the key-value separator",
"$ref": "#/$defs/colors"
}
}
}
@@ -512,7 +519,7 @@
"properties": {
"type": {
"type": "number",
"description": "Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number",
"description": "Set the percentage output type. 1 for percentage number, 2 for multi-color bar, 3 for both, 6 for bar only, 9 for colored number, 10 for monochrome bar",
"minimum": 0,
"maximum": 255,
"default": 9
@@ -677,6 +684,7 @@
"bios",
"bluetooth",
"board",
"bootmgr",
"break",
"brightness",
"camera",
@@ -691,6 +699,7 @@
"disk",
"diskio",
"de",
"editor",
"font",
"gamepad",
"gpu",
@@ -698,6 +707,7 @@
"icons",
"kernel",
"lm",
"loadavg",
"locale",
"localip",
"media",
@@ -709,6 +719,7 @@
"os",
"packages",
"physicaldisk",
"physicalmemory",
"player",
"poweradapter",
"processes",
@@ -767,11 +778,15 @@
"anyOf": [
{
"const": "bios",
"description": "Print BIOS name, version, release date, etc"
"description": "Print information of 1st-stage bootloader (name, version, release date, etc)"
},
{
"const": "board",
"description": "Print mather board name and other info"
"description": "Print motherboard name and other info"
},
{
"const": "bootmgr",
"description": "Print information of 2nd-stage bootloader (name, firmware, etc)"
},
{
"const": "camera",
@@ -785,6 +800,10 @@
"const": "datetime",
"description": "Print current date and time"
},
{
"const": "editor",
"description": "Print information of the default editor ($VISUAL or $EDITOR)"
},
{
"const": "font",
"description": "Print system font name"
@@ -825,6 +844,10 @@
"const": "os",
"description": "Print operating system name and version"
},
{
"const": "physicalmemory",
"description": "Print system physical memory devices"
},
{
"const": "player",
"description": "Print music player name"
@@ -897,6 +920,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -931,6 +957,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -962,6 +991,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -988,6 +1020,21 @@
"minimum": 0,
"maximum": 400,
"default": 10
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
}
},
@@ -1006,6 +1053,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1033,12 +1083,20 @@
"maximum": 9,
"default": 2
},
"showPeCoreCount": {
"description": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
"type": "boolean",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1146,6 +1204,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1170,6 +1231,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1219,6 +1283,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1279,6 +1346,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1311,6 +1381,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1339,6 +1412,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1365,6 +1441,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1390,10 +1469,16 @@
"type": "boolean",
"default": false
},
"forceVulkan": {
"description": "Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`",
"type": "boolean",
"default": false
"detectionMethod": {
"description": "Force using a specified method to detect GPUs",
"type": "string",
"enum": [
"auto",
"pci",
"vulkan",
"opengl"
],
"default": "auto"
},
"hideType": {
"description": "Specify the type of GPUs should not be printed",
@@ -1410,6 +1495,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1452,6 +1540,11 @@
"type": "boolean",
"default": true
},
"showAllIps": {
"description": "Show all IPs bound to the same interface.\nBy default only the first IP is shown",
"type": "boolean",
"default": false
},
"compact": {
"description": "Show all IPs in one line",
"type": "boolean",
@@ -1472,6 +1565,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1498,6 +1594,42 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
}
},
{
"title": "Loadavg",
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"const": "loadavg",
"description": "Print system load averages"
},
"ndigits": {
"type": "integer",
"description": "Set the number of digits to keep after the decimal point",
"minimum": 0,
"maximum": 9,
"default": 2
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1535,6 +1667,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1568,6 +1703,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1622,6 +1760,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1652,6 +1793,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1681,12 +1825,20 @@
"minimum": 0,
"default": "disabled (0)"
},
"ipv6": {
"description": "Whether to use IPv6 for public IP detection server",
"type": "boolean",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1708,6 +1860,9 @@
"description": "Set the string to be printed",
"type": "string",
"default": "-"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
}
}
},
@@ -1739,6 +1894,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1765,6 +1923,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1812,6 +1973,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1850,6 +2014,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1878,6 +2045,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
+14 -2
View File
@@ -6,13 +6,17 @@
"os",
"host",
"bios",
"bootmgr",
"board",
"chassis",
"kernel",
"initsystem",
"uptime",
"loadavg",
"processes",
"packages",
"shell",
"editor",
"display",
"brightness",
"monitor",
@@ -29,10 +33,14 @@
"terminalfont",
"terminalsize",
"terminaltheme",
"cpu",
{
"type": "cpu",
"showPeCoreCount": true
},
"cpuusage",
"gpu",
"memory",
"physicalmemory",
"swap",
"disk",
"battery",
@@ -40,7 +48,11 @@
"player",
"media",
"publicip",
"localip",
{
"type": "localip",
"showIpV6": true,
"showMac": true
},
"wifi",
"datetime",
"locale",
+84
View File
@@ -0,0 +1,84 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"modules": [
{
"type": "title",
"key": "User",
"format": "{1}"
},
{
"type": "title",
"key": "Hostname",
"format": "{2}"
},
{
"type": "host",
"key": "Model"
},
{
"type": "os",
"format": "{3} {9} {12}"
},
"kernel",
"uptime",
{
"type": "loadavg",
"key": "Load Average"
},
"processes",
{
"type": "wm",
"key": "Window Manager"
},
{
"type": "de",
"key": "Desktop Environment"
},
{
"type": "shell",
"format": "{7}"
},
{
"type": "terminal",
"format": "{5} {6} {#37}█{#97}█ {#36}█{#96}█ {#35}█{#95}█ {#34}█{#94}█ {#33}█{#93}█ {#32}█{#92}█ {#31}█{#91}█ {#30}█{#90}█"
},
{
"type": "packages",
"format": "{1}"
},
{
"type": "cpu",
"key": "Temperature",
"temp": true,
"format": "{8}"
},
{
"type": "cpu",
"key": "CPU",
"format": "{4} x {1}"
},
{
"type": "gpu",
"format": "{2}"
},
{
"type": "memory",
"key": "RAM"
},
{
"type": "disk",
"key": "Disk",
"folders": "/"
},
{
"type": "localip",
"key": "LAN IP",
"showIpv6": true,
"showPrefixLen": false
},
{
"type": "publicip",
"key": "WAN IP"
}
]
}
+15 -2
View File
@@ -6,19 +6,24 @@
"showErrors": true,
"noBuffer": true
},
"logo": null,
"modules": [
"title",
"separator",
"os",
"host",
"bios",
"bootmgr",
"board",
"chassis",
"kernel",
"initsystem",
"uptime",
"loadavg",
"processes",
"packages",
"shell",
"editor",
"display",
"brightness",
"monitor",
@@ -35,10 +40,14 @@
"terminalfont",
"terminalsize",
"terminaltheme",
"cpu",
{
"type": "cpu",
"showPeCoreCount": true
},
"cpuusage",
"gpu",
"memory",
"physicalmemory",
"swap",
"disk",
"battery",
@@ -46,7 +55,11 @@
"player",
"media",
"publicip",
"localip",
{
"type": "localip",
"showIpV6": true,
"showMac": true
},
"wifi",
"datetime",
"locale",
+10 -6
View File
@@ -14,7 +14,8 @@
"modules": [
{
"type": "custom",
"format": "\u001b[90m┌────────────────────────────────────────────────────────────┐"
"format": "┌────────────────────────────────────────────────────────────┐",
"outputColor": "90"
},
{
"type": "title",
@@ -22,15 +23,17 @@
},
{
"type": "custom",
"format": "\u001b[90m└────────────────────────────────────────────────────────────┘"
"format": "└────────────────────────────────────────────────────────────┘",
"outputColor": "90"
},
{
"type": "custom",
"format": " \u001b[90m\u001b[31m\u001b[32m\u001b[33m\u001b[34m\u001b[35m\u001b[36m\u001b[37m\u001b[38m\u001b[39m  \u001b[38m\u001b[37m\u001b[36m\u001b[35m\u001b[34m\u001b[33m\u001b[32m\u001b[31m\u001b[90m"
"format": " {#90}{#31}{#32}{#33}{#34}{#35}{#36}{#37}{#38}{#39}  {#38}{#37}{#36}{#35}{#34}{#33}{#32}{#31}{#90}"
},
{
"type": "custom",
"format": "\u001b[90m┌────────────────────────────────────────────────────────────┐"
"format": "┌────────────────────────────────────────────────────────────┐",
"outputColor": "90"
},
{
"type": "os",
@@ -139,12 +142,13 @@
},
{
"type": "custom",
"format": "\u001b[90m└────────────────────────────────────────────────────────────┘"
"format": "└────────────────────────────────────────────────────────────┘",
"outputColor": "90"
},
"break",
{
"type": "custom",
"format": " \u001b[90m\u001b[31m\u001b[32m\u001b[33m\u001b[34m\u001b[35m\u001b[36m\u001b[37m\u001b[38m\u001b[39m  \u001b[38m\u001b[37m\u001b[36m\u001b[35m\u001b[34m\u001b[33m\u001b[32m\u001b[31m\u001b[90m"
"format": " {#90}{#31}{#32}{#33}{#34}{#35}{#36}{#37}{#38}{#39}  {#38}{#37}{#36}{#35}{#34}{#33}{#32}{#31}{#90}"
}
]
}
+4 -1
View File
@@ -4,7 +4,10 @@
"type": "small"
},
"display": {
"separator": "\u001b[31m-> "
"separator": "-> ",
"color": {
"separator": "red"
}
},
"modules": [
{
+6 -3
View File
@@ -4,7 +4,10 @@
"type": "none"
},
"display": {
"separator": "-> "
"separator": "-> ",
"color": {
"separator": "1"
}
},
"modules": [
{
@@ -14,7 +17,7 @@
"break",
{
"type": "custom",
"format": "┌───────────────────────────── \u001b[1mSystem Information\u001b[0m ─────────────────────────────┐" // `\u001b` is `\033`, or `\e`
"format": "┌───────────────────────────── {#1}System Information{#} ─────────────────────────────┐"
},
"break",
{
@@ -92,7 +95,7 @@
"break",
{
"type": "custom",
"format": "└──────────────────────────────────────────────────────────────────────────────┘" // `\u001b` is `\033`, or `\e`
"format": "└──────────────────────────────────────────────────────────────────────────────┘"
},
"break",
{
+15 -14
View File
@@ -17,54 +17,55 @@
},
{
// draw borders first to make colors of left and right border consistant
"key": "│ │\u001b[11D\u001b[31m user",
"key": "│ │\u001b[11D{#31} user",
"type": "title",
"format": "{1}"
},
{
"key": "│ │\u001b[11D\u001b[32m󰇅 hname",
"key": "│ │\u001b[11D{#32}󰇅 hname",
"type": "title",
"format": "{2}"
},
{
"key": "│ │\u001b[11D\u001b[33m󰅐 uptime",
"key": "│ │\u001b[11D{#33}󰅐 uptime",
"type": "uptime"
},
{
"key": "│ │\u001b[11D\u001b[34m󰟾 distro",
"key": "│ │\u001b[11D{#34}󰟾 distro",
"type": "os"
},
{
"key": "│ │\u001b[11D\u001b[35m kernel",
"key": "│ │\u001b[11D{#35} kernel",
"type": "kernel"
},
{
"key": "│ │\u001b[11D\u001b[36m󰇄 desktop",
"key": "│ │\u001b[11D{#36}󰇄 desktop",
"type": "de"
},
{
"key": "│ │\u001b[11D\u001b[31m term",
"key": "│ │\u001b[11D{#31} term",
"type": "terminal"
},
{
"key": "│ │\u001b[11D\u001b[32m shell",
"key": "│ │\u001b[11D{#32} shell",
"type": "shell"
},
{
"key": "│ │\u001b[11D\u001b[33m󰍛 cpu",
"type": "cpu"
"key": "│ │\u001b[11D{#33}󰍛 cpu",
"type": "cpu",
"showPeCoreCount": true
},
{
"key": "│ │\u001b[11D\u001b[34m󰉉 disk",
"key": "│ │\u001b[11D{#34}󰉉 disk",
"type": "disk",
"folders": "/"
},
{
"key": "│ │\u001b[11D\u001b[35m memory",
"key": "│ │\u001b[11D{#35} memory",
"type": "memory"
},
{
"key": "│ │\u001b[11D\u001b[36m󰩟 network",
"key": "│ │\u001b[11D{#36}󰩟 network",
"type": "localip",
"format": "{1} ({4})"
},
@@ -73,7 +74,7 @@
"type": "custom"
},
{
"key": "│ │\u001b[11D\u001b[m colors",
"key": "│ │\u001b[11D{#39} colors",
"type": "colors",
"symbol": "circle"
},
+2 -2
View File
@@ -15,7 +15,7 @@
"modules": [
{
"type": "custom", // HardwareStart
"format": "┌─────────── \u001b[1mHardware Information\u001b[0m ───────────┐" // `\u001b` is `\033`, or `\e`
"format": "┌─────────── {#1}Hardware Information{#} ───────────┐" // {#1} is the same as `\u001b[1m`. {#} is `\u001b[m`
},
{
"type": "host",
@@ -71,7 +71,7 @@
},
{
"type": "custom", // SoftwareStart
"format": "├─────────── \u001b[1mSoftware Information\u001b[0m ───────────┤"
"format": "├─────────── {#1}Software Information{#} ───────────┤"
},
{
"type": "title",
+1 -2
View File
@@ -9,8 +9,7 @@
"modules": [
{
"type": "theme",
"key": "T",
"format": "{7}"
"key": "T"
},
{
"type": "icons",
+1 -1
View File
@@ -24,7 +24,7 @@
"type": "os",
"key": "├", // Just get your distro's logo off nerdfonts.com
"keyColor": "yellow",
"format": "{6}{?6} {?}{10} {8}"
"format": "{6}{?6} {?}{10}{?10} {?}{8}{?8} {?}{11}"
},
{
"type": "kernel",
+6 -6
View File
@@ -24,29 +24,29 @@
},
{
"type": "os",
"key": "",
"key": "",
"format": "{2} {8}"
},
{
"type": "kernel",
"key": ""
"key": ""
},
{
"type": "memory",
"key": "󰻠"
"key": ""
},
{
"type": "packages",
"key": ""
"key": "󰏖"
},
{
"type": "uptime",
"key": ""
"key": "󰅐"
},
{
"type": "custom",
"key": "",
"format": "\u001b[31m███\u001b[32m███\u001b[33m███\u001b[34m███\u001b[35m███\u001b[36m███"
"format": "{#31}███{#32}███{#33}███{#34}███{#35}███{#36}███"
}
]
}
+25 -13
View File
@@ -1,25 +1,37 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "builtin",
"source": "arch"
},
"modules": [
"host",
"display",
{
"type": "host",
"format": "{?2}{2}{?}{?5} ({5}){?}"
},
"chassis",
{
"type": "board",
"format": "{?1}{1}{?}{?2} ({2}){?}"
},
"cpu",
"gpu",
{
"type": "memory",
"format": "{?2}{2}{?}"
},
{
"type": "disk",
"format": "{?2}{2}{?}"
},
"physicaldisk",
"gpu",
"display",
"monitor",
{
"type": "wifi",
"format": "{?1}{1}{?}{?6} - {6}{?}"
},
{
"type": "sound",
"format": "{?2}{2}{?}"
},
"camera",
{
"type": "battery",
"format": "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
}
"format": "{?1}{1}{?}{?2} {2}{?}{?3} ({3}){?}"
},
"poweradapter"
]
}
+9 -12
View File
@@ -1,16 +1,16 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"display": {
"size": {
"maxPrefix": "MB",
"ndigits": 0
}
},
"modules": [
"title",
"separator",
{
"type": "os",
"format": "{3} {12}"
},
{
"type": "host",
"format": "{/2}{-}{/}{2}{?3} {3}{?}"
},
"os",
"host",
"kernel",
"uptime",
"packages",
@@ -23,10 +23,7 @@
"de",
"wm",
"wmtheme",
{
"type": "theme",
"format": "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
},
"theme",
"icons",
"terminal",
{
Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

-11074
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -1,6 +0,0 @@
{
"home": "https://github.com/NVIDIA/nvidia-settings/blob/main/src/nvml.h",
"license": "Embed in source",
"version": "550.54.14",
"author": "NVIDIA Corporation"
}
+4 -23
View File
@@ -11,7 +11,7 @@
bool ffParseModuleOptions(const char* key, const char* value)
{
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) return false;
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules)
{
@@ -79,30 +79,11 @@ static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
static void parseStructureCommand(
const char* line,
FFlist* customValues,
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
yyjson_mut_doc* jsonDoc
)
{
// handle `--set` and `--set-keyless`
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
{
if (ffStrbufEqualS(&customValue->key, line))
{
__attribute__((__cleanup__(ffDestroyCustomOptions))) FFCustomOptions options;
ffInitCustomOptions(&options);
if (customValue->printKey)
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
if (__builtin_expect(jsonDoc != NULL, false))
fn((FFModuleBaseInfo*) &options, jsonDoc);
else
ffPrintCustom(&options);
return;
}
}
if(isalpha(line[0]))
if(ffCharIsEnglishAlphabet(line[0]))
{
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
{
@@ -134,7 +115,7 @@ void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
if(instance.config.display.stat)
ms = ffTimeGetTick();
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc);
parseStructureCommand(data->structure.chars + startIndex, genJsonResult, jsonDoc);
if(instance.config.display.stat)
{
@@ -177,7 +158,7 @@ void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
data->structure.chars[colonIndex] = '\0';
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc);
parseStructureCommand(data->structure.chars + startIndex, genJsonConfig, jsonDoc);
startIndex = colonIndex + 1;
}
-8
View File
@@ -2,18 +2,10 @@
#include "fastfetch.h"
typedef struct FFCustomValue
{
bool printKey;
FFstrbuf key;
FFstrbuf value;
} FFCustomValue;
// Things only needed by fastfetch
typedef struct FFdata
{
FFstrbuf structure;
FFlist customValues; // List of FFCustomValue
bool configLoaded;
} FFdata;
+78 -57
View File
@@ -52,14 +52,29 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
* @param placeholderValue the string to parse
* @return uint32_t the parsed value
*/
static inline uint32_t getArgumentIndex(const FFstrbuf* placeholderValue)
static uint32_t getArgumentIndex(const FFstrbuf* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
{
uint32_t result = UINT32_MAX;
char firstChar = placeholderValue->chars[0];
if(placeholderValue->chars[0] != '-')
sscanf(placeholderValue->chars, "%" PRIu32, &result);
if(firstChar >= '1' && firstChar <= '9')
{
char* pEnd = NULL;
unsigned long result = strtoul(placeholderValue->chars, &pEnd, 10);
if (pEnd != placeholderValue->chars + placeholderValue->length || result > numArgs)
return UINT32_MAX;
return (uint32_t) result;
}
else if (ffCharIsEnglishAlphabet(firstChar))
{
for (uint32_t i = 0; i < numArgs; ++i)
{
const FFformatarg* arg = &arguments[i];
if(arg->name && ffStrbufIgnCaseEqualS(placeholderValue, arg->name))
return i + 1;
}
}
return result == 0 ? UINT32_MAX : result;
return UINT32_MAX;
}
static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start, const FFstrbuf* placeholderValue, uint32_t index, uint32_t formatStringLength)
@@ -101,7 +116,8 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
uint32_t numOpenIfs = 0;
uint32_t numOpenNotIfs = 0;
uint32_t numOpenColors = 0;
FF_STRBUF_AUTO_DESTROY placeholderValue = ffStrbufCreate();
for(uint32_t i = 0; i < formatstr->length; ++i)
{
@@ -136,67 +152,70 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
FF_STRBUF_AUTO_DESTROY placeholderValue = ffStrbufCreate();
ffStrbufClear(&placeholderValue);
while(i < formatstr->length && formatstr->chars[i] != '}')
ffStrbufAppendC(&placeholderValue, formatstr->chars[i++]);
// test if for stop, if so break the loop
if(placeholderValue.length == 1 && placeholderValue.chars[0] == '-')
break;
// test for end of an if, if so do nothing
if(placeholderValue.length == 1 && placeholderValue.chars[0] == '?')
{
if(numOpenIfs == 0)
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
else
--numOpenIfs;
continue;
uint32_t iEnd = ffStrbufNextIndexC(formatstr, i, '}');
ffStrbufAppendNS(&placeholderValue, iEnd - i, &formatstr->chars[i]);
i = iEnd;
}
// test for end of a not if, if so do nothing
if(placeholderValue.length == 1 && placeholderValue.chars[0] == '/')
{
if(numOpenNotIfs == 0)
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
else
--numOpenNotIfs;
char firstChar = placeholderValue.chars[0];
continue;
}
// test for end of a color, if so do nothing
if(placeholderValue.length == 1 && placeholderValue.chars[0] == '#')
if (placeholderValue.length == 1)
{
if(numOpenColors == 0)
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
else
// test if for stop, if so break the loop
if (firstChar == '-')
break;
// test for end of an if, if so do nothing
if (firstChar == '?')
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
--numOpenColors;
if(numOpenIfs == 0)
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
else
--numOpenIfs;
continue;
}
continue;
// test for end of a not if, if so do nothing
if (firstChar == '/')
{
if(numOpenNotIfs == 0)
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
else
--numOpenNotIfs;
continue;
}
// test for end of a color, if so do nothing
if (firstChar == '#')
{
if (!instance.config.display.pipe)
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
continue;
}
}
// test for if, if so evaluate it
if(placeholderValue.chars[0] == '?')
if (firstChar == '?')
{
ffStrbufSubstrAfter(&placeholderValue, 0);
uint32_t index = getArgumentIndex(&placeholderValue);
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
// testing for an invalid index
if(index > numArgs)
if (index > numArgs)
{
appendInvalidPlaceholder(buffer, "{?", &placeholderValue, i, formatstr->length);
continue;
}
// continue normally if an format arg is set and the value is > 0
if(formatArgSet(&arguments[index - 1]))
if (formatArgSet(&arguments[index - 1]))
{
++numOpenIfs;
continue;
@@ -208,21 +227,21 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
}
// test for not if, if so evaluate it
if(placeholderValue.chars[0] == '/')
if (firstChar == '/')
{
ffStrbufSubstrAfter(&placeholderValue, 0);
uint32_t index = getArgumentIndex(&placeholderValue);
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
// testing for an invalid index
if(index > numArgs)
if (index > numArgs)
{
appendInvalidPlaceholder(buffer, "{/", &placeholderValue, i, formatstr->length);
continue;
}
//continue normally if an format arg is not set or the value is 0
if(!formatArgSet(&arguments[index - 1]))
if (!formatArgSet(&arguments[index - 1]))
{
++numOpenNotIfs;
continue;
@@ -234,20 +253,21 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
}
//test for color, if so evaluate it
if(placeholderValue.chars[0] == '#')
if (firstChar == '#')
{
++numOpenColors;
ffStrbufSubstrAfter(&placeholderValue, 0);
ffStrbufAppendS(buffer, "\033[");
ffStrbufAppend(buffer, &placeholderValue);
ffStrbufAppendC(buffer, 'm');
if (!instance.config.display.pipe)
{
ffStrbufAppendS(buffer, "\e[");
ffOptionParseColorNoClear(placeholderValue.chars + 1, buffer);
ffStrbufAppendC(buffer, 'm');
}
continue;
}
uint32_t index = getArgumentIndex(&placeholderValue);
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
// test for invalid index
if(index > numArgs)
if (index > numArgs)
{
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
@@ -256,5 +276,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
}
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
if (!instance.config.display.pipe)
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
}
+1
View File
@@ -20,6 +20,7 @@ typedef struct FFformatarg
{
FFformatargtype type;
const void* value;
const char* name; // argument name, must start with an alphabet
} FFformatarg;
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
+6 -1
View File
@@ -22,6 +22,11 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
return true;
}
else if(ffStrEqualsIgnCase(key, "outputColor"))
{
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->outputColor);
return true;
}
else if(ffStrEqualsIgnCase(key, "keyColor"))
{
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->keyColor);
@@ -94,7 +99,7 @@ static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
{
if(!isalpha(type[0])) return false;
if(!ffCharIsEnglishAlphabet(type[0])) return false;
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
{
+4
View File
@@ -1,6 +1,8 @@
#include "fastfetch.h"
#include "common/library.h"
#ifndef FF_DISABLE_DLOPEN
#include <stdarg.h>
//Clang doesn't define __SANITIZE_ADDRESS__ but defines __has_feature(address_sanitizer)
@@ -77,3 +79,5 @@ void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...)
return result;
}
#endif
+44
View File
@@ -3,6 +3,8 @@
#include "fastfetch.h"
#include "util/FFcheckmacros.h"
#ifndef FF_DISABLE_DLOPEN
#if defined(_WIN32)
#include <libloaderapi.h>
#define FF_DLOPEN_FLAGS 0
@@ -71,3 +73,45 @@ static inline void ffLibraryUnload(void** handle)
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
#else
#define FF_LIBRARY_EXTENSION ""
#define FF_LIBRARY_SYMBOL(symbolName) \
__typeof__(&symbolName) ff ## symbolName;
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
FF_MAYBE_UNUSED void* libraryObjectName = NULL; // Placeholder
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
symbolMapping = (__typeof__(&symbolName)) &symbolName
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \
symbolMapping = (__typeof__(&symbolName)) &symbolName
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
FF_MAYBE_UNUSED __typeof__(&symbolName) ff ## symbolName = (__typeof__(&symbolName)) &symbolName;
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE2(library, symbolName, alternateName) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
#endif
+5
View File
@@ -9,6 +9,7 @@ static FFModuleBaseInfo* B[] = {
(void*) &instance.config.modules.bios,
(void*) &instance.config.modules.bluetooth,
(void*) &instance.config.modules.board,
(void*) &instance.config.modules.bootmgr,
(void*) &instance.config.modules.break_,
(void*) &instance.config.modules.brightness,
NULL,
@@ -36,6 +37,7 @@ static FFModuleBaseInfo* D[] = {
};
static FFModuleBaseInfo* E[] = {
(void*) &instance.config.modules.editor,
NULL,
};
@@ -57,6 +59,7 @@ static FFModuleBaseInfo* H[] = {
static FFModuleBaseInfo* I[] = {
(void*) &instance.config.modules.icons,
(void*) &instance.config.modules.initSystem,
NULL,
};
@@ -71,6 +74,7 @@ static FFModuleBaseInfo* K[] = {
static FFModuleBaseInfo* L[] = {
(void*) &instance.config.modules.lm,
(void*) &instance.config.modules.loadavg,
(void*) &instance.config.modules.locale,
(void*) &instance.config.modules.localIP,
NULL,
@@ -98,6 +102,7 @@ static FFModuleBaseInfo* O[] = {
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.modules.packages,
(void*) &instance.config.modules.physicalDisk,
(void*) &instance.config.modules.physicalMemory,
(void*) &instance.config.modules.player,
(void*) &instance.config.modules.powerAdapter,
(void*) &instance.config.modules.processes,
+1
View File
@@ -22,6 +22,7 @@ typedef struct FFNetworkingState {
#endif
uint32_t timeout;
bool ipv6;
} FFNetworkingState;
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
+1 -1
View File
@@ -14,7 +14,7 @@ static const char* connectAndSend(FFNetworkingState* state)
struct addrinfo* addr;
if(getaddrinfo(state->host.chars, "80", &(struct addrinfo) {
.ai_family = AF_INET,
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
.ai_socktype = SOCK_STREAM,
}, &addr) != 0)
{
+1 -1
View File
@@ -51,7 +51,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
struct addrinfo* addr;
if(getaddrinfo(host, "80", &(struct addrinfo) {
.ai_family = AF_INET,
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
.ai_socktype = SOCK_STREAM,
}, &addr) != 0)
return "getaddrinfo() failed";
+43 -26
View File
@@ -39,6 +39,16 @@ bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const
ffOptionParseString(argumentKey, value, &result->outputFormat);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "output-color"))
{
if(value == NULL)
{
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
exit(477);
}
ffOptionParseColor(value, &result->outputColor);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "key-color"))
{
if(value == NULL)
@@ -135,41 +145,46 @@ bool ffOptionParseBoolean(const char* str)
);
}
void ffOptionParseColor(const char* value, FFstrbuf* buffer)
void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
{
ffStrbufClear(buffer);
ffStrbufEnsureFree(buffer, 63);
while(*value != '\0')
{
#define FF_APPEND_COLOR_CODE_COND(prefix, code) \
if(ffStrStartsWithIgnCase(value, #prefix)) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); }
if(ffStrStartsWithIgnCase(value, #prefix)) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); continue; }
FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET)
else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD)
else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM)
else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK)
else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED)
else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN)
else FF_APPEND_COLOR_CODE_COND(yellow, FF_COLOR_FG_YELLOW)
else FF_APPEND_COLOR_CODE_COND(blue, FF_COLOR_FG_BLUE)
else FF_APPEND_COLOR_CODE_COND(magenta, FF_COLOR_FG_MAGENTA)
else FF_APPEND_COLOR_CODE_COND(cyan, FF_COLOR_FG_CYAN)
else FF_APPEND_COLOR_CODE_COND(white, FF_COLOR_FG_WHITE)
else FF_APPEND_COLOR_CODE_COND(default, FF_COLOR_FG_DEFAULT)
else FF_APPEND_COLOR_CODE_COND(light_black, FF_COLOR_FG_LIGHT_BLACK)
else FF_APPEND_COLOR_CODE_COND(light_red, FF_COLOR_FG_LIGHT_RED)
else FF_APPEND_COLOR_CODE_COND(light_green, FF_COLOR_FG_LIGHT_GREEN)
else FF_APPEND_COLOR_CODE_COND(light_yellow, FF_COLOR_FG_LIGHT_YELLOW)
else FF_APPEND_COLOR_CODE_COND(light_blue, FF_COLOR_FG_LIGHT_BLUE)
else FF_APPEND_COLOR_CODE_COND(light_magenta, FF_COLOR_FG_LIGHT_MAGENTA)
else FF_APPEND_COLOR_CODE_COND(light_cyan, FF_COLOR_FG_LIGHT_CYAN)
else FF_APPEND_COLOR_CODE_COND(light_white, FF_COLOR_FG_LIGHT_WHITE)
else
if (ffCharIsEnglishAlphabet(value[0]))
{
ffStrbufAppendC(buffer, *value);
++value;
FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET)
else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD)
else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM)
else FF_APPEND_COLOR_CODE_COND(italic_, FF_COLOR_MODE_ITALIC)
else FF_APPEND_COLOR_CODE_COND(underline_, FF_COLOR_MODE_UNDERLINE)
else FF_APPEND_COLOR_CODE_COND(blink_, FF_COLOR_MODE_BLINK)
else FF_APPEND_COLOR_CODE_COND(inverse_, FF_COLOR_MODE_INVERSE)
else FF_APPEND_COLOR_CODE_COND(hidden_, FF_COLOR_MODE_HIDDEN)
else FF_APPEND_COLOR_CODE_COND(strike_, FF_COLOR_MODE_STRIKETHROUGH)
else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK)
else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED)
else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN)
else FF_APPEND_COLOR_CODE_COND(yellow, FF_COLOR_FG_YELLOW)
else FF_APPEND_COLOR_CODE_COND(blue, FF_COLOR_FG_BLUE)
else FF_APPEND_COLOR_CODE_COND(magenta, FF_COLOR_FG_MAGENTA)
else FF_APPEND_COLOR_CODE_COND(cyan, FF_COLOR_FG_CYAN)
else FF_APPEND_COLOR_CODE_COND(white, FF_COLOR_FG_WHITE)
else FF_APPEND_COLOR_CODE_COND(default, FF_COLOR_FG_DEFAULT)
else FF_APPEND_COLOR_CODE_COND(light_black, FF_COLOR_FG_LIGHT_BLACK)
else FF_APPEND_COLOR_CODE_COND(light_red, FF_COLOR_FG_LIGHT_RED)
else FF_APPEND_COLOR_CODE_COND(light_green, FF_COLOR_FG_LIGHT_GREEN)
else FF_APPEND_COLOR_CODE_COND(light_yellow, FF_COLOR_FG_LIGHT_YELLOW)
else FF_APPEND_COLOR_CODE_COND(light_blue, FF_COLOR_FG_LIGHT_BLUE)
else FF_APPEND_COLOR_CODE_COND(light_magenta, FF_COLOR_FG_LIGHT_MAGENTA)
else FF_APPEND_COLOR_CODE_COND(light_cyan, FF_COLOR_FG_LIGHT_CYAN)
else FF_APPEND_COLOR_CODE_COND(light_white, FF_COLOR_FG_LIGHT_WHITE)
}
ffStrbufAppendC(buffer, *value);
++value;
#undef FF_APPEND_COLOR_CODE_COND
}
@@ -180,6 +195,7 @@ void ffOptionInitModuleArg(FFModuleArgs* args)
ffStrbufInit(&args->key);
ffStrbufInit(&args->keyColor);
ffStrbufInit(&args->outputFormat);
ffStrbufInit(&args->outputColor);
args->keyWidth = 0;
}
@@ -188,4 +204,5 @@ void ffOptionDestroyModuleArg(FFModuleArgs* args)
ffStrbufDestroy(&args->key);
ffStrbufDestroy(&args->keyColor);
ffStrbufDestroy(&args->outputFormat);
ffStrbufDestroy(&args->outputColor);
}
+7 -1
View File
@@ -50,6 +50,7 @@ typedef struct FFModuleArgs
FFstrbuf key;
FFstrbuf keyColor;
FFstrbuf outputFormat;
FFstrbuf outputColor;
uint32_t keyWidth;
} FFModuleArgs;
@@ -66,6 +67,11 @@ FF_C_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char*
FF_C_NODISCARD int32_t ffOptionParseInt32(const char* argumentKey, const char* value);
FF_C_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]);
FF_C_NODISCARD bool ffOptionParseBoolean(const char* str);
void ffOptionParseColor(const char* value, FFstrbuf* buffer);
void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer);
static inline void ffOptionParseColor(const char* value, FFstrbuf* buffer)
{
ffStrbufClear(buffer);
ffOptionParseColorNoClear(value, buffer);
}
void ffOptionInitModuleArg(FFModuleArgs* args);
void ffOptionDestroyModuleArg(FFModuleArgs* args);
+43 -11
View File
@@ -6,7 +6,15 @@
#include "util/textModifier.h"
#include "util/stringUtils.h"
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config)
static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
{
if (module->outputColor.length)
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
else if (instance.config.display.colorOutput.length)
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
}
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -42,14 +50,34 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
{
if(!options->pipe)
{
uint32_t section1Begin = (uint32_t) ((green <= yellow ? green : yellow) / 100.0 * options->barWidth + 0.5);
uint32_t section2Begin = (uint32_t) ((green > yellow ? green : yellow) / 100.0 * options->barWidth + 0.5);
if (i == section2Begin)
ffStrbufAppendF(buffer, "\e[%sm", (green > yellow ? colorGreen : colorRed));
else if (i == section1Begin)
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
else if (i == 0)
ffStrbufAppendF(buffer, "\e[%sm", (green <= yellow ? colorGreen : colorRed));
if (options->percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT)
{
const char* color = NULL;
if (green <= yellow)
{
if (percent < green) color = colorGreen;
else if (percent < yellow) color = colorYellow;
else color = colorRed;
}
else
{
if (percent < yellow) color = colorRed;
else if (percent < green) color = colorYellow;
else color = colorGreen;
}
ffStrbufAppendF(buffer, "\e[%sm", color);
}
else
{
uint32_t section1Begin = (uint32_t) ((green <= yellow ? green : yellow) / 100.0 * options->barWidth + 0.5);
uint32_t section2Begin = (uint32_t) ((green > yellow ? green : yellow) / 100.0 * options->barWidth + 0.5);
if (i == section2Begin)
ffStrbufAppendF(buffer, "\e[%sm", (green > yellow ? colorGreen : colorRed));
else if (i == section1Begin)
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
else if (i == 0)
ffStrbufAppendF(buffer, "\e[%sm", (green <= yellow ? colorGreen : colorRed));
}
}
ffStrbufAppend(buffer, &options->barCharElapsed);
}
@@ -66,16 +94,19 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
if(options->barBorder)
{
if(!options->pipe)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");\
else
ffStrbufAppendS(buffer, " ]");
}
if(!options->pipe)
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
appendOutputColor(buffer, module);
}
}
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses)
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -120,6 +151,7 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig con
if (colored && !options->pipe)
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
appendOutputColor(buffer, module);
}
if (parentheses)
+5 -3
View File
@@ -2,13 +2,15 @@
#include "util/FFstrbuf.h"
#include "common/parsing.h"
#include "common/option.h"
enum
enum FFPercentageTypeFlags
{
FF_PERCENTAGE_TYPE_NUM_BIT = 1 << 0,
FF_PERCENTAGE_TYPE_BAR_BIT = 1 << 1,
FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT = 1 << 2,
FF_PERCENTAGE_TYPE_NUM_COLOR_BIT = 1 << 3,
FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT = FF_PERCENTAGE_TYPE_NUM_COLOR_BIT,
};
// if (green <= yellow)
@@ -21,8 +23,8 @@ enum
// [yellow, green): print yellow
// [0, yellow): print red
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses);
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module);
typedef struct yyjson_val yyjson_val;
typedef struct yyjson_mut_doc yyjson_mut_doc;
+50 -42
View File
@@ -11,52 +11,63 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
return;
//This is used as a magic value for hiding keys
if(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " "))
return;
if(!instance.config.display.pipe)
if (!(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " ")))
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (instance.config.display.brightColor)
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
if(!instance.config.display.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (instance.config.display.brightColor)
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
ffPrintColor(&moduleArgs->keyColor);
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
ffPrintColor(&moduleArgs->keyColor);
else
ffPrintColor(&instance.config.display.colorKeys);
}
//NULL check is required for modules with custom keys, e.g. disk with the folder path
if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
{
fputs(moduleName, stdout);
if(moduleIndex > 0)
printf(" %hhu", moduleIndex);
}
else
ffPrintColor(&instance.config.display.colorKeys);
}
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 1, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex, "index"},
}));
ffStrbufWriteTo(&key, stdout);
}
//NULL check is required for modules with custom keys, e.g. disk with the folder path
if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
{
fputs(moduleName, stdout);
if(!instance.config.display.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
ffPrintColor(&instance.config.display.colorSeparator);
}
if(moduleIndex > 0)
printf(" %hhu", moduleIndex);
}
else
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 1, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex}
}));
ffStrbufWriteTo(&key, stdout);
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
if(!instance.config.display.pipe && instance.config.display.colorSeparator.length)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (!(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
{
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
if (keyWidth > 0)
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
}
}
if(!instance.config.display.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
if(!instance.config.display.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (!instance.config.display.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
{
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
if (keyWidth > 0)
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (moduleArgs->outputColor.length)
ffPrintColor(&moduleArgs->outputColor);
else if (instance.config.display.colorOutput.length)
ffPrintColor(&instance.config.display.colorOutput);
}
}
@@ -68,11 +79,8 @@ void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleAr
else
ffStrbufAppendS(&buffer, "unknown");
if(buffer.length > 0)
{
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
ffStrbufPutTo(&buffer, stdout);
}
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
ffStrbufPutTo(&buffer, stdout);
}
static void printError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, va_list arguments)
+11 -8
View File
@@ -2,16 +2,15 @@
#include "util/FFstrbuf.h"
#include <sys/types.h>
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr);
static inline const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
{
const char* error = ffProcessAppendOutput(buffer, argv, false);
if (!error)
{
ffStrbufTrimRight(buffer, '\n');
ffStrbufTrimRight(buffer, ' ');
}
ffStrbufTrimRightSpace(buffer);
return error;
}
@@ -19,9 +18,13 @@ static inline const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const ar
{
const char* error = ffProcessAppendOutput(buffer, argv, true);
if (!error)
{
ffStrbufTrimRight(buffer, '\n');
ffStrbufTrimRight(buffer, ' ');
}
ffStrbufTrimRightSpace(buffer);
return error;
}
#ifdef _WIN32
bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath, bool* gui);
#else
void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath);
const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, int32_t* tty);
#endif
+242
View File
@@ -2,6 +2,8 @@
#include "common/processing.h"
#include "common/io/io.h"
#include "common/time.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <unistd.h>
@@ -11,6 +13,15 @@
#include <errno.h>
#include <sys/wait.h>
#if defined(__FreeBSD__) || defined(__APPLE__)
#include <sys/types.h>
#include <sys/user.h>
#include <sys/sysctl.h>
#endif
#ifdef __APPLE__
#include <libproc.h>
#endif
enum { FF_PIPE_BUFSIZ = 8192 };
static inline int ffPipe2(int *fds, int flags)
@@ -101,3 +112,234 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
return "read(childPipeFd, str, FF_PIPE_BUFSIZ) failed";
}
void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath)
{
assert(processName->length > 0);
ffStrbufClear(exe);
#ifdef __linux__
char filePath[64];
snprintf(filePath, sizeof(filePath), "/proc/%d/cmdline", (int)pid);
if(ffReadFileBuffer(filePath, exe))
{
ffStrbufRecalculateLength(exe); //Trim the arguments
ffStrbufTrimRightSpace(exe);
ffStrbufTrimLeft(exe, '-'); //Login shells start with a dash
}
if (exePath)
{
snprintf(filePath, sizeof(filePath), "/proc/%d/exe", (int)pid);
ffStrbufEnsureFixedLengthFree(exePath, PATH_MAX);
ssize_t length = readlink(filePath, exePath->chars, exePath->allocated - 1);
if (length > 0) // doesn't contain trailing NUL
{
exePath->chars[length] = '\0';
exePath->length = (uint32_t) length;
}
}
#elif defined(__APPLE__)
size_t len = 0;
int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid };
if (sysctl(mibs, sizeof(mibs) / sizeof(*mibs), NULL, &len, NULL, 0) == 0)
{// try get arg0
#ifndef MAC_OS_X_VERSION_10_15
//don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version.
len++;
#endif
FF_AUTO_FREE char* const procArgs2 = malloc(len);
if (sysctl(mibs, sizeof(mibs) / sizeof(*mibs), procArgs2, &len, NULL, 0) == 0)
{
// https://gist.github.com/nonowarn/770696#file-getargv-c-L46
uint32_t argc = *(uint32_t*) procArgs2;
const char* realExePath = procArgs2 + sizeof(argc);
const char* arg0 = memchr(realExePath, '\0', len - (size_t) (realExePath - procArgs2));
if (exePath)
ffStrbufSetNS(exePath, (uint32_t) (arg0 - realExePath), realExePath);
do arg0++; while (*arg0 == '\0');
assert(arg0 < procArgs2 + len);
if (argc > 1)
{
// #977
const char* p = strrchr(arg0, '/');
if (p)
p++;
else
p = arg0;
if (ffStrStartsWithIgnCase(p, "python")) // /opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/Resources/Python.app/Contents/MacOS/Python /Users/carter/.local/bin/xonsh
arg0 = p + strlen(p) + 1;
}
if (*arg0 == '-') arg0++; // Login shells
ffStrbufSetS(exe, arg0);
}
}
else
{
ffStrbufEnsureFixedLengthFree(exe, PATH_MAX);
int length = proc_pidpath(pid, exe->chars, exe->allocated);
if (length > 0)
{
exe->length = (uint32_t) length;
if (exePath)
ffStrbufSet(exePath, exe);
}
}
#elif defined(__FreeBSD__)
size_t size = ARG_MAX;
FF_AUTO_FREE char* args = malloc(size);
static_assert(ARG_MAX > PATH_MAX, "");
if(exePath && sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid}, 4,
args, &size,
NULL, 0
) == 0)
ffStrbufSetNS(exePath, (uint32_t) (size - 1), args);
size = ARG_MAX;
if(sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_ARGS, pid}, 4,
args, &size,
NULL, 0
) == 0)
{
char* arg0 = args;
size_t arg0Len = strlen(args);
if (size > arg0Len + 1)
{
char* p = (char*) memrchr(args, '/', arg0Len);
if (p)
p++;
else
p = arg0;
if (ffStrStartsWith(p, "python")) // /usr/local/bin/python3.9 /home/carter/.local/bin/xonsh
{
arg0 += arg0Len + 1;
}
}
if (arg0[0] == '-') arg0++;
ffStrbufSetS(exe, arg0);
}
#endif
if(exe->length == 0)
ffStrbufSet(exe, processName);
assert(exe->length > 0);
uint32_t lastSlashIndex = ffStrbufLastIndexC(exe, '/');
if(lastSlashIndex < exe->length)
*exeName = exe->chars + lastSlashIndex + 1;
}
const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, int32_t* tty)
{
if (pid <= 0)
return "Invalid pid";
#ifdef __linux__
char procFilePath[64];
if (ppid)
{
snprintf(procFilePath, sizeof(procFilePath), "/proc/%d/stat", (int)pid);
char buf[PROC_FILE_BUFFSIZ];
ssize_t nRead = ffReadFileData(procFilePath, sizeof(buf) - 1, buf);
if(nRead <= 8)
return "ffReadFileData(/proc/pid/stat, PROC_FILE_BUFFSIZ-1, buf) failed";
buf[nRead] = '\0';
*ppid = 0;
static_assert(sizeof(*ppid) == sizeof(int), "");
ffStrbufEnsureFixedLengthFree(name, 255);
int tty_;
if(
sscanf(buf, "%*s (%255[^)]) %*c %d %*d %*d %d", name->chars, ppid, &tty_) < 2 || //stat (comm) state ppid pgrp session tty
name->chars[0] == '\0'
)
return "sscanf(stat) failed";
ffStrbufRecalculateLength(name);
if (tty)
*tty = tty_ & 0xFF;
}
else
{
snprintf(procFilePath, sizeof(procFilePath), "/proc/%d/comm", (int)pid);
ssize_t nRead = ffReadFileBuffer(procFilePath, name);
if(nRead <= 0)
return "ffReadFileBuffer(/proc/pid/comm, name) failed";
ffStrbufTrimRightSpace(name);
}
#elif defined(__APPLE__)
struct kinfo_proc proc;
size_t size = sizeof(proc);
if(sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}, 4,
&proc, &size,
NULL, 0
))
return "sysctl(KERN_PROC_PID) failed";
ffStrbufSetS(name, proc.kp_proc.p_comm); //trancated to 16 chars
if (ppid)
*ppid = (pid_t)proc.kp_eproc.e_ppid;
if (tty)
{
*tty = ((proc.kp_eproc.e_tdev >> 24) & 0xFF) == 0x10
? proc.kp_eproc.e_tdev & 0xFFFFFF
: -1;
}
#elif defined(__FreeBSD__)
struct kinfo_proc proc;
size_t size = sizeof(proc);
if(sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}, 4,
&proc, &size,
NULL, 0
))
return "sysctl(KERN_PROC_PID) failed";
ffStrbufSetS(name, proc.ki_comm);
if (ppid)
*ppid = (pid_t)proc.ki_ppid;
if (tty)
{
if (proc.ki_tdev != NODEV && proc.ki_flag & P_CONTROLT)
{
const char* ttyName = devname(proc.ki_tdev, S_IFCHR);
if (ffStrStartsWith(ttyName, "pts/"))
*tty = (int32_t) strtol(ttyName + strlen("pts/"), NULL, 10);
else
*tty = -1;
}
else
*tty = -1;
}
#else
return "Unsupported platform";
#endif
return NULL;
}
+45
View File
@@ -3,6 +3,8 @@
#include "common/io/io.h"
#include <Windows.h>
#include <ntstatus.h>
#include <winternl.h>
enum { FF_PIPE_BUFSIZ = 8192 };
@@ -124,3 +126,46 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
return NULL;
}
bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath, bool* gui)
{
FF_AUTO_CLOSE_FD HANDLE hProcess = pid == 0
? GetCurrentProcess()
: OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (gui)
*gui = GetGuiResources(hProcess, GR_GDIOBJECTS) > 0;
if(ppid)
{
PROCESS_BASIC_INFORMATION info = {};
ULONG size;
if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &info, sizeof(info), &size)))
{
assert(size == sizeof(info));
*ppid = (uint32_t)info.InheritedFromUniqueProcessId;
}
else
return false;
}
if(exe)
{
DWORD bufSize = exe->allocated;
if(QueryFullProcessImageNameA(hProcess, 0, exe->chars, &bufSize))
{
// We use full path here
// Querying command line of remote processes in Windows requires either WMI or ReadProcessMemory
exe->length = bufSize;
if (exePath) ffStrbufSet(exePath, exe);
}
else
return false;
}
if(pname && exeName)
{
*exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1;
ffStrbufSetS(pname, *exeName);
}
return true;
}
+25 -29
View File
@@ -1,5 +1,7 @@
#include "fastfetch.h"
#include "common/properties.h"
#include "common/io/io.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#ifdef _WIN32
@@ -95,50 +97,44 @@ bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries)
{
FILE* file = fopen(filename, "r");
if(file == NULL)
FF_AUTO_CLOSE_FILE FILE* file = fopen(filename, "r");
if (file == NULL)
return false;
bool valueStorage[4];
bool* unsetValues;
bool valueStorage[32];
bool* unsetValues = valueStorage;
if(numQueries > sizeof(valueStorage) / sizeof(valueStorage[0]))
if (numQueries > sizeof(valueStorage) / sizeof(valueStorage[0]))
unsetValues = malloc(sizeof(bool) * numQueries);
else
unsetValues = valueStorage;
bool allSet = true;
for(uint32_t i = 0; i < numQueries; i++)
for (uint32_t i = 0; i < numQueries; i++)
{
if((unsetValues[i] = queries[i].buffer->length == 0))
unsetValues[i] = queries[i].buffer->length == 0;
if (unsetValues[i])
allSet = false;
}
if(allSet)
goto done;
char* line = NULL;
size_t len = 0;
while (getline(&line, &len, file) != -1)
if (!allSet)
{
for(uint32_t i = 0; i < numQueries; i++)
{
if(!unsetValues[i])
continue;
FF_AUTO_FREE char* line = NULL;
size_t len = 0;
uint32_t currentLength = queries[i].buffer->length;
queries[i].buffer->length = 0;
if(!ffParsePropLine(line, queries[i].start, queries[i].buffer))
queries[i].buffer->length = currentLength;
while (getline(&line, &len, file) != -1)
{
for(uint32_t i = 0; i < numQueries; i++)
{
if(!unsetValues[i])
continue;
uint32_t currentLength = queries[i].buffer->length;
queries[i].buffer->length = 0;
if(!ffParsePropLine(line, queries[i].start, queries[i].buffer))
queries[i].buffer->length = currentLength;
}
}
}
if(line != NULL)
free(line);
done:
fclose(file);
if(unsetValues != valueStorage)
free(unsetValues);
return true;
+88 -90
View File
@@ -6,45 +6,6 @@
#include <string.h>
typedef enum FFInitState
{
FF_INITSTATE_UNINITIALIZED = 0,
FF_INITSTATE_SUCCESSFUL = 1,
FF_INITSTATE_FAILED = 2
} FFInitState;
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
static dataObject data; \
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
if(initState != FF_INITSTATE_UNINITIALIZED) {\
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
} \
initState = FF_INITSTATE_SUCCESSFUL; \
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
if(libraryHandle == NULL) { \
initState = FF_INITSTATE_FAILED; \
return NULL; \
} \
#define FF_LIBRARY_DATA_LOAD_SYMBOL(symbolName) \
data.ff ## symbolName = dlsym(libraryHandle, #symbolName); \
if(data.ff ## symbolName == NULL) { \
dlclose(libraryHandle); \
initState = FF_INITSTATE_FAILED; \
return NULL; \
}
#define FF_LIBRARY_DATA_LOAD_RETURN \
initState = FF_INITSTATE_SUCCESSFUL; \
return &data;
#define FF_LIBRARY_DATA_LOAD_ERROR \
{ \
dlclose(libraryHandle); \
initState = FF_INITSTATE_FAILED; \
return NULL; \
}
#ifdef FF_HAVE_GIO
#include <gio/gio.h>
@@ -88,32 +49,39 @@ typedef struct GSettingsData
FF_LIBRARY_SYMBOL(g_settings_schema_source_get_default)
GSettingsSchemaSource* schemaSource;
GVariantGetters variantGetters;
bool inited;
} GSettingsData;
static const GSettingsData* getGSettingsData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.library.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
static GSettingsData data;
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_new_full)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_value)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_user_value)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_default_value)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_get_default)
if (!data.inited)
{
data.inited = true;
FF_LIBRARY_LOAD(libgsettings, &instance.config.library.libGIO, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_lookup, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_has_key, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_new_full, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_value, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_user_value, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_default_value, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_get_default, NULL)
#define data data.variantGetters
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref);
#undef data
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_dup_string, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_boolean, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_int32, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_unref, NULL);
data.schemaSource = data.ffg_settings_schema_source_get_default();
if(data.schemaSource == NULL)
FF_LIBRARY_DATA_LOAD_ERROR
data.schemaSource = data.ffg_settings_schema_source_get_default();
if (data.schemaSource)
libgsettings = NULL;
}
if(!data.schemaSource)
return NULL;
FF_LIBRARY_DATA_LOAD_RETURN
return &data;
}
FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type)
@@ -161,27 +129,34 @@ typedef struct DConfData
FF_LIBRARY_SYMBOL(dconf_client_new)
GVariantGetters variantGetters;
DConfClient* client;
bool inited;
} DConfData;
static const DConfData* getDConfData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.library.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
static DConfData data;
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full)
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
if (!data.inited)
{
data.inited = true;
#define data data.variantGetters
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref)
#undef data
FF_LIBRARY_LOAD(libdconf, &instance.config.library.libDConf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2);
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_read_full, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_new, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_dup_string, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_boolean, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_int32, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_unref, NULL)
data.client = data.ffdconf_client_new();
if(data.client == NULL)
FF_LIBRARY_DATA_LOAD_ERROR
data.client = data.ffdconf_client_new();
if (data.client)
libdconf = NULL;
}
if(!data.client)
return NULL;
FF_LIBRARY_DATA_LOAD_RETURN
return &data;
}
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type)
@@ -232,23 +207,35 @@ typedef struct XFConfData
FF_LIBRARY_SYMBOL(xfconf_channel_get_bool)
FF_LIBRARY_SYMBOL(xfconf_channel_get_int)
FF_LIBRARY_SYMBOL(xfconf_init)
bool inited;
} XFConfData;
static const XFConfData* getXFConfData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.library.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
static XFConfData data;
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get)
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property)
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_string)
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_bool)
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_int)
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_init)
if (!data.inited)
{
data.inited = true;
FF_LIBRARY_LOAD(libxfconf, &instance.config.library.libXFConf, NULL, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
if(data.ffxfconf_init(NULL) == false)
FF_LIBRARY_DATA_LOAD_ERROR
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_has_property, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_string, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_bool, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_int, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_init, NULL)
if(!data.ffxfconf_init(NULL))
data.ffxfconf_init = NULL;
else
libxfconf = NULL;
}
FF_LIBRARY_DATA_LOAD_RETURN
if(!data.ffxfconf_init)
return NULL;
return &data;
}
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
@@ -294,22 +281,33 @@ typedef struct SQLiteData
FF_LIBRARY_SYMBOL(sqlite3_column_text)
FF_LIBRARY_SYMBOL(sqlite3_finalize)
FF_LIBRARY_SYMBOL(sqlite3_close)
bool inited;
} SQLiteData;
static const SQLiteData* getSQLiteData(void)
{
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.library.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
static SQLiteData data;
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_step)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_data_count)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_int)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_text)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_finalize)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_close)
if (!data.inited)
{
data.inited = true;
FF_LIBRARY_LOAD(libsqlite, &instance.config.library.libSQLite3, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_open_v2, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_prepare_v2, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_step, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_data_count, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_int, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_text, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_finalize, NULL)
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_close, NULL)
libsqlite = NULL;
}
FF_LIBRARY_DATA_LOAD_RETURN
if (!data.ffsqlite3_close)
return NULL;
return &data;
}
int ffSettingsGetSQLite3Int(const char* dbPath, const char* query)
+8 -2
View File
@@ -3,7 +3,7 @@
#include "util/textModifier.h"
#include "util/stringUtils.h"
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config)
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module)
{
if (celsius != celsius) // ignores NaN
return;
@@ -37,7 +37,7 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
}
}
switch (options->temperatureUnit)
switch (options->tempUnit)
{
case FF_TEMPERATURE_UNIT_CELSIUS:
ffStrbufAppendF(buffer, "%.*f°C", options->tempNdigits, celsius);
@@ -51,7 +51,13 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
}
if (!options->pipe)
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
if (module->outputColor.length)
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
else if (instance.config.display.colorOutput.length)
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
}
}
bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config)
+2 -1
View File
@@ -1,8 +1,9 @@
#pragma once
#include "common/parsing.h"
#include "common/option.h"
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config);
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module);
bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config);
bool ffTempsParseJsonObject(const char* key, yyjson_val* value, bool* useTemp, FFColorRangeConfig* config);
void ffTempsGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FF_MAYBE_UNUSED bool defaultTemp, FFColorRangeConfig defaultConfig, bool temp, FFColorRangeConfig config);
+78 -30
View File
@@ -436,7 +436,7 @@
{
"long": "color-keys",
"desc": "Set the color of the keys",
"remark": "See `-h color` for the list of available colors",
"remark": "Doesn't affect module Title, Separator and Colors. See `-h color` for the list of available colors",
"arg": {
"type": "color"
}
@@ -449,6 +449,22 @@
"type": "color"
}
},
{
"long": "color-output",
"desc": "Set the color of module output",
"remark": "See `-h color` for the list of available colors",
"arg": {
"type": "color"
}
},
{
"long": "color-separator",
"desc": "Set the color of the key-value separator",
"remark": "See `-h color` for the list of available colors",
"arg": {
"type": "color"
}
},
{
"long": "color",
"desc": "Set the color of both the keys and title",
@@ -481,22 +497,6 @@
"default": ": "
}
},
{
"long": "set",
"desc": "Hard set the value of a key",
"remark": "Deprecated. Use \"Custom\" module instead",
"arg": {
"type": "key=value"
}
},
{
"long": "set-keyless",
"desc": "Hard set the value of a key, but don't print the key or the separator",
"remark": "Deprecated. Use \"Custom\" module instead",
"arg": {
"type": "key=value"
}
},
{
"long": "show-errors",
"desc": "Print occurring errors",
@@ -521,7 +521,7 @@
"arg": {
"type": "bool",
"optional": true,
"default": true
"default": false
}
},
{
@@ -542,10 +542,11 @@
"desc": "Set the percentage output type",
"remark": [
"1 for percentage number",
"2 for bar",
"2 for multi-color bar",
"3 for both",
"6 for bar only",
"9 for colored number"
"9 for colored number",
"10 for monochrome bar"
],
"arg": {
"type": "num",
@@ -938,11 +939,11 @@
}
},
{
"long": "os-file",
"desc": "Set the additional file path which containing OS information",
"remark": "Linux only",
"long": "separator-output-color",
"desc": "Set the color of the separator module",
"arg": {
"type": "path"
"type": "color",
"default": "default"
}
},
{
@@ -1160,6 +1161,15 @@
"default": 2
}
},
{
"long": "cpu-show-pe-core-count",
"desc": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
"arg": {
"type": "bool",
"optional": true,
"default": false
}
},
{
"long": "cpuusage-separate",
"desc": "Display CPU usage per CPU logical core, instead of an average result",
@@ -1205,13 +1215,18 @@
}
},
{
"long": "gpu-force-vulkan",
"desc": "Force using vulkan to detect GPUs",
"remark": "Vulkan supports video memory usage detection",
"long": "gpu-detection-method",
"desc": "Force using a specified method to detect GPUs",
"remark": "Will fall back to next methods if the specified method fails",
"arg": {
"type": "bool",
"optional": true,
"default": false
"type": "enum",
"enum": {
"auto": "Query platform specific graphic APIs. Requires proper GPU drivers installed. Not supported on FreeBSD",
"pci": "Search PCI devices, which do not requires GPU driver installed. Not supported on Windows and macOS",
"vulkan": "Use Vulkan API. Slow and requires vulkan driver installed. Used for Android",
"opengl": "Use OpenGL API. Slow and only detects one GPU"
},
"default": "auto"
}
},
{
@@ -1236,6 +1251,14 @@
"default": false
}
},
{
"long": "loadavg-ndigits",
"desc": "Set the number of digits to keep after the decimal point when printing load average",
"arg": {
"type": "num",
"default": 2
}
},
{
"long": "localip-show-ipv4",
"desc": "Show IPv4 addresses in local ip module",
@@ -1298,6 +1321,15 @@
"default": true
}
},
{
"long": "localip-show-all-ips",
"desc": "Show all IPs bound to the same interface. By default only the first IP is shown",
"arg": {
"type": "bool",
"optional": true,
"default": false
}
},
{
"long": "localip-compact",
"desc": "Show all IPs in one line",
@@ -1348,6 +1380,14 @@
"type": "str"
}
},
{
"long": "publicip-ipv6",
"desc": "Whether to use IPv6 for public IP detection server",
"arg": {
"type": "bool",
"default": false
}
},
{
"long": "weather-location",
"desc": "Set the location to be used",
@@ -1522,6 +1562,14 @@
},
"pseudo": true
},
{
"long": "<module>-output-color",
"desc": "Override the global \"--color-output\" option for each specific module",
"arg": {
"type": "color"
},
"pseudo": true
},
{
"long": "<module>-key-width",
"desc": "Override the global \"--key-width\" option for each specific module",
+4 -3
View File
@@ -3,7 +3,8 @@ Usage: fastfetch --color <color>
<color> must be a color encoding as ANSI escape sequences. It is inserted between "ESC[" and "m".
Infos about them can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters.
Examples:
--color 35: sets the color to magenta. `--color magenta` is also supported
--color 4;92: sets the color to bright Green with underline
--color 5;104: blinking text on a blue background
--color 35: sets the color to magenta. `--color magenta` is also supported
--color 38;5;38: sets the color to 38th color of ANSI 256 colors
--color 4;92: sets the color to bright Green with underline. `--color underline_green` is also supported
--color 5;104: blinking text on a blue background
If no color is set, the main color of the logo will be used.
+6 -2
View File
@@ -4,6 +4,10 @@ For example the format string "Values: {1} ({2})", with the values "First" and "
The format string can contain placeholders in any order and have multiple occurrences.
To include spaces when setting from the command line, surround the whole string with double quotes (").
In 2.14.0 or newer, the value indices can be meaningful named tags.
For example: "--title-format '{user-name-colored}{at-symbol-colored}{host-name-colored}'" is equivalent to "--title-format '{6}{7}{8}'"
See "fastfetch -h title-format" for all supported tags.
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
@@ -16,7 +20,7 @@ To only print something if a variable is set, use "{?<index>} ... {?}".
For example, to only print a second value if it is set, use "{?2} Second value: {2}{?}".
If a "{?}" is found without an opener, it is printed as is.
To only print something if a variable is not set, do the same as with if, just replace every '?' with a '!'.
To only print something if a variable is not set, do the same as with if, just replace every '?' with a '/'.
For example to print a fallback for a second value if it is not set, use "{?2}{2}{?}{/2}Second value fallback{/}".
To stop formatting at any point in the format string, use "{-}".
@@ -24,7 +28,7 @@ To stop formatting at any point in the format string, use "{-}".
To print something with color, start a placeholder with a '#' and then the linux terminal color encoding.
"\033[" at the start, and an 'm' at the end is automatically added, so don't do that.
A "{#}" is equivalent to a "{#0}" and resets everything to normal.
For example to print something pink and underline, use "{#4;35}...{#}".
For example to print something pink and underline, use "{#4;35}...{#}". "{#underline_magenta}" is also supported. See `fastfetch -h color` for detail.
Information about what the numbers mean can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters.
Which escape codes are supported and how they look is defined by your terminal.
-3
View File
@@ -170,8 +170,5 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
ffStrbufSubstrBefore(&baseDir, baseDirLength);
}
if(results->length == 0)
return "\"/sys/class/power_supply/\" doesn't contain any battery folder";
return NULL;
}
+13 -20
View File
@@ -1,4 +1,7 @@
#include "battery.h"
#include "common/io/io.h"
#include "util/windows/nt.h"
#include "util/windows/unicode.h"
#include "util/mallocHelper.h"
#include "util/smbiosHelper.h"
@@ -10,21 +13,6 @@
#include <devguid.h>
#include <winternl.h>
NTSYSCALLAPI
NTSTATUS
NTAPI
NtPowerInformation(
IN POWER_INFORMATION_LEVEL InformationLevel,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength);
static inline void wrapCloseHandle(HANDLE* handle)
{
if(*handle)
CloseHandle(*handle);
}
static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
{
if(*hdev)
@@ -52,7 +40,7 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
if(!SetupDiGetDeviceInterfaceDetailW(hdev, &did, pdidd, cbRequired, &cbRequired, NULL))
continue;
HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hBattery =
HANDLE FF_AUTO_CLOSE_FD hBattery =
CreateFileW(pdidd->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hBattery == INVALID_HANDLE_VALUE)
@@ -157,8 +145,6 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
return NULL;
}
typedef struct FFSmbiosPortableBattery
{
FFSmbiosHeader Header;
@@ -181,11 +167,18 @@ typedef struct FFSmbiosPortableBattery
uint8_t SbdsDeviceChemistry; // string
uint8_t DesignCapacityMultiplier; // varies
uint16_t OEMSpecific; // varies
} FFSmbiosPortableBattery;
} __attribute__((__packed__)) FFSmbiosPortableBattery;
static_assert(offsetof(FFSmbiosPortableBattery, OEMSpecific) == 0x16,
"FFSmbiosPortableBattery: Wrong struct alignment");
const char* detectBySmbios(FFBatteryResult* battery)
{
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*smbiosTable)[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
if (!data)
return "Portable battery section is not found in SMBIOS data";
+1 -1
View File
@@ -4,7 +4,7 @@
#include <stdlib.h>
const char* ffDetectBios(FFBiosResult* bios)
const char *ffDetectBios(FFBiosResult *bios)
{
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
+11 -3
View File
@@ -1,5 +1,6 @@
#include "bios.h"
#include "util/smbiosHelper.h"
#include "util/windows/registry.h"
#include <ntstatus.h>
#include <winternl.h>
@@ -35,7 +36,7 @@ typedef struct FFSmbiosBios
uint16_t BiosStartingAddressSegment; // varies
uint8_t BiosReleaseDate; // string
uint8_t BiosRomSize; // string
uint32_t BiosCharacteristics; // bit field
uint64_t BiosCharacteristics; // bit field
// 2.4+
uint8_t BiosCharacteristicsExtensionBytes[2]; // bit field
@@ -46,11 +47,18 @@ typedef struct FFSmbiosBios
// 3.1+
uint16_t ExtendedBiosRomSize; // bit field
} FFSmbiosBios;
} __attribute__((__packed__)) FFSmbiosBios;
static_assert(offsetof(FFSmbiosBios, ExtendedBiosRomSize) == 0x18,
"FFSmbiosBios: Wrong struct alignment");
const char* ffDetectBios(FFBiosResult* bios)
{
const FFSmbiosBios* data = (const FFSmbiosBios*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_BIOS];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosBios* data = (const FFSmbiosBios*) (*smbiosTable)[FF_SMBIOS_TYPE_BIOS];
if (!data)
return "BIOS section is not found in SMBIOS data";
+11 -4
View File
@@ -14,13 +14,20 @@ typedef struct FFSmbiosBaseboard
uint8_t LocationInChassis; // string
uint16_t ChassisHandle; // varies
uint8_t BoardType; // enum
uint8_t NumberOfContainedObjectHandle; // varies
uint16_t ContainedObjectHandle[]; // varies
} FFSmbiosBaseboard;
uint8_t NumberOfContainedObjectHandles; // varies
uint16_t ContainedObjectHandles[]; // varies
} __attribute__((__packed__)) FFSmbiosBaseboard;
static_assert(offsetof(FFSmbiosBaseboard, ContainedObjectHandles) == 0x0F,
"FFSmbiosBaseboard: Wrong struct alignment");
const char* ffDetectBoard(FFBoardResult* board)
{
const FFSmbiosBaseboard* data = (const FFSmbiosBaseboard*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_BASEBOARD_INFO];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosBaseboard* data = (const FFSmbiosBaseboard*) (*smbiosTable)[FF_SMBIOS_TYPE_BASEBOARD_INFO];
if (!data)
return "Baseboard information section is not found in SMBIOS data";
+50
View File
@@ -0,0 +1,50 @@
#include "efi_helper.h"
static inline uint8_t evBits(uint16_t val, uint8_t mask, uint8_t shift)
{
return (uint8_t) ((val & (mask << shift)) >> shift);
}
static void ffEfiUcs2ToUtf8(const uint16_t *const chars, FFstrbuf* result)
{
for (uint32_t i = 0; chars[i]; i++)
{
if (chars[i] <= 0x007f)
ffStrbufAppendC(result, (char) chars[i]);
else if (chars[i] > 0x007f && chars[i] <= 0x07ff)
{
ffStrbufAppendC(result, (char) (0xc0 | evBits(chars[i], 0x1f, 6)));
ffStrbufAppendC(result, (char) (0x80 | evBits(chars[i], 0x3f, 0)));
}
else
{
ffStrbufAppendC(result, (char) (0xe0 | evBits(chars[i], 0xf, 12)));
ffStrbufAppendC(result, (char) (0x80 | evBits(chars[i], 0x3f, 6)));
ffStrbufAppendC(result, (char) (0x80 | evBits(chars[i], 0x3f, 0)));
}
}
}
bool ffEfiFillLoadOption(const FFEfiLoadOption* efiOption, FFBootmgrResult* result)
{
uint32_t descLen = 0;
while (efiOption->Description[descLen]) ++descLen;
if (descLen)
ffEfiUcs2ToUtf8(efiOption->Description, &result->name);
for (
ffEfiDevicePathProtocol* filePathList = (void*) &efiOption->Description[descLen + 1];
filePathList->Type != 0x7F; // End of Hardware Device Path
filePathList = (void*) ((uint8_t*) filePathList + filePathList->Length))
{
if (filePathList->Type == 4 && filePathList->SubType == 4)
{
// https://uefi.org/specs/UEFI/2.10/10_Protocols_Device_Path_Protocol.html#file-path-media-device-path
ffEfiUcs2ToUtf8((uint16_t*) filePathList->SpecificDevicePathData, &result->firmware);
return true;
}
}
return false;
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "fastfetch.h"
typedef struct FFBootmgrResult
{
FFstrbuf name;
FFstrbuf firmware;
bool secureBoot;
} FFBootmgrResult;
const char* ffDetectBootmgr(FFBootmgrResult* bios);
+12
View File
@@ -0,0 +1,12 @@
#include "bootmgr.h"
#include "common/io/io.h"
const char* ffDetectBootmgr(FFBootmgrResult* result)
{
if (ffPathExists("/System/Library/CoreServices/boot.efi", FF_PATHTYPE_FILE))
ffStrbufSetStatic(&result->firmware, "/System/Library/CoreServices/boot.efi");
ffStrbufSetStatic(&result->name, "iBoot");
return NULL;
}
+43
View File
@@ -0,0 +1,43 @@
#include "bootmgr.h"
#include "efi_helper.h"
#include "common/io/io.h"
#include <sys/efiio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
const char* ffDetectBootmgr(FFBootmgrResult* result)
{
FF_AUTO_CLOSE_FD int efifd = open("/dev/efi", O_RDWR);
if (efifd < 0) return "open(/dev/efi) failed";
uint8_t buffer[2048];
struct efi_var_ioc ioc = {
.vendor = { 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, { 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c } },
.data = buffer,
};
ioc.datasize = sizeof(buffer);
ioc.name = (efi_char[]){ 'B', 'o', 'o', 't', 'C', 'u', 'r', 'r', 'e', 'n', 't', '\0' };
ioc.namesize = sizeof("BootCurrent") * 2;
if (ioctl(efifd, EFIIOC_VAR_GET, &ioc) < 0 || ioc.datasize != 2)
return "ioctl(EFIIOC_VAR_GET, BootCurrent) failed";
unsigned char hex[5];
snprintf((char*) hex, sizeof(hex), "%04X", *(uint16_t*)buffer);
ioc.datasize = sizeof(buffer);
ioc.name = (efi_char[]){ 'B', 'o', 'o', 't', hex[0], hex[1], hex[2], hex[3], '\0' };
ioc.namesize = sizeof("Boot####") * 2;
if (ioctl(efifd, EFIIOC_VAR_GET, &ioc) < 0 || ioc.datasize == sizeof(buffer))
return "ioctl(EFIIOC_VAR_GET, Boot####) failed";
ffEfiFillLoadOption((FFEfiLoadOption *)buffer, result);
ioc.name = (efi_char[]){ 'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', '\0' };
ioc.namesize = sizeof("SecureBoot") * 2;
ioc.datasize = sizeof(buffer);
if (ioctl(efifd, EFIIOC_VAR_GET, &ioc) == 0 && ioc.datasize == 1)
result->secureBoot = !!buffer[0];
return NULL;
}
+27
View File
@@ -0,0 +1,27 @@
#include "bootmgr.h"
#include "common/io/io.h"
#include "efi_helper.h"
#define FF_EFIVARS_PATH_PREFIX "/sys/firmware/efi/efivars/"
const char* ffDetectBootmgr(FFBootmgrResult* result)
{
uint8_t buffer[2048];
if (ffReadFileData(FF_EFIVARS_PATH_PREFIX "BootCurrent-" FF_EFI_GLOBAL_GUID, sizeof(buffer), buffer) != 6)
return "Failed to read efivar: BootCurrent";
uint16_t value = *(uint16_t *)&buffer[4];
snprintf((char*) buffer, sizeof(buffer), FF_EFIVARS_PATH_PREFIX "Boot%04X-" FF_EFI_GLOBAL_GUID, value);
ssize_t size = ffReadFileData((const char*) buffer, sizeof(buffer), buffer);
if (size < 5 + (int) sizeof(FFEfiLoadOption) || size == (ssize_t) sizeof(buffer))
return "Failed to read efivar: Boot####";
ffEfiFillLoadOption((FFEfiLoadOption *)&buffer[4], result);
if (ffReadFileData(FF_EFIVARS_PATH_PREFIX "SecureBoot-" FF_EFI_GLOBAL_GUID, sizeof(buffer), buffer) == 6)
result->secureBoot = buffer[4] == 1;
return NULL;
}
@@ -0,0 +1,6 @@
#include "bootmgr.h"
const char* ffDetectBootmgr(FF_MAYBE_UNUSED FFBootmgrResult* result)
{
return "Not supported on this platform";
}
+53
View File
@@ -0,0 +1,53 @@
#include "bootmgr.h"
#include "efi_helper.h"
#include <windows.h>
const char* enablePrivilege(const wchar_t* privilege)
{
HANDLE token;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
return "OpenProcessToken() failed";
TOKEN_PRIVILEGES tp = {
.PrivilegeCount = 1,
.Privileges = {
(LUID_AND_ATTRIBUTES) { .Attributes = SE_PRIVILEGE_ENABLED }
},
};
if (!LookupPrivilegeValueW(NULL, privilege, &tp.Privileges[0].Luid))
return "LookupPrivilegeValue() failed";
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL, NULL))
return "AdjustTokenPrivileges() failed";
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
return "The token does not have the specified privilege";
return NULL;
}
const char* ffDetectBootmgr(FFBootmgrResult* result)
{
if (enablePrivilege(L"SeSystemEnvironmentPrivilege") != NULL)
return "Failed to enable SeSystemEnvironmentPrivilege";
uint16_t value;
if (GetFirmwareEnvironmentVariableW(L"BootCurrent", L"{" FF_EFI_GLOBAL_GUID L"}", &value, sizeof(value)) != 2)
return "GetFirmwareEnvironmentVariableW(BootCurrent) failed";
uint8_t buffer[2048];
wchar_t key[16];
wsprintfW(key, L"Boot%04X", value);
uint32_t size = GetFirmwareEnvironmentVariableW(key, L"{" FF_EFI_GLOBAL_GUID L"}", buffer, sizeof(buffer));
if (size < sizeof(FFEfiLoadOption) || size == sizeof(buffer))
return "GetFirmwareEnvironmentVariableW(Boot####) failed";
ffEfiFillLoadOption((FFEfiLoadOption *)buffer, result);
DWORD uefiSecureBootEnabled = 0, bufSize = 0;
if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SYSTEM\\ControlSet001\\Control\\SecureBoot\\State", L"UEFISecureBootEnabled", RRF_RT_REG_DWORD, NULL, &uefiSecureBootEnabled, &bufSize) == ERROR_SUCCESS)
result->secureBoot = !!uefiSecureBootEnabled;
return NULL;
}
+24
View File
@@ -0,0 +1,24 @@
#include "bootmgr.h"
// https://uefi.org/specs/UEFI/2.10/10_Protocols_Device_Path_Protocol.html#generic-device-path-structures
typedef struct ffEfiDevicePathProtocol
{
uint8_t Type;
uint8_t SubType;
uint16_t Length;
uint8_t SpecificDevicePathData[];
} ffEfiDevicePathProtocol;
// https://uefi.org/specs/UEFI/2.10/03_Boot_Manager.html#load-options
typedef struct FFEfiLoadOption
{
uint32_t Attributes;
uint16_t FilePathListLength;
uint16_t Description[];
// ffEfiDevicePathProtocol FilePathList[];
// uint8_t OptionalData[];
} FFEfiLoadOption;
bool ffEfiFillLoadOption(const FFEfiLoadOption* efiOption, FFBootmgrResult* result);
#define FF_EFI_GLOBAL_GUID "8be4df61-93ca-11d2-aa0d-00e098032b8c"
+8 -3
View File
@@ -4,7 +4,6 @@
#include "util/stringUtils.h"
#include <dirent.h>
#include <ctype.h>
#include <limits.h>
static const char* detectWithBacklight(FFlist* result)
@@ -58,14 +57,14 @@ static const char* detectWithBacklight(FFlist* result)
{
ffStrbufSubstrBeforeLastC(&brightness->name, '/'); // remove "/edid"
ffStrbufSubstrAfterLastC(&brightness->name, '/'); // try getting DRM connector name
if(isdigit(brightness->name.chars[0]))
if(ffCharIsDigit(brightness->name.chars[0]))
{
// PCI address or some unknown path, give up
ffStrbufSetS(&brightness->name, entry->d_name);
}
else
{
if(ffStrbufStartsWithS(&brightness->name, "card") && isdigit(brightness->name.chars[4]))
if(ffStrbufStartsWithS(&brightness->name, "card") && ffCharIsDigit(brightness->name.chars[4]))
ffStrbufSubstrAfterFirstC(&brightness->name, '-');
}
}
@@ -109,14 +108,19 @@ static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_any_vcp_value)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_close_display)
#ifndef FF_DISABLE_DLOPEN
__typeof__(&ddca_init) ffddca_init = dlsym(libddcutil, "ddca_init");
if (ffddca_init)
#else
__typeof__(&ddca_init) ffddca_init = ddca_init;
#endif
{
FF_SUPPRESS_IO();
// Ref: https://github.com/rockowitz/ddcutil/issues/344
if (ffddca_init(NULL, -1 /*DDCA_SYSLOG_NOT_SET*/, 1 /*DDCA_INIT_OPTIONS_DISABLE_CONFIG_FILE*/) < 0)
return "ddca_init() failed";
}
#ifndef FF_DISABLE_DLOPEN
else
{
__typeof__(&ddca_set_default_sleep_multiplier) ffddca_set_default_sleep_multiplier = dlsym(libddcutil, "ddca_set_default_sleep_multiplier");
@@ -125,6 +129,7 @@ static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330
}
#endif
FF_AUTO_FREE DDCA_Display_Info_List* infoList = NULL;
if (ffddca_get_display_info_list2(false, &infoList) < 0)
+22 -2
View File
@@ -3,10 +3,28 @@
#import <AVFoundation/AVCaptureDevice.h>
// warning: 'AVCaptureDeviceTypeExternalUnknown' is deprecated
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
const char* ffDetectCamera(FFlist* result)
{
#ifdef MAC_OS_X_VERSION_10_15
FF_SUPPRESS_IO(); // #822
AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeExternalUnknown]
AVCaptureDeviceType deviceType;
#ifdef MAC_OS_VERSION_14_0
if (@available(macOS 14.0, *))
{
deviceType = AVCaptureDeviceTypeExternal;
}
else
#endif
{
deviceType = AVCaptureDeviceTypeExternalUnknown;
}
AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera, deviceType]
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionUnspecified];
if (!session)
@@ -30,6 +48,8 @@ const char* ffDetectCamera(FFlist* result)
camera->width = size.width < 0 ? 0 : (uint32_t) size.width;
camera->height = size.height < 0 ? 0 : (uint32_t) size.height;
}
return NULL;
#else
return "No support for old MacOS version";
#endif
}
+9 -2
View File
@@ -25,11 +25,18 @@ typedef struct FFSmbiosSystemEnclosure
uint8_t ContainedElementCount; // varies
uint8_t ContainedRecordLength; // varies
uint8_t ContainedElements[]; // varies
} FFSmbiosSystemEnclosure;
} __attribute__((__packed__)) FFSmbiosSystemEnclosure;
static_assert(offsetof(FFSmbiosSystemEnclosure, ContainedElements) == 0x15,
"FFSmbiosSystemEnclosure: Wrong struct alignment");
const char* ffDetectChassis(FFChassisResult* result)
{
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) (*smbiosTable)[FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE];
if (!data)
return "System enclosure is not found in SMBIOS data";
+9 -1
View File
@@ -4,6 +4,12 @@
#define FF_CPU_TEMP_UNSET (0/0.0)
typedef struct FFCPUCore
{
uint32_t freq;
uint32_t count;
} FFCPUCore;
typedef struct FFCPUResult
{
FFstrbuf name;
@@ -16,10 +22,12 @@ typedef struct FFCPUResult
double frequencyBase; // GHz
double frequencyMax; // GHz
double frequencyMin; // GHz
double frequencyBiosLimit; // GHz
FFCPUCore coreTypes[16]; // number of P cores, E cores, etc.
double temperature;
} FFCPUResult;
const char* ffCPUDetectByCpuid(FFCPUResult* cpu);
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
const char* ffCPUAppleCodeToName(uint32_t code);
+23 -5
View File
@@ -68,20 +68,37 @@ static const char* detectFrequency(FFCPUResult* cpu)
{
cpu->frequencyBase = ffSysctlGetInt64("hw.cpufrequency", 0) / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency_min", 0) / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0);
if(cpu->frequencyMax > 0.0)
cpu->frequencyMax /= 1000.0 * 1000.0 * 1000.0;
else
cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0) / 1000.0 / 1000.0 / 1000.0;
if(cpu->frequencyBase != cpu->frequencyBase)
{
unsigned current = 0;
size_t size = sizeof(current);
if (sysctl((int[]){ CTL_HW, HW_CPU_FREQ }, 2, &current, &size, NULL, 0) == 0)
cpu->frequencyMax = (double) current / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyBase = (double) current / 1000.0 / 1000.0 / 1000.0;
}
return NULL;
}
#endif
static const char* detectCoreCount(FFCPUResult* cpu)
{
uint32_t nPerfLevels = (uint32_t) ffSysctlGetInt("hw.nperflevels", 0);
if (nPerfLevels <= 0) return "sysctl(hw.nperflevels) failed";
char sysctlKey[] = "hw.perflevelN.logicalcpu";
if (nPerfLevels > sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]))
nPerfLevels = sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]);
for (uint32_t i = 0; i < nPerfLevels; ++i)
{
sysctlKey[strlen("hw.perflevel")] = (char) ('0' + i);
cpu->coreTypes[i] = (FFCPUCore) {
.freq = nPerfLevels - i,
.count = (uint32_t) ffSysctlGetInt(sysctlKey, 0),
};
}
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString("machdep.cpu.brand_string", &cpu->name) != NULL)
@@ -104,6 +121,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.activecpu", 1);
detectFrequency(cpu);
if (options->showPeCoreCount) detectCoreCount(cpu);
cpu->temperature = options->temp ? detectCpuTemp(&cpu->name) : FF_CPU_TEMP_UNSET;
+58
View File
@@ -11,6 +11,64 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coresLogical = cpu->coresPhysical;
cpu->coresOnline = cpu->coresPhysical;
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0)
{
// <groups>
// <group level="1" cache-level="3">
// <cpu count="4" mask="f,0,0,0">0, 1, 2, 3</cpu>
// <children>
// <group level="2" cache-level="2">
// <cpu count="2" mask="3,0,0,0">0, 1</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// <group level="2" cache-level="2">
// <cpu count="2" mask="c,0,0,0">2, 3</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// </children>
// </group>
// </groups>
uint32_t i = 0;
while (true)
{
i = ffStrbufNextIndexS(&buffer, i, "<flag name=\"THREAD\">THREAD group</flag>"); // Find physical core with hyper-threading enabled
if (i >= buffer.length) break;
cpu->coresPhysical--;
i += (uint32_t) strlen("<flag name=\"THREAD\">THREAD group</flag>");
}
}
for (uint16_t i = 0; i < cpu->coresLogical; ++i)
{
ffStrbufClear(&buffer);
char key[32];
snprintf(key, sizeof(key), "dev.cpu.%u.freq_levels", i);
if (ffSysctlGetString(key, &buffer) == NULL && buffer.length > 0)
{
// MHz/Watts pairs like: 2501/32000 2187/27125 2000/24000
uint32_t fmax = (uint32_t) strtoul(buffer.chars, NULL, 10);
uint32_t fmin = fmax;
uint32_t i = ffStrbufLastIndexC(&buffer, ' ');
if (i < buffer.length)
fmin = (uint32_t) strtoul(buffer.chars + i + 1, NULL, 10);
if (!(cpu->frequencyMin <= fmin)) cpu->frequencyMin = fmin; // Counting for NaN
if (!(cpu->frequencyMax >= fmax)) cpu->frequencyMax = fmax;
if (options->showPeCoreCount)
{
uint32_t ifreq = 0;
while (cpu->coreTypes[ifreq].freq != fmax && cpu->coreTypes[ifreq].freq > 0)
++ifreq;
if (cpu->coreTypes[ifreq].freq == 0)
cpu->coreTypes[ifreq].freq = fmax;
cpu->coreTypes[ifreq].count++;
}
}
}
cpu->frequencyMin /= 1000;
cpu->frequencyMax /= 1000;
int clockRate = ffSysctlGetInt("hw.clockrate", 0);
cpu->frequencyBase = clockRate <= 0 ? 0.0/0.0 : clockRate / 1000.0;
cpu->temperature = FF_CPU_TEMP_UNSET;
+55 -15
View File
@@ -9,7 +9,6 @@
#include <sys/sysinfo.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#ifdef __ANDROID__
#include "common/settings.h"
@@ -88,14 +87,14 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
return NULL;
}
static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, const char* scalingFileName, FFstrbuf* buffer)
static uint32_t getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, const char* scalingFileName, FFstrbuf* buffer)
{
uint32_t baseLen = basePath->length;
ffStrbufAppendS(basePath, cpuinfoFileName);
bool ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return ffStrbufToDouble(buffer) / 1e6;
return (uint32_t) ffStrbufToUInt(buffer, 0);
if (scalingFileName)
{
@@ -103,13 +102,31 @@ static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, cons
ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return ffStrbufToDouble(buffer) / 1e6;
return (uint32_t) ffStrbufToUInt(buffer, 0);
}
return 0.0/0.0;
return 0;
}
static bool detectFrequency(FFCPUResult* cpu)
static uint8_t getNumCores(FFstrbuf* basePath, FFstrbuf* buffer)
{
uint32_t baseLen = basePath->length;
ffStrbufAppendS(basePath, "/affected_cpus");
bool ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return (uint8_t) ffStrbufCountC(buffer, ' ') + 1;
ffStrbufAppendS(basePath, "/related_cpus");
ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return (uint8_t) ffStrbufCountC(buffer, ' ') + 1;
return 0;
}
static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
{
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/devices/system/cpu/cpufreq/");
FF_AUTO_CLOSE_DIR DIR* dir = opendir(path.chars);
@@ -119,38 +136,61 @@ static bool detectFrequency(FFCPUResult* cpu)
uint32_t baseLen = path.length;
struct dirent* entry;
while((entry = readdir(dir)) != NULL)
while ((entry = readdir(dir)) != NULL)
{
if (ffStrStartsWith(entry->d_name, "policy") && isdigit(entry->d_name[strlen("policy")]))
if (ffStrStartsWith(entry->d_name, "policy") && ffCharIsDigit(entry->d_name[strlen("policy")]))
{
ffStrbufAppendS(&path, entry->d_name);
double fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
if (fbase == fbase)
uint32_t fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
if (fbase > 0)
{
if (cpu->frequencyBase == cpu->frequencyBase)
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
else
cpu->frequencyBase = fbase;
}
double fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax == fmax)
uint32_t fbioslimit = getFrequency(&path, "/bios_limit", NULL, &buffer);
if (fbioslimit > 0)
{
if (cpu->frequencyBiosLimit == cpu->frequencyBiosLimit)
cpu->frequencyBiosLimit = cpu->frequencyBiosLimit > fbioslimit ? cpu->frequencyBiosLimit : fbioslimit;
else
cpu->frequencyBiosLimit = fbioslimit;
}
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax > 0)
{
if (cpu->frequencyMax == cpu->frequencyMax)
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
else
cpu->frequencyMax = fmax;
}
double fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
if (fmin == fmin)
uint32_t fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
if (fmin > 0)
{
if (cpu->frequencyMin == cpu->frequencyMin)
cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin;
else
cpu->frequencyMin = fmin;
}
if (options->showPeCoreCount)
{
uint32_t freq = fbase == 0 ? fmax : fbase; // seems base frequencies are more stable
uint32_t ifreq = 0;
while (cpu->coreTypes[ifreq].freq != freq && cpu->coreTypes[ifreq].freq > 0)
++ifreq;
if (cpu->coreTypes[ifreq].freq == 0)
cpu->coreTypes[ifreq].freq = freq;
cpu->coreTypes[ifreq].count += getNumCores(&path, &buffer);
}
ffStrbufSubstrBefore(&path, baseLen);
}
}
cpu->frequencyBase /= 1e6;
cpu->frequencyMax /= 1e6;
cpu->frequencyMin /= 1e6;
cpu->frequencyBiosLimit /= 1e6;
return true;
}
@@ -232,7 +272,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coresOnline = (uint16_t) get_nprocs();
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
if (!detectFrequency(cpu) || cpu->frequencyBase != cpu->frequencyBase)
if (!detectFrequency(cpu, options) || cpu->frequencyBase != cpu->frequencyBase)
cpu->frequencyBase = ffStrbufToDouble(&cpuMHz) / 1000;
if(cpuUarch.length > 0)
+38 -9
View File
@@ -1,6 +1,7 @@
#include "cpu.h"
#include "detection/temps/temps_windows.h"
#include "util/windows/registry.h"
#include "util/windows/nt.h"
#include "util/mallocHelper.h"
#include "util/smbiosHelper.h"
@@ -48,7 +49,10 @@ typedef struct FFSmbiosProcessorInfo
// 3.6+
uint16_t ThreadEnabled; // varies
} FFSmbiosProcessorInfo;
} __attribute__((__packed__)) FFSmbiosProcessorInfo;
static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30,
"FFSmbiosProcessorInfo: Wrong struct alignment");
#if defined(__x86_64__) || defined(__i386__)
@@ -77,7 +81,11 @@ inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
{
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PROCESSOR_INFO];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_PROCESSOR_INFO];
if (!data)
return "Processor information is not found in SMBIOS data";
@@ -139,13 +147,6 @@ static const char* detectByRegistry(FFCPUResult* cpu)
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL))
return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\", &hKey, NULL) failed";
if (detectSpeedByCpuid(cpu) != NULL || cpu->frequencyBase != cpu->frequencyBase)
{
uint32_t mhz;
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
cpu->frequencyBase = mhz / 1000.0;
}
ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL);
ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL);
@@ -156,6 +157,31 @@ static const char* detectByRegistry(FFCPUResult* cpu)
cpu->coresOnline = cpu->coresPhysical = cpu->coresLogical = (uint16_t) cores;
}
uint32_t mhz;
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
cpu->frequencyBase = mhz / 1000.0;
return NULL;
}
static const char* detectCoreTypes(FFCPUResult* cpu)
{
FF_AUTO_FREE PROCESSOR_POWER_INFORMATION* pinfo = calloc(cpu->coresLogical, sizeof(PROCESSOR_POWER_INFORMATION));
if (!NT_SUCCESS(NtPowerInformation(ProcessorInformation, NULL, 0, pinfo, (ULONG) sizeof(PROCESSOR_POWER_INFORMATION) * cpu->coresLogical)))
return "NtPowerInformation(ProcessorInformation, NULL, 0, pinfo, size) failed";
for (uint32_t icore = 0; icore < cpu->coresLogical && pinfo[icore].MhzLimit; ++icore)
{
uint32_t ifreq = 0;
while (cpu->coreTypes[ifreq].freq != pinfo[icore].MhzLimit && cpu->coreTypes[ifreq].freq > 0)
++ifreq;
if (cpu->coreTypes[ifreq].freq == 0)
cpu->coreTypes[ifreq].freq = pinfo[icore].MhzLimit;
++cpu->coreTypes[ifreq].count;
}
if (cpu->frequencyBase != cpu->frequencyBase)
cpu->frequencyBase = pinfo->MaxMhz / 1000.0;
return NULL;
}
@@ -167,6 +193,9 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
if (error)
return error;
detectSpeedByCpuid(cpu);
if (options->showPeCoreCount) detectCoreTypes(cpu);
if (cpu->frequencyMax != cpu->frequencyMax)
detectMaxSpeedBySmbios(cpu);
+5
View File
@@ -106,11 +106,16 @@ static void getMate(FFstrbuf* result, FFDEOptions* options)
static const char* getXfce4ByLib(FFstrbuf* result)
{
#ifndef FF_DISABLE_DLOPEN
const char* xfce_version_string(void); // from `xfce4/libxfce4util/xfce-misutils.h
FF_LIBRARY_LOAD(xfce4util, NULL, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xfce4util, xfce_version_string);
ffStrbufSetS(result, ffxfce_version_string());
return NULL;
#else
FF_UNUSED(result);
return "dlopen is disabled";
#endif
}
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
+7 -1
View File
@@ -66,6 +66,10 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk)
#include <sys/attr.h>
#include <unistd.h>
#ifndef MAC_OS_X_VERSION_10_15
#define MNT_REMOVABLE 0x00000200
#endif
struct CmnAttrBuf {
uint32_t length;
attrreference_t nameRef;
@@ -132,13 +136,15 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
ffStrbufInitS(&disk->filesystem, fs->f_fstypename);
ffStrbufInit(&disk->name);
disk->type = 0;
disk->createTime = 0;
detectFsInfo(fs, disk);
if(fs->f_flags & MNT_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
struct stat st;
if(stat(fs->f_mntonname, &st) == 0)
if(stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0)
disk->createTime = (uint64_t)((st.st_birthtimespec.tv_sec * 1000) + (st.st_birthtimespec.tv_nsec / 1000000));
}
+51 -34
View File
@@ -1,10 +1,24 @@
#include "disk.h"
#include "common/io/io.h"
#include "common/thread.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <winioctl.h>
static unsigned __stdcall testRemoteVolumeAccessable(void* mountpoint)
{
FF_AUTO_CLOSE_FD HANDLE handle = CreateFileW(
(wchar_t*) mountpoint,
READ_CONTROL,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
return 0;
}
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
{
wchar_t buf[MAX_PATH + 1];
@@ -41,28 +55,48 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
FFDisk* disk = ffListAdd(disks);
if(!GetDiskFreeSpaceExW(
disk->filesUsed = 0;
disk->filesTotal = 0;
disk->bytesTotal = 0;
disk->bytesFree = 0;
disk->bytesUsed = 0; // To be filled in ./disk.c
disk->bytesAvailable = 0;
disk->createTime = 0;
ffStrbufInit(&disk->filesystem);
ffStrbufInit(&disk->name);
ffStrbufInitMove(&disk->mountpoint, &buffer);
ffStrbufInit(&disk->mountFrom);
disk->type = driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM
? FF_DISK_VOLUME_TYPE_EXTERNAL_BIT
: driveType == DRIVE_FIXED
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
: FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
if (mountpoint[2] == L'\\' && mountpoint[3] == L'\0')
{
wchar_t volumeName[MAX_PATH + 1];
mountpoint[2] = L'\0';
if(QueryDosDeviceW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
ffStrbufSetWS(&disk->mountFrom, volumeName);
mountpoint[2] = L'\\';
}
#ifdef FF_HAVE_THREADS
if (driveType == DRIVE_REMOTE)
{
FFThreadType thread = ffThreadCreate(testRemoteVolumeAccessable, mountpoint);
if (!ffThreadJoin(thread, 500))
continue;
}
#endif
GetDiskFreeSpaceExW(
mountpoint,
(PULARGE_INTEGER)&disk->bytesAvailable,
(PULARGE_INTEGER)&disk->bytesTotal,
(PULARGE_INTEGER)&disk->bytesFree
))
{
disk->bytesTotal = 0;
disk->bytesFree = 0;
disk->bytesAvailable = 0;
}
disk->bytesUsed = 0; // To be filled in ./disk.c
);
if(driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM)
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else if(driveType == DRIVE_FIXED)
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
else
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
ffStrbufInit(&disk->filesystem);
ffStrbufInit(&disk->name);
wchar_t diskName[MAX_PATH + 1], diskFileSystem[MAX_PATH + 1];
//https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa#remarks
@@ -89,23 +123,6 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
WIN32_FILE_ATTRIBUTE_DATA data;
if(GetFileAttributesExW(mountpoint, GetFileExInfoStandard, &data) && data.ftCreationTime.dwHighDateTime > 0)
disk->createTime = (*(uint64_t*) &data.ftCreationTime - 116444736000000000ull) / 10000ull;
else
disk->createTime = 0;
ffStrbufInitMove(&disk->mountpoint, &buffer);
if (mountpoint[2] == L'\\' && mountpoint[3] == L'\0')
{
wchar_t volumeName[MAX_PATH + 1];
mountpoint[2] = L'\0';
if(QueryDosDeviceW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
ffStrbufInitWS(&disk->mountFrom, volumeName);
else
ffStrbufInit(&disk->mountFrom);
}
//Unsupported
disk->filesUsed = 0;
disk->filesTotal = 0;
}
return NULL;
@@ -8,6 +8,10 @@
#include <CoreVideo/CVDisplayLink.h>
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
#ifndef MAC_OS_X_VERSION_10_15
#import <IOKit/graphics/IOGraphicsLib.h>
extern CFDictionaryRef CoreDisplay_IODisplayCreateInfoDictionary(io_service_t framebuffer, IOOptionBits options) __attribute__((weak_import));
#endif
static void detectDisplays(FFDisplayServerResult* ds)
{
@@ -38,6 +42,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
}
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
#ifdef MAC_OS_X_VERSION_10_15
if(CoreDisplay_DisplayCreateInfoDictionary)
{
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen);
@@ -48,6 +53,19 @@ static void detectDisplays(FFDisplayServerResult* ds)
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
}
}
#else
if(CoreDisplay_IODisplayCreateInfoDictionary)
{
io_service_t servicePort = CGDisplayIOServicePort(screen);
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
if(displayInfo)
{
CFDictionaryRef productNames;
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
}
}
#endif
ffdsAppendDisplay(ds,
(uint32_t)CGDisplayModeGetPixelWidth(mode),
+1 -1
View File
@@ -194,7 +194,7 @@ static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen libdrm" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmGetDevices)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetResources)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetConnectorCurrent)
@@ -118,7 +118,8 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
rotation,
display.edidName.length
? &display.edidName
: display.description.length && !ffStrbufEndsWithS(&display.description, "-unknown")
// Try ignoring `eDP-1-unknown`, where `unknown` is localized
: display.description.length && !(ffStrbufStartsWithS(&display.description, display.name.chars) && display.description.chars[display.name.length] == '-')
? &display.description
: &display.name,
display.type,
+1 -2
View File
@@ -4,7 +4,6 @@
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
@@ -320,7 +319,7 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
while((dirent = readdir(procdir)) != NULL)
{
//Match only folders starting with a number (the pid folders)
if(dirent->d_type != DT_DIR || !isdigit(dirent->d_name[0]))
if(dirent->d_type != DT_DIR || !ffCharIsDigit(dirent->d_name[0]))
continue;
ffStrbufAppendS(&procPath, dirent->d_name);
+135
View File
@@ -0,0 +1,135 @@
#include "editor.h"
#include "common/processing.h"
#include "util/stringUtils.h"
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
static inline char* realpath(const char* restrict file_name, char* restrict resolved_name)
{
return _fullpath(resolved_name, file_name, _MAX_PATH);
}
#endif
const char* ffDetectEditor(FFEditorResult* result)
{
ffStrbufSetS(&result->name, getenv("VISUAL"));
if (result->name.length)
result->type = "Visual";
else
{
ffStrbufSetS(&result->name, getenv("EDITOR"));
if (result->name.length)
result->type = "Editor";
else
return "$VISUAL or $EDITOR not set";
}
#ifndef _WIN32
if (result->name.chars[0] != '/')
{
if (ffProcessAppendStdOut(&result->path, (char* const[]){
FASTFETCH_TARGET_DIR_USR "/bin/which",
result->name.chars,
NULL,
}) != NULL || result->path.length == 0)
return NULL;
}
#else
if (!(result->name.length > 3 && ffCharIsEnglishAlphabet(result->name.chars[0]) && result->name.chars[1] == ':' && result->name.chars[2] == '\\'))
{
char buf[32];
uint32_t len = GetSystemDirectoryA(buf, sizeof(buf));
if (len < strlen("C:\\WINDOWS\\system32")) return NULL;
strncpy(buf + len, "\\where.exe", sizeof(buf) - len);
if (ffProcessAppendStdOut(&result->path, (char* const[]){
buf,
result->name.chars,
NULL,
}) != NULL || result->path.length == 0)
return NULL;
}
#endif
else
ffStrbufSet(&result->path, &result->name);
char buf[PATH_MAX + 1];
if (!realpath(result->path.chars, buf))
return NULL;
ffStrbufSetS(&result->path, buf);
{
uint32_t index = ffStrbufLastIndexC(&result->path,
#ifndef _WIN32
'/'
#else
'\\'
#endif
);
if (index == result->path.length)
return NULL;
ffStrbufSetS(&result->exe, &result->path.chars[index + 1]);
if (!result->exe.length)
return NULL;
#ifdef _WIN32
if (ffStrbufEndsWithS(&result->exe, ".exe"))
ffStrbufSubstrBefore(&result->exe, result->exe.length - 4);
#endif
}
const char* param = NULL;
if (
ffStrbufEqualS(&result->exe, "nano") ||
ffStrbufEqualS(&result->exe, "vim") ||
ffStrbufEqualS(&result->exe, "nvim") ||
ffStrbufEqualS(&result->exe, "micro") ||
ffStrbufEqualS(&result->exe, "emacs") ||
ffStrbufStartsWithS(&result->exe, "emacs-") || // emacs-29.3
ffStrbufEqualS(&result->exe, "hx") ||
ffStrbufEqualS(&result->exe, "code") ||
ffStrbufEqualS(&result->exe, "sublime_text")
) param = "--version";
else if (
ffStrbufEqualS(&result->exe, "kak") ||
ffStrbufEqualS(&result->exe, "pico")
) param = "-version";
else if (
ffStrbufEqualS(&result->exe, "ne")
) param = "-h";
else return NULL;
ffProcessAppendStdOut(&result->version, (char* const[]){
result->path.chars,
(char*) param,
NULL,
});
if (result->version.length == 0)
return NULL;
ffStrbufSubstrBeforeFirstC(&result->version, '\n');
for (uint32_t iStart = 0; iStart < result->version.length; ++iStart)
{
char c = result->version.chars[iStart];
if (ffCharIsDigit(c))
{
for (uint32_t iEnd = iStart + 1; iEnd < result->version.length; ++iEnd)
{
char c = result->version.chars[iEnd];
if (isspace(c))
{
ffStrbufSubstrBefore(&result->version, iEnd);
break;
}
}
if (iStart > 0)
ffStrbufSubstrAfter(&result->version, iStart - 1);
break;
}
}
return NULL;
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "fastfetch.h"
typedef struct FFEditorResult
{
const char* type;
FFstrbuf name;
FFstrbuf exe;
FFstrbuf path;
FFstrbuf version;
} FFEditorResult;
const char* ffDetectEditor(FFEditorResult* result);
+4
View File
@@ -25,7 +25,11 @@ const char* ffDetectFontImpl(FFFontResult* result)
{
ffStrbufAppendS(&result->fonts[0], [NSFont systemFontOfSize:12].familyName.UTF8String);
ffStrbufAppendS(&result->fonts[1], [NSFont userFontOfSize:12].familyName.UTF8String);
#ifdef MAC_OS_X_VERSION_10_15
ffStrbufAppendS(&result->fonts[2], [NSFont monospacedSystemFontOfSize:12 weight:400].familyName.UTF8String);
#else
ffStrbufAppendS(&result->fonts[2], "");
#endif
ffStrbufAppendS(&result->fonts[3], [NSFont userFixedPitchFontOfSize:12].familyName.UTF8String);
generateString(result);
+1 -4
View File
@@ -2,9 +2,6 @@
#include "common/io/io.h"
#include "util/stringUtils.h"
#include <dirent.h>
#include <ctype.h>
static void detectGamepad(FFlist* devices, FFstrbuf* name, FFstrbuf* path)
{
uint32_t baseLen = path->length;
@@ -71,7 +68,7 @@ const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */)
{
if (!ffStrStartsWith(entry->d_name, "js"))
continue;
if (!isdigit(entry->d_name[2]))
if (!ffCharIsDigit(entry->d_name[2]))
continue;
ffStrbufAppendS(&path, entry->d_name);
+41 -57
View File
@@ -14,42 +14,24 @@ const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat";
const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle";
static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsigned length)
{
for (unsigned i = 0; i < length; ++i)
{
if (arr[i] == vendorId)
return true;
}
return false;
}
const char* ffGetGPUVendorString(unsigned vendorId)
{
// https://devicehunt.com/all-pci-vendors
if(vendorId == 0x106b)
return FF_GPU_VENDOR_NAME_APPLE;
if(arrayContains((const unsigned[]) {0x1002, 0x1022}, vendorId, 2))
return FF_GPU_VENDOR_NAME_AMD;
else if(arrayContains((const unsigned[]) {0x03e7, 0x8086, 0x8087}, vendorId, 3))
return FF_GPU_VENDOR_NAME_INTEL;
else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3))
return FF_GPU_VENDOR_NAME_NVIDIA;
else if(arrayContains((const unsigned[]) {0x5143}, vendorId, 1))
return FF_GPU_VENDOR_NAME_QUALCOMM;
else if(arrayContains((const unsigned[]) {0x14c3}, vendorId, 1))
return FF_GPU_VENDOR_NAME_MTK;
else if(arrayContains((const unsigned[]) {0x15ad}, vendorId, 1))
return FF_GPU_VENDOR_NAME_VMWARE;
else if(arrayContains((const unsigned[]) {0x1af4}, vendorId, 1))
return FF_GPU_VENDOR_NAME_REDHAT;
else if(arrayContains((const unsigned[]) {0x1ab8}, vendorId, 1))
return FF_GPU_VENDOR_NAME_PARALLEL;
else if(arrayContains((const unsigned[]) {0x1414}, vendorId, 1))
return FF_GPU_VENDOR_NAME_MICROSOFT;
else if(arrayContains((const unsigned[]) {0x108e}, vendorId, 1))
return FF_GPU_VENDOR_NAME_ORACLE;
return NULL;
switch (vendorId)
{
case 0x106b: return FF_GPU_VENDOR_NAME_APPLE;
case 0x1002: case 0x1022: return FF_GPU_VENDOR_NAME_AMD;
case 0x8086: case 0x8087: case 0x03e7: return FF_GPU_VENDOR_NAME_INTEL;
case 0x0955: case 0x10de: case 0x12d2: return FF_GPU_VENDOR_NAME_NVIDIA;
case 0x5143: return FF_GPU_VENDOR_NAME_QUALCOMM;
case 0x14c3: return FF_GPU_VENDOR_NAME_MTK;
case 0x15ad: return FF_GPU_VENDOR_NAME_VMWARE;
case 0x1af4: return FF_GPU_VENDOR_NAME_REDHAT;
case 0x1ab8: return FF_GPU_VENDOR_NAME_PARALLEL;
case 0x1414: return FF_GPU_VENDOR_NAME_MICROSOFT;
case 0x108e: return FF_GPU_VENDOR_NAME_ORACLE;
default: return NULL;
}
}
const char* detectByOpenGL(FFlist* gpus)
@@ -64,9 +46,9 @@ const char* detectByOpenGL(FFlist* gpus)
{
FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus);
gpu->type = FF_GPU_TYPE_UNKNOWN;
ffStrbufInitMove(&gpu->vendor, &result.vendor);
ffStrbufInit(&gpu->vendor);
ffStrbufInitMove(&gpu->name, &result.renderer);
ffStrbufInit(&gpu->driver);
ffStrbufInitMove(&gpu->driver, &result.vendor);
ffStrbufInitF(&gpu->platformApi, "OpenGL %s", result.version.chars);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
@@ -74,22 +56,18 @@ const char* detectByOpenGL(FFlist* gpus)
gpu->dedicated = gpu->shared = (FFGPUMemory){0, 0};
gpu->deviceId = 0;
if (ffStrbufIgnCaseEqualS(&gpu->vendor, "Mesa"))
ffStrbufClear(&gpu->vendor);
if (!gpu->vendor.length)
if (ffStrbufContainS(&gpu->name, "Apple"))
{
if (ffStrbufContainS(&gpu->name, "Apple"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
else if (ffStrbufContainS(&gpu->name, "Intel"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if (ffStrbufContainS(&gpu->name, "AMD") || ffStrbufContainS(&gpu->name, "ATI"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if (ffStrbufContainS(&gpu->name, "NVIDIA"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
}
if (ffStrbufEqualS(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
gpu->type = FF_GPU_TYPE_INTEGRATED;
}
else if (ffStrbufContainS(&gpu->name, "Intel"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if (ffStrbufContainS(&gpu->name, "AMD") || ffStrbufContainS(&gpu->name, "ATI"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if (ffStrbufContainS(&gpu->name, "NVIDIA"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
}
ffStrbufDestroy(&result.version);
@@ -101,20 +79,26 @@ const char* detectByOpenGL(FFlist* gpus)
const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result)
{
if (!options->forceVulkan)
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_PCI)
{
const char* error = ffDetectGPUImpl(options, result);
if (!error && result->length > 0) return NULL;
}
FFVulkanResult* vulkan = ffDetectVulkan();
if (!vulkan->error && vulkan->gpus.length > 0)
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_VULKAN)
{
ffListDestroy(result);
ffListInitMove(result, &vulkan->gpus);
return NULL;
FFVulkanResult* vulkan = ffDetectVulkan();
if (!vulkan->error && vulkan->gpus.length > 0)
{
ffListDestroy(result);
ffListInitMove(result, &vulkan->gpus);
return NULL;
}
}
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENGL)
{
if (detectByOpenGL(result) == NULL)
return NULL;
}
if (detectByOpenGL(result) == NULL)
return NULL;
return "GPU detection failed";
}
+15 -4
View File
@@ -5,10 +5,14 @@
#ifndef MAC_OS_VERSION_13_0
#define MTLGPUFamilyMetal3 ((MTLGPUFamily) 5001)
#endif
#ifndef MAC_OS_X_VERSION_10_15
#define MTLFeatureSet_macOS_GPUFamily1_v4 ((MTLFeatureSet) 10004)
#define MTLFeatureSet_macOS_GPUFamily2_v1 ((MTLFeatureSet) 10005)
#endif
const char* ffGpuDetectMetal(FFlist* gpus)
{
if (@available(macOS 10.15, *))
if (@available(macOS 10.13, *))
{
for (id<MTLDevice> device in MTLCopyAllDevices())
{
@@ -23,6 +27,12 @@ const char* ffGpuDetectMetal(FFlist* gpus)
}
if (!gpu) continue;
#ifndef MAC_OS_X_VERSION_10_15
if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1])
ffStrbufSetStatic(&gpu->platformApi, "Metal Feature Set 2");
else if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v1])
ffStrbufSetStatic(&gpu->platformApi, "Metal Feature Set 1");
#else // MAC_OS_X_VERSION_10_15
if ([device supportsFamily:MTLGPUFamilyMetal3])
ffStrbufSetStatic(&gpu->platformApi, "Metal 3");
else if ([device supportsFamily:MTLGPUFamilyCommon3])
@@ -32,15 +42,16 @@ const char* ffGpuDetectMetal(FFlist* gpus)
else if ([device supportsFamily:MTLGPUFamilyCommon1])
ffStrbufSetStatic(&gpu->platformApi, "Metal Common 1");
if (device.hasUnifiedMemory)
gpu->type = device.hasUnifiedMemory ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
#endif
if (gpu->type == FF_GPU_TYPE_INTEGRATED)
{
gpu->type = FF_GPU_TYPE_INTEGRATED;
gpu->shared.total = device.recommendedMaxWorkingSetSize;
gpu->shared.used = device.currentAllocatedSize;
}
else
{
gpu->type = FF_GPU_TYPE_DISCRETE;
gpu->dedicated.total = device.recommendedMaxWorkingSetSize;
gpu->dedicated.used = device.currentAllocatedSize;
}
-1
View File
@@ -2,7 +2,6 @@
#include "common/io/io.h"
#include "common/properties.h"
#include "3rdparty/nvml/nvml.h"
#include "util/mallocHelper.h"
#include <dev/pci/pcireg.h>
+114 -50
View File
@@ -15,7 +15,25 @@
#include <inttypes.h>
static void pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
#if __has_include(<drm/drm.h>)
#include <drm/drm.h>
#define FF_HAVE_DRM_H 1
#elif __has_include(<libdrm/drm.h>)
#include <libdrm/drm.h>
#define FF_HAVE_DRM_H 1
#endif
#if FF_HAVE_DRM_H
#include <fcntl.h>
#include <sys/ioctl.h>
#if __aarch64__ && __has_include(<drm/asahi_drm.h>)
#include <drm/asahi_drm.h>
#define FF_HAVE_ASAHI_DRM_H 1
#endif
#endif
static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, FF_MAYBE_UNUSED const char* drmKey)
{
ffStrbufAppendS(pciDir, "/driver");
char pathBuf[PATH_MAX];
@@ -35,8 +53,11 @@ static void pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
ffStrbufTrimRightSpace(buffer);
ffStrbufAppendC(&gpu->driver, ' ');
ffStrbufAppend(&gpu->driver, buffer);
return true;
}
}
return false;
}
static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
@@ -46,6 +67,8 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
ffStrbufAppendS(pciDir, "/hwmon/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (!dirp) return;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
@@ -98,32 +121,36 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
{
if (!ffStrbufEndsWithS(pciDir, "/device")) // Must be in `/sys/class/drm/cardN/device`
return;
// Works for Intel GPUs
// https://patchwork.kernel.org/project/intel-gfx/patch/1422039866-11572-3-git-send-email-ville.syrjala@linux.intel.com/
ffStrbufSetNS(buffer, pciDir->length - (uint32_t) strlen("device"), pciDir->chars);
ffStrbufAppendS(buffer, "gt_max_freq_mhz");
char str[16];
ssize_t len = ffReadFileData(buffer->chars, sizeof(str) - 1, str);
if (len > 1)
{
str[len] = '\0';
gpu->frequency = (double) strtoul(str, NULL, 10) / 1000.0;
}
if (ffStrbufStartsWithS(&gpu->name, "Intel "))
ffStrbufSubstrAfter(&gpu->name, (uint32_t) strlen("Intel "));
gpu->type = ffStrbufStartsWithIgnCaseS(&gpu->name, "Arc ") ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
ffStrbufAppendS(pciDir, "/drm/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (!dirp) return;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (ffStrStartsWith(entry->d_name, "card")) break;
}
if (!entry) return;
ffStrbufAppendS(pciDir, entry->d_name);
ffStrbufAppendS(pciDir, "/gt_max_freq_mhz");
if (ffReadFileBuffer(pciDir->chars, buffer))
gpu->frequency = ffStrbufToDouble(buffer) / 1000.0;
}
static bool loadPciIds(FFstrbuf* pciids)
{
#ifdef FF_CUSTOM_PCI_IDS_PATH
ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), pciids);
if (pciids->length > 0) return true;
#endif
#else
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", pciids);
if (pciids->length > 0) return true;
@@ -134,12 +161,14 @@ static bool loadPciIds(FFstrbuf* pciids)
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", pciids);
if (pciids->length > 0) return true;
#endif
return false;
}
static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir)
static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf* buffer, FFstrbuf* deviceDir, const char* drmKey)
{
const uint32_t drmDirPathLength = drmDir->length;
const uint32_t drmDirPathLength = deviceDir->length;
uint32_t vendorId, deviceId, subVendorId, subDeviceId;
uint8_t classId, subclassId;
if (sscanf(buffer->chars + strlen("pci:"), "v%8" SCNx32 "d%8" SCNx32 "sv%8" SCNx32 "sd%8" SCNx32 "bc%2" SCNx8 "sc%2" SCNx8, &vendorId, &deviceId, &subVendorId, &subDeviceId, &classId, &subclassId) != 6)
@@ -149,15 +178,23 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
return "Not a GPU device";
char pciPath[PATH_MAX];
ssize_t pathLength = readlink(drmDir->chars, pciPath, sizeof(pciPath) - 1);
if (pathLength <= 0)
return "Unable to get PCI device path";
pciPath[pathLength] = '\0';
const char* pPciPath = strrchr(pciPath, '/');
if (pPciPath)
pPciPath++;
const char* pPciPath = NULL;
if (drmKey)
{
ssize_t pathLength = readlink(deviceDir->chars, pciPath, sizeof(pciPath) - 1);
if (pathLength <= 0)
return "Unable to get PCI device path";
pciPath[pathLength] = '\0';
pPciPath = strrchr(pciPath, '/');
if (__builtin_expect(pPciPath != NULL, true))
pPciPath++;
else
pPciPath = pciPath;
}
else
pPciPath = pciPath;
{
pPciPath = memrchr(deviceDir->chars, '/', deviceDir->length) + 1;
}
uint32_t pciDomain, pciBus, pciDevice, pciFunc;
if (sscanf(pPciPath, "%" SCNx32 ":%" SCNx32 ":%" SCNx32 ".%" SCNx32, &pciDomain, &pciBus, &pciDevice, &pciFunc) != 4)
@@ -175,10 +212,12 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
gpu->deviceId = ((uint64_t) pciDomain << 6) | ((uint64_t) pciBus << 4) | (deviceId << 2) | pciFunc;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (drmKey) ffStrbufSetF(&gpu->platformApi, "DRM (%s)", drmKey);
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
ffStrbufAppendS(drmDir, "/revision");
if (ffReadFileBuffer(drmDir->chars, buffer))
ffStrbufAppendS(deviceDir, "/revision");
if (ffReadFileBuffer(deviceDir->chars, buffer))
{
char* pend;
uint64_t revision = strtoul(buffer->chars, &pend, 16);
@@ -186,10 +225,14 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
#else
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
#endif
}
}
ffStrbufSubstrBefore(drmDir, drmDirPathLength);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
if (gpu->name.length == 0)
@@ -200,22 +243,21 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
ffStrbufInit(&pciids);
loadPciIds(&pciids);
}
if (pciids.length)
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
}
pciDetectDriver(gpu, drmDir, buffer);
ffStrbufSubstrBefore(drmDir, drmDirPathLength);
pciDetectDriver(gpu, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
pciDetectAmdSpecific(options, gpu, drmDir, buffer);
ffStrbufSubstrBefore(drmDir, drmDirPathLength);
pciDetectAmdSpecific(options, gpu, deviceDir, buffer);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
{
pciDetectIntelSpecific(gpu, drmDir, buffer);
ffStrbufSubstrBefore(drmDir, drmDirPathLength);
pciDetectIntelSpecific(gpu, deviceDir, buffer);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
{
@@ -252,25 +294,45 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
return NULL;
}
FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir)
FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, const char* drmKey)
{
uint32_t index = ffStrbufFirstIndexS(buffer, "apple,agx-t");
if (index == buffer->length) return "display-subsystem?";
index += strlen("apple,agx-t");
index += (uint32_t) strlen("apple,agx-t");
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
gpu->deviceId = strtoul(buffer->chars + index, NULL, 10);
ffStrbufInitStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
ffStrbufInitStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
ffStrbufInitF(&gpu->platformApi, "DRM (%s)", drmKey);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_INTEGRATED;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
pciDetectDriver(gpu, drmDir, buffer);
pciDetectDriver(gpu, drmDir, buffer, drmKey);
#if FF_HAVE_ASAHI_DRM_H
ffStrbufSetS(buffer, "/dev/dri/");
ffStrbufAppendS(buffer, drmKey);
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd >= 0)
{
struct drm_asahi_params_global paramsGlobal = {};
if (ioctl(fd, DRM_IOCTL_ASAHI_GET_PARAMS, &(struct drm_asahi_get_params){
.param_group = DRM_ASAHI_GET_PARAMS,
.pointer = (uint64_t) &paramsGlobal,
.size = sizeof(paramsGlobal),
}) >= 0)
{
gpu->coreCount = (int) paramsGlobal.num_cores_total_active;
gpu->frequency = paramsGlobal.max_frequency_khz / 1e6;
gpu->deviceId = paramsGlobal.chip_id;
}
}
#endif
return NULL;
}
@@ -302,10 +364,10 @@ static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
ffStrbufSubstrBefore(&drmDir, drmDir.length - (uint32_t) strlen("/modalias"));
if (ffStrbufStartsWithS(&buffer, "pci:"))
detectPci(options, gpus, &buffer, &drmDir);
detectPci(options, gpus, &buffer, &drmDir, entry->d_name);
#ifdef __aarch64__
else if (ffStrbufStartsWithS(&buffer, "of:"))
detectAsahi(gpus, &buffer, &drmDir);
detectAsahi(gpus, &buffer, &drmDir, entry->d_name);
#endif
ffStrbufSubstrBefore(&drmDir, drmDirLength);
@@ -347,7 +409,7 @@ static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
ffStrbufSubstrBefore(&pciDir, pciDevDirLength);
assert(ffStrbufStartsWithS(&buffer, "pci:"));
detectPci(options, gpus, &buffer, &pciDir);
detectPci(options, gpus, &buffer, &pciDir, NULL);
ffStrbufSubstrBefore(&pciDir, pciBaseDirLength);
}
@@ -356,14 +418,16 @@ static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
#ifdef FF_HAVE_DIRECTX_HEADERS
const char* ffGPUDetectByDirectX(const FFGPUOptions* options, FFlist* gpus);
if (ffGPUDetectByDirectX(options, gpus) == NULL)
if (options->detectionMethod == FF_GPU_DETECTION_METHOD_AUTO)
{
#ifdef FF_HAVE_DIRECTX_HEADERS
const char* ffGPUDetectByDirectX(const FFGPUOptions* options, FFlist* gpus);
if (ffGPUDetectByDirectX(options, gpus) == NULL)
return NULL;
#endif
if (drmDetectGPUs(options, gpus) == NULL && gpus->length > 0)
return NULL;
#endif
if (drmDetectGPUs(options, gpus) == NULL && gpus->length > 0)
return NULL;
}
return pciDetectGPUs(options, gpus);
}
+10 -1
View File
@@ -1,7 +1,7 @@
#include "gpu_driver_specific.h"
#include "3rdparty/nvml/nvml.h"
#include "common/library.h"
#include "nvml.h"
struct FFNvmlData {
FF_LIBRARY_SYMBOL(nvmlDeviceGetCount_v2)
@@ -19,6 +19,8 @@ struct FFNvmlData {
const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName)
{
#ifndef FF_DISABLE_DLOPEN
if (!nvmlData.inited)
{
nvmlData.inited = true;
@@ -127,4 +129,11 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
}
return NULL;
#else
FF_UNUSED(cond, result, soName);
return "dlopen is disabled";
#endif
}
+5
View File
@@ -31,8 +31,13 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
FF_LIBRARY_LOAD(libdxcore, nullptr, "dlopen libdxcore.so failed. Make sure WSLg is enabled", "/usr/lib/wsl/lib/libdxcore" FF_LIBRARY_EXTENSION, 4)
// DXCoreCreateAdapterFactory is a reloaded function, so we can't use FF_LIBRARY_LOAD_SYMBOL_MESSAGE here
typedef HRESULT (*DXCoreCreateAdapterFactory_t)(REFIID riid, void** ppvFactory);
#ifndef FF_DISABLE_DLOPEN
auto ffDXCoreCreateAdapterFactory = (DXCoreCreateAdapterFactory_t) dlsym(libdxcore, "DXCoreCreateAdapterFactory");
if(ffDXCoreCreateAdapterFactory == nullptr) return "dlsym DXCoreCreateAdapterFactory failed";
#else
auto ffDXCoreCreateAdapterFactory = (DXCoreCreateAdapterFactory_t) DXCoreCreateAdapterFactory;
#endif
IDXCoreAdapterFactory *factory = nullptr;
+120
View File
@@ -0,0 +1,120 @@
#pragma once
// DISCLAIMER:
// THIS FILE IS CREATED FROM SCRATCH, BY READING THE OFFICIAL NVML API
// DOCUMENTATION REFERENCED BELOW, IN ORDER TO MAKE FASTFETCH MIT COMPLIANT.
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceStructs.html
#define NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE 32
#define NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE 16
typedef enum { NVML_SUCCESS = 0 } nvmlReturn_t;
typedef struct nvmlDevice_t* nvmlDevice_t;
// https://docs.nvidia.com/deploy/nvml-api/structnvmlPciInfo__t.html
// PCI information about a GPU device
typedef struct {
// The legacy tuple domain:bus:device.function PCI identifier (& NULL terminator)
char busIdLegacy[NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE];
// The PCI domain on which the device's bus resides, 0 to 0xffffffff
unsigned int domain;
// The bus on which the device resides, 0 to 0xff
unsigned int bus;
// The device's id on the bus, 0 to 31
unsigned int device;
// The combined 16-bit device id and 16-bit vendor id
unsigned int pciDeviceId;
// The 32-bit Sub System Device ID
unsigned int pciSubSystemId;
// The tuple domain:bus:device.function PCI identifier (& NULL terminator)
char busId[NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE];
} nvmlPciInfo_t;
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g2650b526841fa38b8f293c2d509a1de0
// Temperature sensors
typedef enum {
// Temperature sensor for the GPU die
NVML_TEMPERATURE_GPU = 0,
NVML_TEMPERATURE_COUNT,
} nvmlTemperatureSensors_t;
// https://docs.nvidia.com/deploy/nvml-api/structnvmlMemory__v2__t.html#structnvmlMemory__v2__t
// Memory allocation information for a device (v2)
typedef struct {
// Structure format version (must be 2)
unsigned int version;
// Total physical device memory (in bytes)
unsigned long long total;
// Device memory (in bytes) reserved for system use (driver or firmware)
unsigned long long reserved;
// Unallocated device memory (in bytes)
unsigned long long free;
// Allocated device memory (in bytes)
unsigned long long used;
} nvmlMemory_v2_t;
enum { nvmlMemory_v2 = 2 };
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64
// Clock types
typedef enum {
// Graphics clock domain
NVML_CLOCK_GRAPHICS = 0,
// SM clock domain
NVML_CLOCK_SM = 1,
// Memory clock domain
NVML_CLOCK_MEM = 2,
// Video encoder/decoder clock domain
NVML_CLOCK_VIDEO = 3,
// Count of clock types
NVML_CLOCK_COUNT,
} nvmlClockType_t;
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1gfa6b01990b212f7b49089b7158eafd2b
// The Brand of the GPU
typedef enum {
NVML_BRAND_UNKNOWN = 0,
NVML_BRAND_QUADRO = 1,
NVML_BRAND_TESLA = 2,
NVML_BRAND_NVS = 3,
NVML_BRAND_GRID = 4,
NVML_BRAND_GEFORCE = 5,
NVML_BRAND_TITAN = 6,
NVML_BRAND_NVIDIA_VAPPS = 7,
NVML_BRAND_NVIDIA_VPC = 8,
NVML_BRAND_NVIDIA_VCS = 9,
NVML_BRAND_NVIDIA_VWS = 10,
NVML_BRAND_NVIDIA_CLOUD_GAMING = 11,
NVML_BRAND_NVIDIA_VGAMING = NVML_BRAND_NVIDIA_CLOUD_GAMING,
NVML_BRAND_QUADRO_RTX = 12,
NVML_BRAND_NVIDIA_RTX = 13,
NVML_BRAND_NVIDIA = 14,
NVML_BRAND_GEFORCE_RTX = 15,
NVML_BRAND_TITAN_RTX = 16,
NVML_BRAND_COUNT,
} nvmlBrandType_t;
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlInitializationAndCleanup.html#group__nvmlInitializationAndCleanup
// Initialize NVML, but don't initialize any GPUs yet
nvmlReturn_t nvmlInit_v2(void);
// Shut down NVML by releasing all GPU resources previously allocated with nvmlInit_v2()
nvmlReturn_t nvmlShutdown(void);
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html
// Retrieves the number of compute devices in the system. A compute device is a single GPU
extern nvmlReturn_t nvmlDeviceGetCount_v2(unsigned int* deviceCount);
// Acquire the handle for a particular device, based on its index
extern nvmlReturn_t nvmlDeviceGetHandleByIndex_v2(unsigned int index, nvmlDevice_t* device);
// Acquire the handle for a particular device, based on its PCI bus id
extern nvmlReturn_t nvmlDeviceGetHandleByPciBusId_v2(const char* pciBusId, nvmlDevice_t* device);
// Retrieves the PCI attributes of this device
extern nvmlReturn_t nvmlDeviceGetPciInfo_v3(nvmlDevice_t device, nvmlPciInfo_t* pci);
// Retrieves the current temperature readings for the device, in degrees C
extern nvmlReturn_t nvmlDeviceGetTemperature(nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int* temp);
// Retrieves the amount of used, free, reserved and total memory available on the device, in bytes. The reserved amount is supported on version 2 only
extern nvmlReturn_t nvmlDeviceGetMemoryInfo_v2(nvmlDevice_t device, nvmlMemory_v2_t* memory);
// Gets the device's core count
extern nvmlReturn_t nvmlDeviceGetNumGpuCores(nvmlDevice_t device, unsigned int* numCores);
// Retrieves the maximum clock speeds for the device
extern nvmlReturn_t nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType_t type, unsigned int* clock);
// Retrieves the brand of this device
extern nvmlReturn_t nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t* type);
+10 -3
View File
@@ -18,17 +18,24 @@ typedef struct FFSmbiosSystemInfo
uint8_t ClockSeqHiAndReserved;
uint8_t ClockSeqLow;
uint8_t Node[6];
} UUID; // varies
} __attribute__((__packed__)) UUID; // varies
uint8_t WakeUpType; // enum
// 2.4+
uint8_t SKUNumber; // string
uint8_t Family; // string
} FFSmbiosSystemInfo;
} __attribute__((__packed__)) FFSmbiosSystemInfo;
static_assert(offsetof(FFSmbiosSystemInfo, Family) == 0x1A,
"FFSmbiosSystemInfo: Wrong struct alignment");
const char* ffDetectHost(FFHostResult* host)
{
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_INFO];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_SYSTEM_INFO];
if (!data)
return "System information is not found in SMBIOS data";
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include "fastfetch.h"
typedef struct FFInitSystemResult
{
FFstrbuf name;
FFstrbuf exe;
FFstrbuf version;
uint32_t pid;
} FFInitSystemResult;
const char* ffDetectInitSystem(FFInitSystemResult* result);
@@ -0,0 +1,57 @@
#include "initsystem.h"
#include "common/processing.h"
const char* ffDetectInitSystem(FFInitSystemResult* result)
{
const char* error = ffProcessGetBasicInfoLinux((int) result->pid, &result->name, NULL, NULL);
if (error) return error;
const char* _;
// In linux /proc/1/exe is not readable
ffProcessGetInfoLinux((int) result->pid, &result->name, &result->exe, &_, NULL);
if (result->exe.chars[0] == '/')
{
// In some old system, /sbin/init is a symlink
char buf[PATH_MAX];
if (realpath(result->exe.chars, buf))
ffStrbufSetS(&result->exe, buf);
}
if (ffStrbufEqualS(&result->name, "systemd"))
{
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
ffStrbufEndsWithS(&result->exe, "/systemd") ? result->exe.chars : "systemctl", // use exe path in case users have another systemd installed
"--version",
NULL,
}) == NULL && result->version.length)
{
uint32_t iStart = ffStrbufFirstIndexC(&result->version, '(');
if (iStart < result->version.length)
{
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ')');
ffStrbufSubstrBefore(&result->version, iEnd);
ffStrbufSubstrAfter(&result->version, iStart);
}
}
}
else if (ffStrbufEqualS(&result->name, "launchd"))
{
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
"/bin/launchctl",
"version",
NULL,
}) == NULL && result->version.length)
{
uint32_t iStart = ffStrbufFirstIndexS(&result->version, "Version ");
if (iStart < result->version.length)
{
iStart += strlen("Version");
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ':');
ffStrbufSubstrBefore(&result->version, iEnd);
ffStrbufSubstrAfter(&result->version, iStart);
}
}
}
return NULL;
}

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